put the 0.6.9 version in the trunk directory
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 16 Dec 2005 03:28:06 +0000 (03:28 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 16 Dec 2005 03:28:06 +0000 (03:28 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1393 04897980-b3bd-0310-b5e0-8ef037075253

259 files changed:
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/AUTHORS [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ChangeLog [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/NEWS [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/QUICKSTART [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/README [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/autogen.sh [new file with mode: 0755]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/configure.in [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/coding.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/developer_guide.dvi [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/developer_guide.docbook [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.eps [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c18.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c40.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c67.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/index.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/lttv-context.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x23.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x33.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x46.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x50.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x72.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x77.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x81.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x84.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/discuss.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/filter_specification.docbook [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/format.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/guiControlFlow.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/gui_layout.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/guidetailed-event-list-redesign.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/hook_prio.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/index.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/library-header.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/ltt-to-do.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttng-lttv-roadmap.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttv.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttvwindow_events_delivery.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/process_traceset_strict_boundaries.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/program-header.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/requests_servicing_schedulers.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/status.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/todo.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/guiEvents.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.eps [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.eps [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/user_guide.docbook [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c159.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c162.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c20.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c25.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c88.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c91.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/index.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-color-list.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-numbered-5.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x127.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x130.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x169.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x172.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x46.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x54.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x61.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x64.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x78.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x81.html [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/user_guide.dvi [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doxyfile [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/core.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/fs.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/ipc.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/kernel.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/memory.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/network.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/process.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/s390_kernel.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/socket.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/timer.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/liblttctl.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/lttctl.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/compiler.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/LTTTypes.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/LinuxEvents.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/README [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/convert.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/core.xml [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/sysInfo [new file with mode: 0755]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/crc32.tab [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/event.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/event.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/facility.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/facility.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt-private.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt-types.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/parser.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/parser.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/time.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/trace.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/tracefile.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/type.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/type.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttctl/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttctl/lttctl.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttd/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttd/lttd.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/README [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/attribute.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/attribute.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/batchtest.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/contextmacros.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/filter.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/filter.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/hook.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/hook.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/iattribute.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/iattribute.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv-gui.sh [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv.sh [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/main.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/module.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/module.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/option.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/option.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/print.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/print.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/state.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/state.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/stats.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/stats.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/tracecontext.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/tracecontext.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/traceset.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/traceset.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/README [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/sampledep.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/samplemodule.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/samplemodule2.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/TODO [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/cfv.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/cfv.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawing.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawing.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawitem.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawitem.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/eventhooks.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/eventhooks.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/hGuiControlFlowInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/hLegendInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/module.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/processlist.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/processlist.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/test.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/events.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/hGuiEventsInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/.deps/diskperformance.Plo [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/.deps/libsysteminfo.la.Plo [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/diskperformance.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/hDiskPerformanceInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/liste.txt [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/filter.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/hGuiFilterInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/.deps/interrupts.Plo [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/.deps/systeminfo.Plo [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/hInterruptsInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/interrupts.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/glade/lttvwindow.glade [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/glade/lttvwindow.gladep [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/computetrace.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/interface.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/interface.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/menu.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/menu.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/support.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/support.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/test_main.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/mainwin.glade [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/mainwin.gladep [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1downarrow.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1uparrow.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/close.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_add_22.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_remove_22.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filenew.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/fileopen.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesave.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesaveas.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-add.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-jump-to.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/lttv-color-list.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/mini-display.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/move_message.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove1.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_redo_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_refresh_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_stop_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_fit_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_in_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_out_24.png [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/hGuiStatisticInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/statistics.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlPause.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlStart.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlStop.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/hTraceControlInsert.xpm [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/tracecontrol.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/Makefile.am [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/batchAnalysis.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/batchanalysis.h [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/textDump.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/textFilter.c [new file with mode: 0644]
ltt/trunk/LinuxTraceToolkitViewer-0.6.9/profile.sh [new file with mode: 0755]

diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/AUTHORS b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/AUTHORS
new file mode 100644 (file)
index 0000000..032edf0
--- /dev/null
@@ -0,0 +1,25 @@
+Linux Trace Toolkit Viewer
+
+Contributors :
+
+Michel Dagenais (New trace format, lttv main)
+Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,
+                   lttv gui, control flow view, gui cooperative trace reading
+                   scheduler with interruptible foreground and background
+                   computation, detailed event list (rewrite), trace reading
+                   library (rewrite))
+Benoit Des Ligneris, Ã‰ric Clement (Cluster adaptation, work in progress)
+Xang-Xiu Yang (trace reading library and converter, lttv gui, 
+               detailed event list and statistics view)
+Tom Zanussi (RelayFS)
+
+Strongly inspired from the original Linux Trace Toolkit Visualizer made by
+Karim Yaghmour.
+
+Linux Trace Toolkit Viewer, Copyright (C) 2004
+                                                Michel Dagenais
+                                                Mathieu Desnoyers
+                                                Xang-Xiu Yang
+Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.
+This is free software, and you are welcome to redistribute it
+under certain conditions. See COPYING for details.
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ChangeLog b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ChangeLog
new file mode 100644 (file)
index 0000000..ad3e132
--- /dev/null
@@ -0,0 +1,4 @@
+LinuxTraceToolkit ChangeLog
+
+29/05/2003     Subversion repository preliminary files addition
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/Makefile.am
new file mode 100644 (file)
index 0000000..66afa90
--- /dev/null
@@ -0,0 +1,6 @@
+# WARNING : ltt must come before lttv, so that the traceread library is
+# up to date
+
+SUBDIRS = liblttctl ltt lttctl lttv lttd doc facilities
+
+EXTRA_DIST = QUICKSTART
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/NEWS b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/QUICKSTART b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/QUICKSTART
new file mode 100644 (file)
index 0000000..f297e15
--- /dev/null
@@ -0,0 +1,366 @@
+
+QUICKSTART
+
+How to use LTTng and LTTV in a few lines :
+
+This document is made of four parts : The first one explains how to install
+LTTng and LTTV from Debian and RPM binary packages, the second one explains how
+to install LTTng and LTTV from sources and the third one describes the steps
+to follow to trace a system and view it. The fourth and last part explains
+briefly how to add a new trace point to the kernel.
+
+What you will typically want is to read sections 1 and 3 : install LTTng from
+binary packages and use it. If there are no packages ready for your system, you
+will have to install from sources (section 2) instead.
+
+These operations are made for installing the LTTng 0.4.2 tracer on a
+linux 2.6.12-rc4-mm2 kernel. You will also find instructions for installtion of
+LTTV 0.6.x : the Linux Trace Toolkit Viewer.
+
+At this point, the -mm tree of the kernel is used because it has RelayFS support
+in it. In a nearby future, a vanilla kernel 2.6.14 will be used, as RelayFS has
+been integrated in the linux 2.6.14-rc series.
+
+The following lttng patch is necessary to have the tracing hooks in the kernel.
+The following ltt-control module controls the tracing.
+
+Required programs and librairies are assumed to be automatically installed in an
+installation with Debian or RPM packages. In the case of an installation from
+sources, the dependencies are listed.
+
+
+** Current development status **
+
+LTTng : 
+supported architectures : 
+Intel Pentium (UP/SMP) with TSC
+
+LTTV :
+supported architectures :
+Intel i386 and better
+PowerPC
+
+
+
+Author : Mathieu Desnoyers, September 2005
+
+
+
+***********************************************************
+** Section 1 * Installation from Debian or RPM packages  **
+***********************************************************
+
+* Install from RPM packages on Fedora Core 4 :
+
+Get LTTV RPM from :
+
+http://ltt.polymtl.ca/packages/fedora/RPMS
+
+LTTV RPM are ready.
+
+LTTng kernel and lttng-modules RPM are available for some architectures (i586,
+i686). Feel free to help fix the spec files to have correct lttng-modules RPM
+package.
+
+
+* Install from Deb packages on Debian :
+
+You can use the ltt.polymtl.ca apt source to get LTTV for Debian :
+
+Add the following two sources to your /etc/apt/sources.list :
+
+deb http://ltt.polymtl.ca/packages/debian experimental main
+deb-src http://ltt.polymtl.ca/packages/debian experimental main
+
+
+* Install from precompiled binary packages (LTTV compiled only for i386, and
+  LTTng only for i686 smp), perform the following :
+
+su -
+apt-get update
+apt-get install lttv lttv-doc
+apt-get install kernel-image-2.6.12-rc4-mm2-lttng-0.4.2
+apt-get install lttng-modules-modules-2.6.12-rc4-mm2-lttng-0.4.2
+  * note : the packages are signed by myself. I am not considered a trusted
+    Debian source yet, so warnings are normal.
+
+Then, follow the section "Editing the system wide configuration" in section 2.
+
+* Create custom LTTV Debian packages
+
+Binary packages are only available for i386. If you want to create your own LTTV
+packages for other platforms, do :
+
+su -
+cd /usr/src
+apt-get source lttv
+cd lttv-0.6.9
+dpkg-buildpackage -rfakeroot
+
+You should then have your LTTV .deb files created for your architecture.
+
+* Create custom LTTng packages
+
+For building LTTng Debian packages :
+
+su -
+apt-get install kernel-source-2.6.12-rc4-mm2-lttng-0.4.2
+cd /usr/src
+bzip2 -cd kernel-source-2.6.12-rc4-mm2-lttng-0.4.2.tar.bz2 | tar xvof -
+cd kernel-source-2.6.12-rc4-mm2-lttng-0.4.2
+make menuconfig (or xconfig or config) (customize your configuration)
+make-kpkg kernel_image
+
+You will then see your freshly created .deb in /usr/src. Install it with
+dpkg -i /usr/src/(image-name).deb
+
+You will also need to create a package for the lttng-modules :
+
+su -
+cd /usr/src
+apt-get source lttng-modules
+cd kernel-source-2.6.12-rc4-mm2-lttng-0.4.2
+make-kpkg --added_modules /usr/src/lttng-modules-0.3 modules_image
+
+You will then see your freshly created .deb in /usr/src. Install it with
+dpkg -i /usr/src/lttng-modules-modules-(your version).deb
+
+
+Then, follow the section "Editing the system wide configuration" in section 2.
+
+
+***********************************************************
+** Section 2 * Installation from sources                 **
+***********************************************************
+
+* Prerequisites
+
+Tools needed to follow the package download steps :
+
+o wget
+o bzip2
+o gzip
+o tar
+
+You have to install the standard development librairies and programs necessary
+to compile a kernel :
+
+(from Documentation/Changes in the Linux kernel tree)
+o  Gnu C                  2.95.3                  # gcc --version
+o  Gnu make               3.79.1                  # make --version
+o  binutils               2.12                    # ld -v
+o  util-linux             2.10o                   # fdformat --version
+o  module-init-tools      0.9.10                  # depmod -V
+
+You might also want to have libncurses5 to have the text mode kernel
+configuration menu, but there are alternatives.
+
+Prerequisites for LTTV 0.6.x installation are :
+
+gcc 3.2 or better
+gtk 2.4 or better development libraries
+  (Debian : libgtk2.0, libgtk2.0-dev)
+  (Fedora : gtk2, gtk2-devel)
+  note : For Fedora users : this might require at least core 3 from Fedora,
+  or you might have to compile your own GTK2 library.
+glib 2.4 or better development libraries
+  (Debian : libglib2.0-0, libglib2.0-dev)
+  (Fedora : glib2, glib2-devel)
+libpopt development libraries
+  (Debian : libpopt0, libpopt-dev)
+  (Fedora : popt)
+libpango development libraries
+  (Debian : libpango1.0, libpango1.0-dev)
+  (Fedora : pango, pango-devel)
+libc6 development librairies 
+  (Debian : libc6, libc6-dev)
+  (Fedora : glibc, glibc)
+
+
+* Getting the LTTng packages
+
+su -
+mkdir /usr/src/lttng
+cd /usr/src/lttng
+(see http://ltt.polymtl.ca/lttng for package listing)
+wget http://ltt.polymtl.ca/lttng/lttng-modules-0.3.tar.bz2
+wget http://ltt.polymtl.ca/lttng/patch-2.6.12-rc4-mm2-lttng-0.4.2.tar.bz2
+bzip2 -cd lttng-modules-0.3.tar.bz2 | tar xvof -
+bzip2 -cd patch-2.6.12-rc4-mm2-lttng-0.4.2.tar.bz2 | tar xvof -
+
+
+* Getting LTTng kernel sources
+
+su -
+cd /usr/src
+wget http://kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.12-rc4.tar.bz2
+wget http://kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.12-rc4/2.6.12-rc4-mm2/2.6.12-rc4-mm2.bz2
+bzip2 -cd linux-2.6.12-rc4.tar.bz2 | tar xvof -
+cd linux-2.6.12-rc4
+bzip2 -cd ../2.6.12-rc4-mm2.bz2 | patch -p1
+cat /usr/src/lttng/patch-2.6.12-rc4-mm2-lttng-0.4.2-* | patch -p1
+cd ..
+mv linux-2.6.12-rc4 linux-2.6.12-rc4-mm2-lttng-0.4.2
+
+
+* Installing a LTTng kernel
+
+su -
+cd /usr/src/linux-2.6.12-rc4-mm2-lttng-0.4.2
+make menuconfig (or make xconfig or make config)
+    Select the < Help > button if you are not familiar with kernel
+    configuration.
+    Items preceded by [*] means they has to be built into the kernel.
+    Items preceded by [M] means they has to be built as modules.
+    Items preceded by [ ] means they should be removed.
+  go to the "General setup" section
+    Select the following options :
+    [*] Linux Trace Toolkit Instrumentation Support
+    [M] or [*] Linux Trace Toolkit Tracer
+        It makes no difference for the rest of the procedure whether the Tracer
+        is compiled built-in or as a module.
+    do NOT activate (not ready yet) :
+       [ ] Align Linux Trace Toolkit Traces
+       [ ] Activate Linux Trace Toolkit Heartbeat Timer
+              IMPORTANT : This is enabled by default : you must disable it!
+    Select <Exit>
+  Select <Exit>
+  Select <Yes>
+make
+make modules_install
+make install
+
+reboot
+
+  Select the Linux 2.6.12-rc4-mm2-lttng-0.4.2 kernel in your boot loader.
+
+
+* Install the ltt-modules
+
+su -
+cd /usr/src/lttng/lttng-modules-0.3
+KERNELDIR=/usr/src/linux-2.6.12-rc4-mm2-lttng-0.4.2 make
+KERNELDIR=/usr/src/linux-2.6.12-rc4-mm2-lttng-0.4.2 make modules_install
+
+
+* Editing the system wide configuration
+
+You must activate relayfs and specify a mount point. This is typically done in
+fstab such that it happens at boot time.
+
+If you have never used RelayFS before, these operation would do this for you :
+
+mkdir /mnt/relayfs
+cp /etc/fstab /etc/fstab.lttng.bkp
+echo "relayfs         /mnt/relayfs    relayfs rw              0       0"  >> /etc/fstab
+
+then, rebooting or issuing the following command will activate relayfs :
+
+mount /mnt/relayfs
+
+You need to load the ltt-control module to be able to control tracing from user
+space. This is done by issuing the command :
+
+modprobe ltt-control
+
+You can automate at boot time loading the ltt-control module by :
+
+echo ltt-control >> /etc/modules
+
+
+* Getting and installing the LTTV package
+
+su -
+cd /usr/src
+wget http://ltt.polymtl.ca/packages/LinuxTraceToolkitViewer-0.6.9-10102005.tar.gz
+gzip -cd LinuxTraceToolkitViewer-0.6.9-10102005.tar.gz | tar xvof -
+cd LinuxTraceToolkitViewer-0.6.9-10102005
+(refer to README to see the development libraries that must be installed on you
+system)
+./configure
+make
+make install
+
+
+
+
+***********************************************************
+** Section 3 * Using LTTng and LTTV                      **
+***********************************************************
+
+* Use graphical LTTV to control tracing and analyse traces
+
+lttv-gui (or /usr/local/bin/lttv-gui)
+  - Spot the "Tracing Control" icon : click on it
+      (it's a traffic light icon)
+    - enter the root password
+    - click "start"
+    - click "stop"
+    - Yes
+      * You should now see a trace
+
+* Use text mode LTTng to control tracing
+
+The tracing can be controlled from a terminal by using the lttctl command (as
+root).
+
+Start tracing :
+
+lttctl -n trace -d -l /mnt/relayfs/ltt -t /tmp/trace
+
+Stop tracing and destroy trace channels :
+
+lttctl -n trace -R
+
+see lttctl --help for details.
+
+
+* Use text mode LTTV
+
+Fell free to look in /usr/local/lib/lttv/plugins to see all the text and
+graphical plugins available.
+
+For example, a simple trace dump in text format is available with :
+
+lttv -m textDump -t /tmp/trace
+
+see lttv -m textDump --help for detailed command line options of textDump.
+
+
+
+
+***********************************************************
+** Section 4 * Adding new instrumentations with genevent **
+***********************************************************
+
+* Getting and installing genevent
+
+su -
+cd /usr/src
+wget http://ltt.polymtl.ca/packages/genevent-0.2.tar.gz
+gzip -cd genevent-0.2.tar.gz | tar xvof -
+cd genevent-0.2
+make
+make install
+
+
+* Add new events to the kernel with genevent
+
+su -
+cd /usr/local/share/LinuxTraceToolkitViewer/facilities
+cp process.xml yourfacility.xml
+  * edit yourfacility.xml to fit your needs.
+cd /tmp
+/usr/local/bin/genevent /usr/local/share/LinuxTraceToolkitViewer/yourfacility.xml
+cp ltt-facility-yourfacility.h ltt-facility-id-yourfacility.h \
+         /usr/src/linux-2.6.12-rc4-mm2-lttng-0.4.2/include/linux/ltt
+cp ltt-facility-loader-yourfacility.c ltt-facility-loader-yourfacility.h \
+         /usr/src/linux-2.6.12-rc4-mm2-lttng-0.4.2/ltt
+  * edit the kernel file you want to instrument
+    - Add #include <linux/ltt/ltt-facility-yourfacility.h> at the beginning
+      of the file.
+    - Add a call to the tracing functions. See their names and parameters in
+      /usr/src/linux-2.6.12-rc4-mm2-lttng-0.4.2/include/linux/ltt/ltt-facility-yourfacility.h
+    
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/README b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/README
new file mode 100644 (file)
index 0000000..836472a
--- /dev/null
@@ -0,0 +1,77 @@
+
+This package contains the trace reading library and trace viewing tools for
+the new Linux Trace Toolkit trace format. It also contains the lttd, lttctl and
+liblttctl programs which are necessary to obtain a trace.
+
+* Compiling
+
+gcc 3.2 or better
+gtk 2.4 or better development libraries
+  (Debian : libgtk2.0, libgtk2.0-dev)
+  (Fedora : gtk2, gtk2-devel)
+  note : For Fedora users : this might require at least core 3 from Fedora,
+  or you might have to compile your own GTK2 library.
+glib 2.4 or better development libraries
+  (Debian : libglib2.0-0, libglib2.0-dev)
+  (Fedora : glib2, glib2-devel)
+libpopt development libraries
+  (Debian : libpopt0, libpopt-dev)
+  (Fedora : popt)
+libpango development libraries
+  (Debian : libpango1.0, libpango1.0-dev)
+  (Fedora : pango, pango-devel)
+libc6 development librairies 
+  (Debian : libc6, libc6-dev)
+  (Fedora : glibc, glibc)
+
+
+To compile the source tree from a tarball, simply follow these steps :
+
+- ./configure
+- make
+- make install
+
+After running ./configure, you can also go in specific subdirectories and
+use make, make install.
+
+
+* Quick Start
+
+See QUICKSTART
+
+* Source Tree Structure
+
+Here is the tree structure of the Linux Trace Toolkit Viewer package.
+
+ltt: new trace format reading library.
+README: This file.
+debian: debian config files (currently empty).
+doc:    Documentation.
+doc/user:      User related documentation.
+doc/developer: Developer related documentation.
+liblttctl:    Library to communicate with the kernel tracer control module.
+lttctl:       Command line program to use the liblttctl library.
+lttd:   Linux Trace Toolkit daemon.
+lttv:   Linux Trace Toolkit trace analysis tool and viewer.
+lttv/modules:  Linux Trace Toolkit analysis tool and viewer plugin modules.
+specs:  RPM config files (currently empty).
+
+
+* For Developers
+
+This source tree is based on the autotools suite from GNU to simplify
+portability. Here are some things you should have on your system in order to
+compile the subversion repository tree :
+
+
+GNU autotools (automake-1,7, autoconf2.50, autoheader2.50)
+(make sure your system wide "automake" points to version 1.7!)
+GNU Libtool
+(for more information, go to http://www.gnu.org/software/autoconf/)
+
+If you get the tree from the repository, you will need to use the autogen.sh
+script. It calls all the GNU tools needed to prepare the tree configuration.
+
+
+
+Mathieu Desnoyers 
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/autogen.sh b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/autogen.sh
new file mode 100755 (executable)
index 0000000..1b5ca02
--- /dev/null
@@ -0,0 +1,177 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+DIE=0
+
+if [ -n "$GNOME2_DIR" ]; then
+       ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS"
+       LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH"
+       PATH="$GNOME2_DIR/bin:$PATH"
+       export PATH
+       export LD_LIBRARY_PATH
+fi
+
+(test -f $srcdir/configure.in) || {
+    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+    echo " top-level package directory"
+    exit 1
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+  echo
+  echo "**Error**: You must have \`autoconf' installed."
+  echo "Download the appropriate package for your distribution,"
+  echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+  DIE=1
+}
+
+(grep "^AC_PROG_INTLTOOL" $srcdir/configure.in >/dev/null) && {
+  (intltoolize --version) < /dev/null > /dev/null 2>&1 || {
+    echo 
+    echo "**Error**: You must have \`intltool' installed."
+    echo "You can get it from:"
+    echo "  ftp://ftp.gnome.org/pub/GNOME/"
+    DIE=1
+  }
+}
+
+(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.in >/dev/null) && {
+  (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || {
+    echo
+    echo "**Error**: You must have \`xml-i18n-toolize' installed."
+    echo "You can get it from:"
+    echo "  ftp://ftp.gnome.org/pub/GNOME/"
+    DIE=1
+  }
+}
+
+(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
+  (libtool --version) < /dev/null > /dev/null 2>&1 || {
+    echo
+    echo "**Error**: You must have \`libtool' installed."
+    echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+    DIE=1
+  }
+}
+
+(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.in >/dev/null) && {
+  (grep "sed.*POTFILES" $srcdir/configure.in) > /dev/null || \
+  (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
+    echo
+    echo "**Error**: You must have \`glib' installed."
+    echo "You can get it from: ftp://ftp.gtk.org/pub/gtk"
+    DIE=1
+  }
+}
+
+(automake-1.7 --version) < /dev/null > /dev/null 2>&1 || {
+  echo
+  echo "**Error**: You must have \`automake' installed."
+  echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+  DIE=1
+  NO_AUTOMAKE=yes
+}
+
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal-1.7 --version) < /dev/null > /dev/null 2>&1 || {
+  echo
+  echo "**Error**: Missing \`aclocal'.  The version of \`automake'"
+  echo "installed doesn't appear recent enough."
+  echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
+  DIE=1
+}
+
+if test "$DIE" -eq 1; then
+  exit 1
+fi
+
+if test -z "$*"; then
+  echo "**Warning**: I am going to run \`configure' with no arguments."
+  echo "If you wish to pass any to it, please specify them on the"
+  echo \`$0\'" command line."
+  echo
+fi
+
+case $CC in
+xlc )
+  am_opt=--include-deps;;
+esac
+
+for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.in -print`
+do 
+  dr=`dirname $coin`
+  if test -f $dr/NO-AUTO-GEN; then
+    echo skipping $dr -- flagged as no auto-gen
+  else
+    echo processing $dr
+    ( cd $dr
+
+      aclocalinclude="$ACLOCAL_FLAGS"
+
+      if grep "^AM_GLIB_GNU_GETTEXT" configure.in >/dev/null; then
+       echo "Creating $dr/aclocal.m4 ..."
+       test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
+       echo "Running glib-gettextize...  Ignore non-fatal messages."
+       echo "no" | glib-gettextize --force --copy
+       echo "Making $dr/aclocal.m4 writable ..."
+       test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
+      fi
+      if grep "^AC_PROG_INTLTOOL" configure.in >/dev/null; then
+        echo "Running intltoolize..."
+       intltoolize --copy --force --automake
+      fi
+      if grep "^AM_PROG_XML_I18N_TOOLS" configure.in >/dev/null; then
+        echo "Running xml-i18n-toolize..."
+       xml-i18n-toolize --copy --force --automake
+      fi
+      if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
+       if test -z "$NO_LIBTOOLIZE" ; then 
+         echo "Running libtoolize..."
+         libtoolize --force --copy
+       fi
+      fi
+      echo "Running aclocal-1.7 $aclocalinclude ..."
+      aclocal-1.7 $aclocalinclude
+      if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
+       echo "Running autoheader..."
+       autoheader
+      fi
+      echo "Running automake-1.7 --gnu $am_opt ..."
+      automake-1.7 --add-missing --gnu $am_opt
+      echo "Running autoconf ..."
+      autoconf
+    )
+  fi
+done
+
+conf_flags="--enable-maintainer-mode"
+
+
+#if [ -a "$srcdir/include" ]; then
+#      echo -n Removing old system include behavior emulation... 
+#      rm -rf $srcdir/include
+#      echo done.
+#fi
+#echo -n Creating the system include behavior emulation... 
+#mkdir $srcdir/include
+#mkdir $srcdir/include/ltt
+#ln -sf ../../LibLTT/ltt.h $srcdir/include/ltt/ltt.h
+#mkdir $srcdir/include/lttv
+#ln -sf ../../lttv/module.h $srcdir/include/lttv/module.h
+#ln -sf ../../lttv/hook.h $srcdir/include/lttv/hook.h
+#ln -sf ../../lttv/traceWindow.h $srcdir/include/lttv/traceWindow.h
+#echo done.
+
+
+
+if test x$NOCONFIGURE = x; then
+  echo Running $srcdir/configure $conf_flags "$@" ...
+  $srcdir/configure $conf_flags "$@" \
+  && echo Now type \`make\' to compile. || exit 1
+else
+  echo Skipping configure process.
+fi
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/configure.in b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/configure.in
new file mode 100644 (file)
index 0000000..a77108e
--- /dev/null
@@ -0,0 +1,139 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 Mathieu Desnoyers
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+# MA 02111-1307, USA.
+
+
+
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.57)
+AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
+#AC_WITH_LTDL  # not needed ?
+AM_INIT_AUTOMAKE(LinuxTraceToolkitViewer,0.6.9-10102005)
+AM_CONFIG_HEADER(config.h)
+AM_PROG_LIBTOOL
+
+AM_PATH_GLIB_2_0(2.4.0, ,AC_MSG_ERROR([glib is required in order to compile LinuxTraceToolkit - download it from ftp://ftp.gtk.org/pub/gtk]) , gmodule)
+
+AM_PATH_GTK_2_0(2.4.0, ,AC_MSG_ERROR([gtk is required in order to compile GUI - download it from ftp://ftp.gtk.org/pub/gtk]) , gmodule)
+
+AC_PATH_PROGS(BASH, bash)
+
+AC_SYS_LARGEFILE
+
+# Checks for programs.
+AC_PROG_CC
+
+# Checks for libraries.
+AC_CHECK_LIB([popt], [poptGetNextOpt], POPT_LIBS="-lpopt",AC_MSG_ERROR([libpopt is required in order to compile LinuxTraceToolkit])  )
+#AC_CHECK_LIB([m], [round], M_LIBS="-lm",AC_MSG_ERROR([Mathematical libraries are missing.])  )
+
+AC_CHECK_LIB([util], [forkpty], UTIL_LIBS="-lutil", AC_MSG_ERROR([libutil is
+required in order to compile LinuxTraceToolkit]))
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/time.h unistd.h])
+
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+
+pkg_modules="gtk+-2.0 >= 2.0.0"
+PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
+PACKAGE_CFLAGS="-Wall -Wformat"
+AC_SUBST(PACKAGE_CFLAGS)
+AC_SUBST(PACKAGE_LIBS)
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_MALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_CHECK_FUNCS([select])
+
+#CPPFLAGS="$CPPFLAGS -I"
+
+AM_CONDITIONAL(LTTVSTATIC, test "$enable_lttvstatic" = yes)
+lttvlibdir="${libdir}/lttv"
+lttvplugindir="${lttvlibdir}/plugins"
+#lttlibdir="${libdir}/ltt"
+top_lttvdir="\$(top_srcdir)/lttv"
+top_lttvwindowdir="\$(top_srcdir)/lttv/modules/gui/lttvwindow"
+
+DEFAULT_INCLUDES="-I\$(top_srcdir) -I\$(top_lttvdir) -I\$(top_lttvwindowdir)"
+
+#CPPFLAGS="${GLIB_CFLAGS}"
+#AC_SUBST(CPPFLAGS)
+
+lttincludedir="${includedir}/ltt"
+lttvincludedir="${includedir}/lttv"
+lttvwindowincludedir="${includedir}/lttvwindow"
+lttctlincludedir="${includedir}/liblttctl"
+
+AC_SUBST(POPT_LIBS)
+AC_SUBST(UTIL_LIBS)
+AC_SUBST(lttvlibdir)
+AC_SUBST(lttvplugindir)
+#AC_SUBST(lttlibdir)
+AC_SUBST(top_lttvdir)
+AC_SUBST(top_lttvwindowdir)
+AC_SUBST(DEFAULT_INCLUDES)
+AC_SUBST(lttincludedir)
+AC_SUBST(lttvincludedir)
+AC_SUBST(lttvwindowincludedir)
+AC_SUBST(lttctlincludedir)
+
+AC_CONFIG_FILES([Makefile
+     liblttctl/Makefile
+     lttctl/Makefile
+                lttv/Makefile
+                lttv/lttv/Makefile
+                lttv/modules/Makefile
+                lttv/modules/text/Makefile
+                lttv/modules/gui/Makefile
+                lttv/modules/gui/lttvwindow/Makefile
+                lttv/modules/gui/interrupts/Makefile
+                lttv/modules/gui/diskperformance/Makefile
+                lttv/modules/gui/lttvwindow/lttvwindow/Makefile
+                lttv/modules/gui/lttvwindow/pixmaps/Makefile
+                lttv/modules/gui/controlflow/Makefile
+                lttv/modules/gui/detailedevents/Makefile
+                lttv/modules/gui/statistics/Makefile
+     lttv/modules/gui/filter/Makefile
+     lttv/modules/gui/tracecontrol/Makefile
+                lttd/Makefile
+                ltt/Makefile
+     doc/Makefile
+     doc/developer/Makefile
+     doc/developer/developer_guide/Makefile
+     doc/developer/developer_guide/docbook/Makefile
+     doc/developer/developer_guide/html/Makefile
+     doc/user/Makefile
+     doc/user/user_guide/Makefile
+     doc/user/user_guide/docbook/Makefile
+     doc/user/user_guide/html/Makefile
+     facilities/Makefile])
+AC_OUTPUT
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/Makefile.am
new file mode 100644 (file)
index 0000000..528d881
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = developer user
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/Makefile.am
new file mode 100644 (file)
index 0000000..4306cca
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = developer_guide
+
+EXTRA_DIST = coding.html discuss.html format.html guiControlFlow.html gui_layout.txt hook_prio.txt index.html library-header.txt ltt-to-do.html lttv.html lttvwindow_events_delivery.txt process_traceset_strict_boundaries.txt program-header.txt requests_servicing_schedulers.txt status.html todo.html
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/coding.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/coding.html
new file mode 100644 (file)
index 0000000..4822f45
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Coding practices</title>
+</head>
+  <body>
+        
+<h1>Coding practices</h1>
+        
+<p>
+The Linux Trace Toolkit viewer and libltt libraries use the coding standards
+of the underlying <A HREF="www.gtk.org">glib and gtk libraries</A>.
+This includes: 
+
+<UL>
+<LI>lower case file names without underscore but with an occasional dash,
+<LI>lower case function names with underscores separating words,
+<LI>type names starting with a capital letter and with capital letters
+separating words.
+</UL>
+
+<P>
+Each file in the libltt library should contain a 
+<A HREF=library-header.txt">LGPL header</A> while each file in the LTT viewer
+should contain a
+<A HREF=library-header.txt">GPL header</A>.
+
+</body>
+</html>
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/Makefile.am
new file mode 100644 (file)
index 0000000..7df24eb
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = docbook html
+
+EXTRA_DIST = developer_guide.dvi
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/developer_guide.dvi b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/developer_guide.dvi
new file mode 100644 (file)
index 0000000..b4379ec
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/developer_guide.dvi differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/Makefile.am
new file mode 100644 (file)
index 0000000..e0c05ea
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST = developer_guide.docbook lttv-context.eps lttv-context.png
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/developer_guide.docbook b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/developer_guide.docbook
new file mode 100644 (file)
index 0000000..f410532
--- /dev/null
@@ -0,0 +1,668 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+                      "/usr/share/sgml/docbook/dtd/4.3/xdocbook.dtd">
+<!--<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" >-->
+
+<book>
+
+<bookinfo>
+<title>Linux Trace Toolkit Viewer Developer Guide</title>
+<authorgroup>
+<author>
+<firstname>Mathieu</firstname>
+<surname>Desnoyers</surname>
+</author>
+</authorgroup>
+
+<date>01/12/2004</date>
+<releaseinfo>1.00.00</releaseinfo>
+
+<abstract>
+<para>
+This document describes the basic steps necessary to develop within the 
+<application>Linux Trace Toolkit Viewer</application> project.
+
+</para>
+</abstract>
+
+<keywordset>
+<keyword>Linux Trace Toolkit Viewer</keyword>
+<keyword>text</keyword>
+<keyword>module</keyword>
+<keyword>context</keyword>
+</keywordset>
+
+</bookinfo>
+<chapter>
+<title>Linux Trace Toolkit Viewer Text Module Tutorial</title>
+
+<sect1>
+<title>Introduction</title>
+<para>
+This chapter explains all the steps that are necessary to create a text module
+in LTTV.
+</para>
+</sect1>
+
+<sect1>
+<title>A typical module</title>
+<para>
+A typical module must have a init() and destroy() function. Please refer to
+lttv/modules/text/textDump.c for the detail of these functions.
+</para>
+<para>
+The init() function is called when the library is loaded and destroy()
+inversely. It adds options to the command line by calling "lttv_option_add" from
+option.h
+</para>
+<para>
+The module communicates with the main lttv program through the use of global
+attributes. Use lttv/attribute.h, lttv/iattribute.h and lttv/lttv.h, and then
+LTTV_IATTRIBUTE(lttv_global_attributes()) to get the pointer to these
+global attributes.
+</para>
+<para>
+You can then add your hooks (functions that follows the prototype of a hook, as
+defined in lttv/hook.h) in the different hook lists defined in lttv/lttv.h. Note
+that hooks have an assigned priority. This is necessary to inform the trace
+reader that a specific hook needs to be called, for example, before or after the
+state update done for an event by the state module. For that specific example, a
+hook could use the LTTV_PRIO_STATE-5 to get called before the state update and a
+second hook could use the LTTV_PRIO_STATE+5 to get called after the state
+update. This is especially important for graphical module, which is the subject
+of a the chapter named "Linux Trace Toolkit Viewer Graphical Module Tutorial".
+</para>
+<para>
+You should also take a look at lttv/state.c, where by_id hooks are used. When
+you only need some specific events, you should use this interface. It makes the
+event filtering sooner in the dispatch chain : you hook doesn't have to be
+called for each event, only the ones selected. That improves the performances a
+lot!
+</para>
+<para>
+Note that you should use the lttv_trace_find_hook method from
+lttv/tracecontext.h to connect the hook to the right facility/event type. See
+state.c for an example. A problem that may arise is that the LttvTraceHook
+structure must be passed as hook_data when registering the hook. In fact, it is
+not necessary for it to be directly passed as the hook_data parameter. As long
+as the hook function can access the LttvTraceHook fields necessary to parse the
+LttEvent, there is no problem. In a complex viewer where you need a pointer to
+your own data structure, just keep a pointer to the LttvTraceHook structure
+inside your own data structure, and give to pointer to your data structure in
+parameter as the hook_data.
+</para>
+<para>
+Then, you should use the macro LTTV_MODULE, defined in lttv/module.h. It allows
+you to specify the module name, a short and a long description, the init and
+destroy functions and the module dependencies. That permits to the module
+backend to load the right dependencies when needed.
+</para>
+<para>
+A typical text module will depend on batchAnalysis for the batch computation of a
+trace, and simply register before and after trace hooks, as weel as the most
+important one : a event hook.
+</para>
+</sect1>
+
+<sect1>
+<title>The hooks</title>
+<para>
+The before and after trace hooks only exists to be able to generate a report at
+the end of a trace computation. The effective computation is done by the event
+hooks.
+</para>
+<para>
+These hooks does particular computation on data arriving as argument, a
+call_data. The type of the call_data, when a hook is called during the trace
+read, is a traceset context. It contains all the necessary information about the
+read in progress. This is the base class from which inherits trace set
+state, and trace set/trace/tracefile state is the base classe of trace
+set/trace/tracefile statistics. All these types can be casted to another without
+problem (a TracesetState, for example, can be casted to a TracesetContext, but
+it's not true for the casting between a TraceContext and a TracesetContext, see
+the chapter "How to use the trace reading context" for details). They offer the
+input data and they give a container (the attributes of the trace set/trace/tracefile
+statistics) to write the output of this hook.
+</para>
+<para>
+The idea behind writing in the attributes container is to provide an extensible
+way of storing any type of information. For example, a specific module that adds
+statistics to a trace can store them there, and the statistic printout will
+automatically include the results produced by the specific module.
+</para>
+<para>
+Output data does not necessarily need to be stored in such a global container
+though. If we think of data of which we need to keed track during the execution,
+an event counter for example, we should create our own data structure that
+contains this counter, and pass the address of the allocated structure as the
+hook_data parameter of the hook list creation function. That way, the hook will
+be called with its hook_data as first parameter, which it can read and write. We
+can think of this structure as the data related to the function that persists
+between each call to the hook. You must make sure that you cast the hook_data to
+the type of the structure before you use it in the hook function.
+</para>
+<para>
+The detail about how to access the different fields of the reading context (the
+hook's call_data) will be discussed in the chapter  "How to use the trace
+reading context".
+</para>
+</sect1>
+
+
+</chapter>
+
+
+<chapter>
+<title>How to use the Linux Trace Toolkit Viewer's Reading Context</title>
+
+<sect1>
+<title>Introduction</title>
+<para>
+This chapter describes how to use the Linux Trace Toolkit reading context, a
+data structure that is given as call data parameter of the modules'callbacks.
+</para>
+<para>
+Linux Trace Toolkit Viewer provides a backend that reads the traces. In combines
+them in tracesets. A trace is an abstaction over many tracefiles, one per CPU.
+LTTV reads the whole trace together, providing the events to modules by calling
+their pre-registered hook lists in a chronological order.
+</para>
+</sect1>
+
+<sect1>
+<title>Why an event driven trace reader ?</title>
+<para>
+The complexity of synchronizing the tracesets is then hidden to the viewer. Some
+future plans involve to be able to put many traces together in a trace set.
+Before this becomes possible, the time of each trace must be synchronized in
+some way. Some work is actually done to create a module that uses the network
+traffic shared by different computers to synchronize the time of different
+traces.
+</para>
+<para>
+In order to make each module integrate well with each other, we made the trace
+reader a simple hook caller. For each event it reads, it just calls the hook
+lists for this event. For each event, it calls the by_id specific hooks
+registered for this event and also the "main" hooks, registered for all events.
+Note that the two hook lists are merged when called so the priority of the
+hooks of each list is respected. For example, a hook of higher priority (20) in
+the main list will be called before a hook of lower priority (40) from the
+by_id specific list.
+</para>
+</sect1>
+
+<sect1>
+<title>Using the reading context</title>
+<para>
+If you have read the tutorials about writing a text and a graphic module, you
+should be fairly ready to use the information provided to your hook by the
+reading API.
+</para>
+<para>
+The data structures of the reading context are based on the gobject, a
+object-oriented library from the glib. Some evolved types that are found in the
+context also comes from the "glib" (GArray, GHashTable and so on). For detailed
+information about "gobjects" and the "glib", see the <ulink
+url="http://www.gtk.org">www.gtk.org</ulink> website. They provide a complete
+API reference about the data types they provide.
+</para>
+<para>
+The reading context is object oriented. It is described by the lttv/tracecontext.h
+header. Is can be illustrated with this UML class diagram :
+</para>
+<para>
+<screenshot>
+<mediaobject>
+<imageobject>
+<imagedata srccredit="Mathieu Desnoyers, 2004" fileref="lttv-context.png"
+format="PNG" align="center"/>
+</imageobject>
+<imageobject>
+<imagedata srccredit="Mathieu Desnoyers, 2004"
+fileref="lttv-context.eps"
+format="EPS" align="center"/>
+</imageobject>
+<!--<imagedata srccredit="Mathieu Desnoyers, 2004" fileref="lttv-numbered-6.svg"
+format="SVG" align="center" scalefit="1"/>
+</imageobject>-->
+<caption><para>Linux Trace Toolkit Viewer Reading Context Class Diagram</para></caption>
+</mediaobject>
+</screenshot>
+</para>
+<para>
+Though, for performance's sake, navigating through it is not as encapsulated as
+it could. Consider the class attributes to be all public (no get/set functions).
+Sometimes, iteration upon a specific element can be uneasy. For example, you may
+have to get the number of tracefiles in a trace from the "vt" field of the trace
+context to be able to iterate over all the tracefiles contained by the trace.
+</para>
+<para>
+To facilitate the common operations on the reading context, LTTV now provides a
+header that consists of simple macros : lttv/contextmacros.h. It gives an object
+look-and-feel to the context classes. Simple "GET" macros can be used to easily
+access the different fields are iterate over the elements (and get the total
+number of elements too).
+</para>
+</sect1>
+</chapter>
+
+<chapter>
+<title>Linux Trace Toolkit Viewer Graphical Module Tutorial</title>
+<sect1>
+<title>Introduction</title>
+<para>
+As a matter of fact, most of the things said for the text modules still hold for
+the graphical modules. However, the fact that every module must instanciate
+objects (called viewers) more than once changes a little bit the scenario. It is
+then impossible to use static structures : everything must be instanciated at
+run-time, except the structures related to the module itself.
+</para>
+</sect1>
+<sect1>
+<title>The static part of a module</title>
+<para>
+A module must have a static part to be able to get loaded just like a text
+module. Now, let's see the differences. The graphical module depends on the
+"lttvwindow" module. See module.c from the control flow viewer for an example.
+</para>
+<para>
+The init() and destroy() functions must register functions that can be called by
+user interaction to instanciate the viewers. That's the goal of
+lttvwindow_register_constructor() and lttvwindow_unregister_constructor() :
+they register a function with a menu entry and an icon. The main window will
+shown them in its interface and call the function when the button or menu item
+is selected. This hook function must receive a pointer to a "Tab" object in
+parameter.
+</para>
+<para>
+Also note the presence of the destroy_walk() method. It is called when the
+module is unloaded : it must destroy all the instances of the viewers from the
+module.
+</para>
+</sect1>
+<sect1>
+<title>The dynamic part of a module : the viewer</title>
+<para>
+The dynamic part starts with the constructor of the viewer. It is called by the
+main window when the corresponding button or menu item is selected. See
+h_guicontrolflow() from control flow viewer eventhooks.c for an example. It does
+basic connexion to the tab's events available : time window change notification,
+current time notification, redraw notification, continue notification. All these
+function should be implemented in your viewer if you want the data you shown to
+be synchronised with the main window and the other viewers. It also calls the
+background computation, which will be discussed in the next section.
+</para>
+<para>
+This is also at this point that the viewer does create it's own memory footprint
+: its inner structure. This structure will have to be passed as hook_data to
+each function registered by the viewer : this is what makes the functions
+"belong" to this instance of the viewer.
+</para>
+</sect1>
+<sect1>
+<title>How to request background computation</title>
+<para>
+You will also notice the presence of a request_background_data() called in the
+constructor. This function, in eventhooks.c, does verify for the presence of the
+state information that could be precomputed by the main window background
+computation. If it has not been precomputed, we ask for a computation and show
+partial data. We also register a hook that will be called (notified) by the main
+window when the requested data will become ready, so the viewer can update
+itself with the new data. If no partial information would have made sense in a
+particular viewer, one could choose to shown a "waiting for computation" message
+while waiting for the notification. See lttvwindow/lttvwindowtraces.h for the API
+of the background requests.
+</para>
+</sect1>
+
+<sect1>
+<title>How to handle events and use the graphical trace reading service</title>
+<para>
+The events that are delivered by the main window are defined in
+lttvwindow/lttvwindow.h. Let's describe them and their use in details. Remember
+that you can refer to the control flow viewer module as an example.
+</para>
+
+<sect2>
+<title>Module Related API</title>
+<para>
+A viewer plugin is, before anything, a plugin. As a dynamically loadable
+module, it thus has an init and a destroy function called whenever it is
+loaded/initialized and unloaded/destroyed. A graphical module depends on
+lttvwindow for construction of its viewer instances. In order to achieve
+this, it must register its constructor function to the main window along
+with button description or text menu entry description. A module keeps
+a list of every viewer that currently sits in memory so it can destroy
+them before the module gets unloaded/destroyed.
+</para>
+<para>
+The contructor registration to the main windows adds button and menu
+entry to each main window, thus allowing instanciation of viewers.
+</para>
+</sect2>
+<sect2>
+<title>Main Window</title>
+<para>
+The main window is a container that offers menus, buttons and a
+notebook. Some of those menus and buttons are part of the core of the
+main window, others are dynamically added and removed when modules are
+loaded/unloaded.
+</para>
+<para>
+The notebook contains as much tabs as wanted. Each tab is linked with
+a set of traces (traceset). Each trace contains many tracefiles (one
+per cpu).  A trace corresponds to a kernel being traced. A traceset
+corresponds to many traces read together. The time span of a traceset
+goes from the earliest start of all the traces to the latest end of all
+the traces.
+</para>
+<para>
+Inside each tab are added the viewers. When they interact with the main
+window through the lttvwindow API, they affect the other viewers located
+in the same tab as they are.
+</para>
+<para>
+The insertion of many viewers in a tab permits a quick look at all the
+information wanted in a glance. The main window does merge the read
+requests from all the viewers in the same tab in a way that every viewer
+will get exactly the events it asked for, while the event reading loop
+and state update are shared. It improves performance of events delivery
+to the viewers.
+</para>
+</sect2>
+
+<sect2>
+<title>Viewer Instance Related API</title>
+<para>
+The lifetime of a viewer is as follows. The viewer constructor function
+is called each time an instance view is created (one subwindow of this
+viewer type is created by the user either by clicking on the menu item
+or the button corresponding to the viewer). Thereafter, the viewer gets
+hooks called for different purposes by the window containing it. These
+hooks are detailed below. It also has to deal with GTK Events. Finally,
+it can be destructed by having its top level widget unreferenced by the
+main window or by any GTK Event causing a "destroy-event" signal on the
+its top widget. Another possible way for it do be destroyed is if the
+module gets unloaded. The module unload function will have to emit a
+"destroy" signal on each top level widget of all instances of its viewers.
+</para>
+</sect2>
+<sect2>
+<title>Notices from Main Window</title>
+<variablelist>
+<varlistentry>
+<term>time_window</term>
+<listitem>
+<simpara>This is the time interval visible on the viewer's tab. Every
+              viewer that cares about being synchronised by respect to the
+              time with other viewers should register to this notification.
+              They should redraw all or part of their display when this
+              occurs.</simpara>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>traceset</term>
+<listitem>
+<simpara>This notification is called whenever a trace is added/removed
+              from the traceset. As it affects all the data displayed by the
+              viewer, it sould redraw itself totally.</simpara>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>filter</term>
+<listitem>
+<simpara>This feature has not been implemented yet.</simpara>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>current_time</term>
+<listitem>
+<simpara>Being able to zoom nearer a specific time or highlight a specific
+              time on every viewer in synchronicity implies that the viewer
+              has to shown a visual sign over the drawing or select an event
+              when it receives this notice. It should also inform the main
+              window with the appropriate report API function when a user
+              selects a specific time as being the current time.</simpara>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>dividor</term>
+<listitem>
+<simpara>This notice links the positions of the horizontal dividors
+              between the graphic display zone of every viewer and their Y axis,
+              typically showing processes, cpus, ...</simpara>
+</listitem>
+</varlistentry>
+</variablelist>
+</sect2>
+<sect2>
+<title>Reporting Changes to the Main Window</title>
+<para>
+In most cases, the enclosing window knows about updates such as described
+in the Notification section higher. There are a few cases, however, where
+updates are caused by actions known by a view instance. For example,
+clicking in a view may update the current time; all viewers within
+the same window must be told about the new current time to change the
+currently highlighted time point. A viewer reports such events by calling
+lttvwindow_report_current_time on its lttvwindow.  The lttvwindow will
+consequently call current_time_notify for each of its contained viewers.
+</para>
+<para>
+Available report methods are :
+<itemizedlist>
+<listitem>
+<simpara>
+lttvwindow_report_time_window : reports the new time window.
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+lttvwindow_report_current_time : reports the new current time.
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+lttvwindow_report_dividor : reports the new horizontal dividor's position.
+</simpara>
+</listitem>
+</itemizedlist>
+</para>
+</sect2>
+
+<sect2>
+<title>Requesting Events to Main Window</title>
+<para>
+Events can be requested by passing a EventsRequest structure to the main
+window.  They will be delivered later when the next g_idle functions
+will be called.  Event delivery is done by calling the event hook for
+this event ID, or the main event hooks. A pointer to the EventsRequest
+structure is passed as hook_data to the event hooks of the viewers.
+</para>
+<para>
+EventsRequest consists in 
+<itemizedlist>
+<listitem>
+<simpara>
+a pointer to the viewer specific data structure
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+a start timestamp or position
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+a stop_flag, ending the read process when set to TRUE
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+a end timestamp and/or position and/or number of events to read
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+hook lists to call for traceset/trace/tracefile begin and end, and for each
+  event (event hooks and event_by_id hooks).
+</simpara>
+</listitem>
+</itemizedlist>
+</para>
+<para>
+The main window will deliver events for every EventRequests it has
+pending through an algorithm that guarantee that all events requested,
+and only them, will be delivered to the viewer between the call of the
+tracefile_begin hooks and the call of the tracefile_end hooks.
+</para>
+<para>
+If a viewer wants to stop the event request at a certain point inside the
+event hooks, it has to set the stop_flag to TRUE and return TRUE from the
+hook function. Then return value will stop the process traceset. Then,
+the main window will look for the stop_flag and remove the EventRequests
+from its lists, calling the process_traceset_end for this request (it
+removes hooks from the context and calls the after hooks).
+</para>
+<para>
+It no stop_flag is risen, the end timestamp, end position or number
+of events to read has to be reached to determine the end of the
+request. Otherwise, the end of traceset does determine it.
+</para>
+</sect2>
+<sect2>
+<title>GTK Events</title>
+<sect3>
+<title>Events and Signals</title>
+<para>
+GTK is quite different from the other graphical toolkits around
+there. The main difference resides in that there are many X Windows
+inside one GtkWindow, instead of just one. That means that X events are
+delivered by the glib main loop directly to the widget corresponding to
+the GdkWindow affected by the X event.
+</para>
+<para>
+Event delivery to a widget emits a signal on that widget. Then, if a
+handler is connected to this widget's signal, it will be executed. There
+are default handlers for signals, connected at class instantiation
+time. There is also the possibility to connect other handlers to these
+signals, which is what should be done in most cases when a viewer needs
+to interact with X in any way.
+</para>
+
+<para>
+Signal emission and propagation is described there : 
+
+<itemizedlist>
+<listitem>
+<simpara>
+http://www.gtk.org/tutorial/sec-signalemissionandpropagation.html
+</simpara>
+</listitem>
+</itemizedlist>
+</para>
+
+<para>
+For further information on the GTK main loop (now a wrapper over glib main loop)
+see :
+
+<itemizedlist>
+<listitem>
+<simpara>
+http://developer.gnome.org/doc/API/2.0/gtk/gtk-General.html
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+http://developer.gnome.org/doc/API/2.0/glib/glib-The-Main-Event-Loop.html
+</simpara>
+</listitem>
+</itemizedlist>
+</para>
+
+
+<para>
+For documentation on event handling in GTK/GDK, see :
+
+<itemizedlist>
+<listitem>
+<simpara>
+http://developer.gnome.org/doc/API/2.0/gdk/gdk-Events.html
+</simpara>
+</listitem>
+<listitem>
+<simpara>
+http://developer.gnome.org/doc/API/2.0/gdk/gdk-Event-Structures.html
+</simpara>
+</listitem>
+</itemizedlist>
+</para>
+
+
+<para>
+Signals can be connected to handlers, emitted, propagated, blocked, 
+stopped. See :
+
+<itemizedlist>
+<listitem>
+<simpara>
+http://developer.gnome.org/doc/API/2.0/gobject/gobject-Signals.html
+</simpara>
+</listitem>
+</itemizedlist>
+</para>
+
+</sect3>
+
+
+<sect3>
+<title>The "expose_event"</title>
+<para>
+Provides the exposed region in the GdkEventExpose structure. 
+</para>
+<para>
+There are two ways of dealing with exposures. The first one is to directly
+draw on the screen and the second one is to draw in a pixmap buffer,
+and then to update the screen when necessary.
+</para>
+<para>
+In the first case, the expose event will be responsible for registering
+hooks to process_traceset and require time intervals to the main
+window. So, in this scenario, if a part of the screen is damaged, the
+trace has to be read to redraw the screen.
+</para>
+<para>
+In the second case, with a pixmap buffer, the expose handler is only
+responsible of showing the pixmap buffer on the screen. If the pixmap
+buffer has never been filled with a drawing, the expose handler may ask
+for it to be filled.
+</para>
+<para>
+The interest of using events request to the main window instead of reading
+the events directly from the trace comes from the fact that the main
+window does merge requests from the different viewers in the same tab so
+that the read loop and the state update is shared. As viewers will, in
+the common scenario, request the same events, only one pass through the
+trace that will call the right hooks for the right intervals will be done.
+</para>
+<para>
+When the traceset read is over for a events request, the traceset_end
+hook is called. It has the responsibility of finishing the drawing if
+some parts still need to be drawn and to show it on the screen (if the
+viewer uses a pixmap buffer).
+</para>
+<para>
+It can add dotted lines and such visual effects to enhance the user's
+experience.
+</para>
+</sect3>
+</sect2>
+</sect1>
+
+</chapter>
+
+
+
+</book>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.eps b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.eps
new file mode 100644 (file)
index 0000000..fb522a4
--- /dev/null
@@ -0,0 +1,4227 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner
+%%Title: lttv-context.eps
+%%CreationDate: Thu Dec  2 00:27:27 2004
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%Pages: 1
+%%BoundingBox: 14 14 447 327
+%%EndComments
+%%BeginProlog
+% Use own dictionary to avoid conflicts
+10 dict begin
+%%EndProlog
+%%Page: 1 1
+% Translate for offset
+14.173228346456693 14.173228346456693 translate
+% Translate to begin of first scanline
+0 312.65546218487395 translate
+432 -312.65546218487395 scale
+% Image geometry
+952 689 8
+% Transformation matrix
+[ 952 0 0 689 0 0 ]
+% Strings to hold RGB-samples per scanline
+/rstr 952 string def
+/gstr 952 string def
+/bstr 952 string def
+{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
+true 3
+%%BeginData:       253599 ASCII Bytes
+colorimage
+JcC<$JcC<$JcC<$JcEjlJ,~>
+JcC<$JcC<$JcC<$JcEjlJ,~>
+JcC<$JcC<$JcC<$JcEjlJ,~>
+JcC<$huBn\JcC<$JcC<$]`3K~>
+JcC<$huBn\JcC<$JcC<$]`3K~>
+JcC<$huBn\JcC<$JcC<$]`3K~>
+JcC<$hu<ZVZMsn)JcC<$JcC<$]`3K~>
+JcC<$hu<ZVZMsn)JcC<$JcC<$]`3K~>
+JcC<$hu<ZVZMsn)JcC<$JcC<$]`3K~>
+JcC<$hu<ZVZMsn)JcC<$JcC<$]`3K~>
+JcC<$hu<ZVZMsn)JcC<$JcC<$]`3K~>
+JcC<$hu<ZVZMsn)JcC<$JcC<$]`3K~>
+JcC<$hu<ZVo)J^ioDeUdg&M$OJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ioDeUdg&M$OJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ioDeUdg&D*RJ:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;Zcsf)P^LJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;Zcsf)P^LJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;Zcsf)GdOJ:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVo)J^irVufr!<;utrVultrVult!ri9#r;cfrr;cltrW)HfrW%NLJcC<$JcEIaJ,~>
+JcC<$hu<ZVo)J^irVufr!<;utrVultrVult!ri9#r;cfrr;cltrW)HfrW%NLJcC<$JcEIaJ,~>
+JcC<$hu<ZVo)J^irVufr!<;utrVultrVult!ri9#r;cfrr;cltrW)Hf!W[b$JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVuisr;Zcss8W*!rVult!ri6#nc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVuisr;Zcss8W*!rVult!ri6#nc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVuisr;Zcss8W*!rVult!ri6#nc&XjJ:N4NJcC<$JcEIa
+J,~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultqu?Zrs8W*!rVult!ri6#nc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultqu?Zrs8W*!rVult!ri6#nc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultqu?Zrs8W*!rVult!ri6#nc&XjJ:N4NJcC<$JcEIa
+J,~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrVufrs8W*!rVucqnc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrVufrs8W*!rVucqnc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrVufrs8W*!rVucqnc&XjJ:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultmf37dJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultmf37dJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultmf*=gJ:N4NJcC<$JcEIa
+J,~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultmf37dJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultmf37dJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)J^ir;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultmf*=gJ:N4NJcC<$JcEIa
+J,~>
+JcC<$hu<ZVo)JRes8W&us8W&urr;uurVultrVucqs8W#ts8W#tnc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)JRes8W&us8W&urr;uurVultrVucqs8W#ts8W#tnc/RgJcC<$JcC<$^Ai]~>
+JcC<$hu<ZVo)JRes8W&us8W&urr;uurVultrVucqs8W#ts8W#tnc&XjJ:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZN'n(JcC<$JcC<$^Ai]~>
+JcC<$hu<ZVZMst+J:N4NJcC<$JcEIaJ,~>
+pA][DpAfdEo`"mkZN'n(JcC<$JcC<$^Ai]~>
+pA][DpAfdEo`"mkZN'n(JcC<$JcC<$^Ai]~>
+pA][DpAfdEo`"mkZMst+J:N4NJcC<$JcEIaJ,~>
+pAY*mJcGQG!!%TMo`)&oJcC<$JcC<$^Ai]~>
+pAY*mJcGQG!!%TMo`)&oJcC<$JcC<$^Ai]~>
+pAY*mJcGQG!!%TMo`),qs+#\#JcC<$JcEIaJ,~>
+pAY*mJcGQG!!%TMo`"mkZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!!%TMo`"mkZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!!%TMo`"mkZMst+J:N4NJcC<$JcEIaJ,~>
+pAY*mirB#Ym/Qk]\,ZI.JcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Ym/Qk]\,ZI.JcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Ym/Qk]\,QI/J:[anrr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uup&G$lf)PaMiW&oXJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Yr;Zcsrr;uup&G$lf)PaMiW&oXJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Yr;Zcsrr;uup&G$lf)PaMiVroYJ:[anrr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mirB#YrVufr!<;ut!ri6#rr2rurVultrVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;bjW
+rr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mirB#YrVufr!<;ut!ri6#rr2rurVultrVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;bjW
+rr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mirB#YrVufr!<;ut!ri6#rr2rurVultrVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;bjW
+!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mirB#Yr;Zcsrr;uus8W*!rr2rurVultrVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#6+Z'
+s8N'!iW&oXJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Yr;Zcsrr;uus8W*!rr2rurVultrVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#6+Z'
+s8N'!iW&oXJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Yr;Zcsrr;uus8W*!rr2rurVultrVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#6+Z'
+s8N'!iVroYJ:[anrr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)rs8N*!s8N)ts8N'%rr<'!s8E#ss8N''rr<'!
+rr<&Xs8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)rs8N*!s8N)ts8N'%rr<'!s8E#ss8N''rr<'!
+rr<&Xs8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)rs8N*!s8N)ts8N'%rr<'!s8E#ss8N''rr<'!
+rr<&XrrE+MJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)ts8;rts8N)ts82lrs8E#ts82lss8N)Xs8N(M
+s7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)ts8;rts8N)ts82lrs8E#ts82lss8N)Xs8N(M
+s7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)ts8;rts8N)ts82lrs8E#ts82lss8N)XrrE+M
+JcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)us8N''rr<'!rr<&ts8N)qs8E#us8N)ss8N)X
+s8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)us8N''rr<'!rr<&ts8N)qs8E#us8N)ss8N)X
+s8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mirB#Yr;Zcsrr;uurr;uu!WN/ts8N)ts8N)us8N''rr<'!rr<&ts8N)qs8E#us8N)ss8N)X
+rrE+MJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mirB#Yr;Zcsrr;uurVultqu?ZrrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;ZcsiW&oX
+JcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Yr;Zcsrr;uurVultqu?ZrrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;ZcsiW&oX
+JcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirB#Yr;Zcsrr;uurVultqu?ZrrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;ZcsiVroY
+J:[anrr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mirAlUs8W&us8W&us8W*!qu?ZrrVultrVucqs8W#ts8W#ts8W#trVufrrr;rtj8],ZJcGEC
+!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirAlUs8W&us8W&us8W*!qu?ZrrVultrVucqs8W#ts8W#ts8W#trVufrrr;rtj8],ZJcGEC
+!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mirAlUs8W&us8W&us8W*!qu?ZrrVultrVucqs8W#ts8W#ts8W#trVufrrr;rtj8T,[J:[an
+rr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+p]#dEo`0RCp&>!lZN'n(JcC<$JcC<$^Ai]~>
+p]#dEo`0RCp&>!lZN'n(JcC<$JcC<$^Ai]~>
+p]#dEp&G)CJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&D/pJcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&D/pJcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QDr!<7S#s+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mkPkM^kl1V_li-qbnG`Rjs8N)^rr<&ls8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mkPkM^kl1V_li-qbnG`Rjs8N)^rr<&ls8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mkPkM^kl1V_li-qbnG`Rjs8N)^rr<&lrrE+MJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mc2RbDr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lp](6nJcGEC!!'>)rW%NLJcC<$
+JcEIaJ,~>
+pAY*mc2RbDr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lp](6nJcGEC!!'>)rW%NLJcC<$
+JcEIaJ,~>
+pAY*mc2RbDr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lp\t6oJ:[anrr<&)rrN1NJ:[`O
+s+13$s1\M`~>
+pAY*mo`"pls8E#trs&Q(!!*$!rrDus!!)lqrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!
+rVururW)uu#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uup&G$lJcGEC!!'>)rW%NLJcC<$
+JcEIaJ,~>
+pAY*mo`"pls8E#trs&Q(!!*$!rrDus!!)lqrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!
+rVururW)uu#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uup&G$lJcGEC!!'>)rW%NLJcC<$
+JcEIaJ,~>
+pAY*mo`"pls8E#trs&Q(!!*$!rrDus!!)lqrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!
+rVururW)uu#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uup&>$mJ:[anrr<&)rrN1NJ:[`O
+s+13$s1\M`~>
+pAY*mo`+pkrr3*$s8N'!rr3'#s8N)urr<&qrr<&urr<&rrr<&srr<&urr<&urr<&urr<&urrN3#
+!<2uu!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!pAb-mJcGEC!!'>)
+rW%NLJcC<$JcEIaJ,~>
+pAY*mo`+pkrr3*$s8N'!rr3'#s8N)urr<&qrr<&urr<&rrr<&srr<&urr<&urr<&urr<&urrN3#
+!<2uu!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!pAb-mJcGEC!!'>)
+rW%NLJcC<$JcEIaJ,~>
+pAY*mo`+pkrr3*$s8N'!rr3'#s8N)urr<&qrr<&urr<&rrr<&srr<&urr<&urr<&urr<&urrN3#
+!<2uu!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!pAY-nJ:[anrr<&)
+rrN1NJ:[`Os+13$s1\M`~>
+pAY*mo`"mkrVls"s8N)trrW9$rrE&u!!)`m!!)or!!)rs!!*#u!!*#u!!*#u!s&B$!<3!#!<<'!
+rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<2uu!<2uu!:g*h!.k1Crr<&)s8E"Ls+13$s+13a
+s*t~>
+pAY*mo`"mkrVls"s8N)trrW9$rrE&u!!)`m!!)or!!)rs!!*#u!!*#u!!*#u!s&B$!<3!#!<<'!
+rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<2uu!<2uu!:g*h!.k1Crr<&)s8E"Ls+13$s+13a
+s*t~>
+pAY*mo`"mkrVls"s8N)trrW9$rrE&u!!)`m!!)or!!)rs!!*#u!!*#u!!*#u!s&B$!<3!#!<<'!
+rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<2uu!<2uu!:g'i!.]Y#p&>!lZMst+J:N4NJcC<$
+JcEIaJ,~>
+pAY*mqu?Qos8N'!rVls"s8N)trr<&urrN3#!;QTm!;lcr!;uis!<2uu!<)p!!<3&urr<&urrW9$
+rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)us82les8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mqu?Qos8N'!rVls"s8N)trr<&urrN3#!;QTm!;lcr!;uis!<2uu!<)p!!<3&urr<&urrW9$
+rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)us82les8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mqu?Qos8N'!rVls"s8N)trr<&urrN3#!;QTm!;lcr!;uis!<2uu!<)p!!<3&urr<&urrW9$
+rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)us82lerrE+MJcGEC!!'>)!W[b$JcC<$JcC<$
+^Ai]~>
+pAY*mo`"mkrVls"s8N)trr<&urrN3#!;ZWp!<2uu!;lcr!;uis!<2uu!<)p#!<3'!s7u]rrrE&u
+!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&ds8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mo`"mkrVls"s8N)trr<&urrN3#!;ZWp!<2uu!;lcr!;uis!<2uu!<)p#!<3'!s7u]rrrE&u
+!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&ds8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mo`"mkrVls"s8N)trr<&urrN3#!;ZWp!<2uu!;lcr!;uis!<2uu!<)p#!<3'!s7u]rrrE&u
+!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&drrE+MJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mo`+pkrr3'#s8N)trr<&urrN3#!;ZWp!<2uu!;lcr!;uis!<2uu!<)p$!<3'!rrDus!W`6#
+rr2rurr2rurVm!#s8N'!rr3<*s8N*!rr<'!rrE&u!!)Edrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mo`+pkrr3'#s8N)trr<&urrN3#!;ZWp!<2uu!;lcr!;uis!<2uu!<)p$!<3'!rrDus!W`6#
+rr2rurr2rurVm!#s8N'!rr3<*s8N*!rr<'!rrE&u!!)Edrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mo`+pkrr3'#s8N)trr<&urrN3#!;ZWp!<2uu!;lcr!;uis!<2uu!<)p$!<3'!rrDus!W`6#
+rr2rurr2rurVm!#s8N'!rr3<*s8N*!rr<'!rrE&u!!)Ed!<@Y$s7QBl!4)V+!.]TNs+13$s+13a
+s*t~>
+pAY*mo`"pls8E#trr<&trr<&trr<&ns82itrrE&uquHcs!!*#u!!)ut!s&B$!;c]s!<3&urrW9$
+rrE#t"9AK%!<<#urVult!WN0!rr<&us8;rfs8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mo`"pls8E#trr<&trr<&trr<&ns82itrrE&uquHcs!!*#u!!)ut!s&B$!;c]s!<3&urrW9$
+rrE#t"9AK%!<<#urVult!WN0!rr<&us8;rfs8N(Ms7QBl!4)Y(!.k0$s+13$s1\M`~>
+pAY*mo`"pls8E#trr<&trr<&trr<&ns82itrrE&uquHcs!!*#u!!)ut!s&B$!;c]s!<3&urrW9$
+rrE#t"9AK%!<<#urVult!WN0!rr<&us8;rfrrE+MJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mo`"mkm/R"aT`>#lJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mo`"mkm/R"aT`>#lJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mo`"mkm/R"aT`5#mJ:[anrr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mo`"mkL]@ASJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mo`"mkL]@ASJcGEC!!'>)rW%NLJcC<$JcEIaJ,~>
+pAY*mo`"mkL]7ATJ:[anrr<&)rrN1NJ:[`Os+13$s1\M`~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+p]#dEo`0RCp&>!lZN'n(JcC<$JcC<$^Ai]~>
+p]#dEo`0RCp&>!lZN'n(JcC<$JcC<$^Ai]~>
+p]#dEp&G)CJcGEC!!'>)!W[b$JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&>!lZN'n(JcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QBl!4)V+!.]TNs+13$s+13as*t~>
+pAY*mJcGQGrr@WMp&D/pJcC<$JcC<$^Ai]~>
+pAY*mJcGQGrr@WMp&D/pJcC<$JcC<$^Ai]~>
+pAY*mJcGQG!<@Y$s7QDr!<7S#s+13$s+13as*t~>
+pAY*mJcGQGrr@WMo)Grpnc,fnli3ITe,QWPgAeAWOoKq~>
+pAY*mJcGQGrr@WMo)Grpnc,fnli3ITe,QWPgAeAWOoKq~>
+pAY*mJcGQG!<@Y$s762pJFWZD!:0ZT!7UtP!8@IW!0R;3~>
+pAY*mJcGQGrr@WMo)Grpnc&RhZMsn)li-qbT)Scje,KCJZMsn)gA_-QZMsn)OoKq~>
+pAY*mJcGQGrr@WMo)Grpnc&RhZMsn)li-qbT)Scje,KCJZMsn)gA_-QZMsn)OoKq~>
+pAY*mJcGQG!<@Y$s762pJFWX>!4)V)!:0Xb!1s2j!7UrJ!4)V)!8@GQ!4)V)!0R;3~>
+pAY*mJcGQGrr@WMcN!kDkl1V_ir8uYZMsn)li-qbT)Scje,KCJZMsn)gA_-QZMsn)OoKq~>
+pAY*mJcGQGrr@WMcN!kDkl1V_ir8uYZMsn)li-qbT)Scje,KCJZMsn)gA_-QZMsn)OoKq~>
+pAY*mJcGQG!<@Y$s3CZDpuq_Xpu;;R!4)V)!:0Xb!1s2j!7UrJ!4)V)!8@GQ!4)V)!0R;3~>
+pAY*mJcGQGrr@WMdf91EkPkM^ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMdf91EkPkM^ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s3grEpuhYWpu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMf)P[Krr3$"rrD9_rW)!Y!!)TirrDWiqZ,:KrW)?c!!)rsrrDBbrrE&urrDNf
+rrD]kquHKkrrDrrrrDusrW(LK!!)iprrDBbrrE&urrDNfrrDHdrW(aR!!)rsrrDZjq#KRWrW!0&
+!!*'!!!)ZkrW&/^J,~>
+pAY*mJcGQGrr@WMf)P[Krr3$"rrD9_rW)!Y!!)TirrDWiqZ,:KrW)?c!!)rsrrDBbrrE&urrDNf
+rrD]kquHKkrrDrrrrDusrW(LK!!)iprrDBbrrE&urrDNfrrDHdrW(aR!!)rsrrDZjq#KRWrW!0&
+!!*'!!!)ZkrW&/^J,~>
+pAY*mJcGQG!<@Y$s475Kq#:9pq#C-Qs8MfRrr<&is8N)is8)fKrrN1NJF3@:!;uls!:0[b!<3#u
+!:Tsf!;-<h!;HNn!;lfr!;uiu!.]UMrr<&ps8N)bs8N)us8N)fs8N)drrN1NJDC/)!;uls!;$6d
+!9X=\!!`H'!<<'!!;-9m!.]T`s*t~>
+pAY*mJcGQGrr@ZNrrDZjrrD?arW)iq!W`6#oDegjp](3mj8T)Zo)J^ir;Zcsrr;uurr;uuk5YG]
+nc/RgmJd.dr;Zcsr;Zcsrr;uup](6nrr;uun,NCfo`+pks8W*!q#C?oqu?Zrr;Z`rec,ULq>^Hp
+r;Zcsrr;uup](6nrr;uun,NCfmJm.ch#@?Sr;Zcsr;Zcsrr;uur;ZcsjT#5[qZ$Qqo`+mjPQ-.~>
+pAY*mJcGQGrr@ZNrrDZjrrD?arW)iq!W`6#oDegjp](3mj8T)Zo)J^ir;Zcsrr;uurr;uuk5YG]
+nc/RgmJd.dr;Zcsr;Zcsrr;uup](6nrr;uun,NCfo`+pks8W*!q#C?oqu?Zrr;Z`rec,ULq>^Hp
+r;Zcsrr;uup](6nrr;uun,NCfmJm.ch#@?Sr;Zcsr;Zcsrr;uur;ZcsjT#5[qZ$Qqo`+mjPQ-.~>
+pAY*mJcGQG!<@Y%s8Vlcs8VlZs8MfjrrVuqq"+Ocq"OgfpuDAS!:p0i!;uls!<3#u!<3#u!9X=]
+!:g'j!.]Uerr<&ss8N)ss8N)us8N)ns8N)us8N)fs8N)ks8N*!s8N)os8N)rs8N)srrN1NJCXZ"
+!;ZZp!;uls!<3#u!;HNn!<3#u!:Tsf!:Bdf!.]UTrr<&ss8N)ss8N)us8N)ss8N)[s8N)qs8N)k
+rrN1NJ<U"`~>
+pAY*mJcGQGrr@]O!s&B$!;6?n!<3&Zs8N'"rrDZj!W`6#q#:HsrrE'!jSo2[o)J^irVufr!<;ut
+s8W*!rVultrr2rurr;rtrr;uu"TJH%s8W#to)J[hmJd.dr;ZcsrVufr!<;ut!ri6#rr3*$s8N'!
+rr;uurr;osrVufrrr;uurr2rurr;oss8W*!s8W*!!ri6#rr3*$s8N'!rr;lrr;Z`rec,ULq>^Hp
+rVufr!<;ut!ri6#rr3*$s8N'!rr;uurr;osrVufrrr;uurr2rurr;osq#C<nh#@?Sr;ZcsrVufr
+!<;utrVultrVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)fprW&/^J,~>
+pAY*mJcGQGrr@]O!s&B$!;6?n!<3&Zs8N'"rrDZj!W`6#q#:HsrrE'!jSo2[o)J^irVufr!<;ut
+s8W*!rVultrr2rurr;rtrr;uu"TJH%s8W#to)J[hmJd.dr;ZcsrVufr!<;ut!ri6#rr3*$s8N'!
+rr;uurr;osrVufrrr;uurr2rurr;oss8W*!s8W*!!ri6#rr3*$s8N'!rr;lrr;Z`rec,ULq>^Hp
+rVufr!<;ut!ri6#rr3*$s8N'!rr;uurr;osrVufrrr;uurr2rurr;osq#C<nh#@?Sr;ZcsrVufr
+!<;utrVultrVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)fprW&/^J,~>
+pAY*mJcGQG!<@Y&rr`&rs7l9e!r2fjj8]/S!WVrdrrVuqq"Xjlq#C-hpuMGT!:p0i!<)rr!!*&t
+!<<*!!<)rt!<2uu!<3#t!<3#u!!N<%!<<)t!:p-k!.]Uerr<&ss8N)ts8;ots8;p!rr<&urr`?%
+rr<&us8N)us8;rrs8;rss8N)urr<&us8;rts8N*!s8N'#rr<&urr`?%rr<&us82lprrN1NJCXZ"
+!;ZZp!<)rr!!*&t!!<0#!<3!$!<<'!!<3#u!<3#s!<)rr!<3#u!<2uu!<3#s!;QQq!.]UTrr<&s
+s8N)ts8;ots8;rrs8N)ts8N'#rrE)t!<)rr!<<)u!<<)s!!`H'!<<'!!<3#t!;c]s!.]T`s*t~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)*[!!*#u!!)Qh!!)fo"9AH%rrD-[!!)TirrDusrrE&urrE&u
+rrE#trrE&u#lt#*!!*$!!<<)u!!`H'!<<'!!:g*g!:Bdd!;uls!;uls!<3#u!<<*!!<3!$!<<'!
+!<3#u!<<*!!<<*!!<<*!!<<*!!<<*!!<<'!!<3#u!;uls!<<'%!<<'!!<3!,!<<'!!<<'!!<<'!
+!;ulr!7h)L!;ZZp!;uls!<3#u!<<*!!<3!$!<<'!!<3#u!<<*!!<<*!!<<*!!<<*!!<<*!!<<'!
+!<3#u!;6Bk!8RSS!;uls!;uls!<3#u!;uls!<)rs!;uls!<<*!!<)rt!!`H'!<<'!!<3#u!<<*!
+!<<*!!!<0#!;lfq!0dG5~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)*[!!*#u!!)Qh!!)fo"9AH%rrD-[!!)TirrDusrrE&urrE&u
+rrE#trrE&u#lt#*!!*$!!<<)u!!`H'!<<'!!:g*g!:Bdd!;uls!;uls!<3#u!<<*!!<3!$!<<'!
+!<3#u!<<*!!<<*!!<<*!!<<*!!<<*!!<<'!!<3#u!;uls!<<'%!<<'!!<3!,!<<'!!<<'!!<<'!
+!;ulr!7h)L!;ZZp!;uls!<3#u!<<*!!<3!$!<<'!!<3#u!<<*!!<<*!!<<*!!<<*!!<<*!!<<'!
+!<3#u!;6Bk!8RSS!;uls!;uls!<3#u!;uls!<)rs!;uls!<<*!!<)rt!!`H'!<<'!!<3#u!<<*!
+!<<*!!!<0#!;lfq!0dG5~>
+pAY*mJcGQG!<@Y'rrDimrrDidrrDiTrrDinrrDiarrDihrri,sq#C-Mrr<&is8N)ss8N)us8N)u
+s8N)ts8N)urs8]*rr<'!!!*'!rW!0&!!*'!!!)Qh!W[b$mJd.dr;Zcsr;Zcsrr;uus8W*!rr3*$
+s8N'!rr;uus8W*!s8W*!s8W*!s8W*!s8W*!s8N'!rr;uur;Zcss8N3%s8N'!rr3B,s8N'!s8N'!
+s8N'!r;QfuJ:Q2M!!)iprrDusrrE&urrE*!rrE&u"9AK%!!*#urrE*!rrE*!rrE*!rrE*!rrE*!
+rrE*!!!*#urrD`l!W[b$h#@?Sr;Zcsr;Zcsrr;uur;ZcsrVuisr;Zcss8W*!rVult#6+Z's8N'!
+rr;uus8W*!s8W*!!ri6#qu6]tJ:Nj`J,~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)-\!!*#u!!)Ng!!)ip"p"]'!<<'!jo5;\o)J^ir;Zcsrr;uu
+rr;lrs8W*!!WN0!s8N'/rr<'!rr<'!rr<'!rr<&hs8E#crr<&ss8N)ss8N)us8N)us8N'"rrE&u
+q>gQqrrE*!rrE*!rrE*!rrE*!rr<*"!<)rs!<)rr!<)rt!!3*"rr;uus8W*!s8W*!r;Z`rec,UL
+q>^Hpr;Zcsrr;uurr;uu!WN0!s7u`qs8N*!s8N*!s8N*!s8N*!s8N'"rrE#trW)ZlrW(aR!!)rs
+rrDusrrE&urrDusrrE#trrDrrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!rr<-#!!)orrW&/^
+J,~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)-\!!*#u!!)Ng!!)ip"p"]'!<<'!jo5;\o)J^ir;Zcsrr;uu
+rr;lrs8W*!!WN0!s8N'/rr<'!rr<'!rr<'!rr<&hs8E#crr<&ss8N)ss8N)us8N)us8N'"rrE&u
+q>gQqrrE*!rrE*!rrE*!rrE*!rr<*"!<)rs!<)rr!<)rt!!3*"rr;uus8W*!s8W*!r;Z`rec,UL
+q>^Hpr;Zcsrr;uurr;uu!WN0!s7u`qs8N*!s8N*!s8N*!s8N*!s8N'"rrE#trW)ZlrW(aR!!)rs
+rrDusrrE&urrDusrrE#trrDrrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!rr<-#!!)orrW&/^
+J,~>
+pAY*mJcGQG!<@Y'rrDimrrDidrrDiUrrDinrrDi`rrDiirs&8us7lWopuVMU!:p0i!;uls!<3#u
+!<3#r!<<*!!!3*"rr;uu%fZM/s8N'!s8N'!s8N'!nc&XjJ:R%e!!)rsrrDusrrE&urrE&urr<*"
+!<3#p!<<*!!<<*!!<<*!!<<*!!<<*!!!3*"rVuisrVufrrVult!WN0!s8N*!s8N*!s8N)srrN1N
+JCXZ"!;ZZp!;uls!<3#u!<3#u!!3*"rr;fps8W*!s8W*!s8W*!s8W*!s8W*!!WN/us8E#lrrN1N
+JDC/)!;uls!;uls!<3#u!;uls!<)rt!;lfr!<<*!!<)rt!!`H'!<<'!!<3#u!<<*!!<<*!!!<0#
+!;lct!.]T`s*t~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)3^rrE#t!!)Ng!!)ip"p"]'!<<'!jo5;\o)J^ir;Zcsrr;uu
+rr;uur;Zcs!WN0!s82lss8N*!s8N*!s8N)hs8E#crr<&ss8N)ss8N)us8N)us8N'"rrE&urrE&u
+rrE*!rrE*!rrE*!rrE*!rrE*!r;ccqrW)rtrrE*!!!*#urr<*"!<3#u!<<*!!<<*!!;ulr!7h)L
+!;ZZp!;uls!<3#u!<3#u!!3*"rr;uurr;uus8W*!s8W*!s8W*!s8W*!s8W#tr;Z`rp](3mh#@?S
+r;Zcsr;Zcsrr;uur;ZcsrVultrVufrs8W*!rVucqs8W*!rr;uus8W*!s8Vusqu?WqPQ-.~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)3^rrE#t!!)Ng!!)ip"p"]'!<<'!jo5;\o)J^ir;Zcsrr;uu
+rr;uur;Zcs!WN0!s82lss8N*!s8N*!s8N)hs8E#crr<&ss8N)ss8N)us8N)us8N'"rrE&urrE&u
+rrE*!rrE*!rrE*!rrE*!rrE*!r;ccqrW)rtrrE*!!!*#urr<*"!<3#u!<<*!!<<*!!;ulr!7h)L
+!;ZZp!;uls!<3#u!<3#u!!3*"rr;uurr;uus8W*!s8W*!s8W*!s8W*!s8W#tr;Z`rp](3mh#@?S
+r;Zcsr;Zcsrr;uur;ZcsrVultrVufrs8W*!rVucqs8W*!rr;uus8W*!s8Vusqu?WqPQ-.~>
+pAY*mJcGQG!<@Y'rrDimrrDidrrDiWs8VlmrrDi`rrDiirs&8us7lWopuVMU!:p0i!;uls!<3#u
+!<3#u!;uls!!3*"rr;lrs8W*!s8W*!s8W*!nc&XjJ:R%e!!)rsrrDusrrE&urrE&urr<*"!<3#u
+!<3#u!<<*!!<<*!!<<*!!<<*!!<<)t!;ulr!<3#u!<<'!!<3#u!!3*"rr;uus8W*!s8W*!r;Qfu
+J:Q2M!!)iprrDusrrE&urrE&urr<*"!<3#u!<3#u!<<*!!<<*!!<<*!!<<*!!<<)t!;ulr!;HKp
+!.]UTrr<&ss8N)ss8N)us8N)ss8N)ts8N)ts8;rts8N)ts82lss8N)us8N*!s8N*!s82lorrN1N
+J<U"`~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)6_!!)rs!!)Kf!!)ip"p"]'!<<'!jo5;\o)J^ir;Zcsrr;uu
+rr;uur;Zcs!WN0!s8N)ss8N*!s8N*!s8N)hs8E#crr<&ss8N)ss8N)us8N)us8N'"rrE&urrE&u
+rrE*!rrE*!rrE*!rrE*!rrE*!rr<-#!!)rsrW)uurrE*!rrE*!rr<*"!<3#u!<<*!!<<*!!;ulr
+!7h)L!;ZZp!;uls!<3#u!<3#u!!3*"rr;uurr;uus8W*!s8W*!s8W*!s8W*!s8W*!!ri6#r;Z`r
+q#C<nh#@?Sr;Zcsr;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultr;Zcsrr;uus8W*!s8W*!
+q#C<nPQ-.~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)6_!!)rs!!)Kf!!)ip"p"]'!<<'!jo5;\o)J^ir;Zcsrr;uu
+rr;uur;Zcs!WN0!s8N)ss8N*!s8N*!s8N)hs8E#crr<&ss8N)ss8N)us8N)us8N'"rrE&urrE&u
+rrE*!rrE*!rrE*!rrE*!rrE*!rr<-#!!)rsrW)uurrE*!rrE*!rr<*"!<3#u!<<*!!<<*!!;ulr
+!7h)L!;ZZp!;uls!<3#u!<3#u!!3*"rr;uurr;uus8W*!s8W*!s8W*!s8W*!s8W*!!ri6#r;Z`r
+q#C<nh#@?Sr;Zcsr;Zcsrr;uur;ZcsrVultrr;uu#6+Z's8N'!rVultr;Zcsrr;uus8W*!s8W*!
+q#C<nPQ-.~>
+pAY*mJcGQG!<@Y'rrDimrrDidrrDiXrrDilrrDi_rrDiirs&8us7lWopuVMU!:p0i!;uls!<3#u
+!<3#u!;uls!!3*"rr;uur;Zcss8W*!s8W*!nc&XjJ:R%e!!)rsrrDusrrE&urrE&urr<*"!<3#u
+!<3#u!<<*!!<<*!!<<*!!<<*!!<<*!!!<0#!;ulr!<<*!!<<*!!<<*!!!3*"rr;uus8W*!s8W*!
+r;QfuJ:Q2M!!)iprrDusrrE&urrE&urr<*"!<3#u!<3#u!<<*!!<<*!!<<*!!<<*!!<<*!!!<0#
+!;ulr!;QQq!.]UTrr<&ss8N)ss8N)us8N)ss8N)ts8N)us8N''rr<'!rr<&ts8N)ss8N)us8N*!
+s8N*!s8N)orrN1NJ<U"`~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)9`!!)rs!!)He!!)lq!!*#u!!*#u!!)0]!!)TirrDusrrE&u
+rrE&urrDrrrrE#trrDusrrE*!rrE*!rrDThrW)?c!!)rsrrDusrrE&urrE#trrE#trrE&urrE*!
+rrE*!rrE*!rrE*!rrE*!rrE*!rrDusrrE*!rrE*!rrE&urrE#trrE*!rr<'!rW)lrrW(LK!!)ip
+rrDusrrE&urrE#trrE#trrE&urrE*!rrE*!rrE*!rrE*!rrE*!rrE*!rrDusrrDiorW(aR!!)rs
+rrDusrrE&urrDusrrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!rrE*!rrDiorW&/^J,~>
+pAY*mJcGQGrr@`P!!)ut!!)Zk!!)9`!!)rs!!)He!!)lq!!*#u!!*#u!!)0]!!)TirrDusrrE&u
+rrE&urrDrrrrE#trrDusrrE*!rrE*!rrDThrW)?c!!)rsrrDusrrE&urrE#trrE#trrE&urrE*!
+rrE*!rrE*!rrE*!rrE*!rrE*!rrDusrrE*!rrE*!rrE&urrE#trrE*!rr<'!rW)lrrW(LK!!)ip
+rrDusrrE&urrE#trrE#trrE&urrE*!rrE*!rrE*!rrE*!rrE*!rrE*!rrDusrrDiorW(aR!!)rs
+rrDusrrE&urrDusrrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!rrE*!rrDiorW&/^J,~>
+pAY*mJcGQG!<@Y'rrDimrrDidrrDiYrrDilrrDi^rrDijrrDinrrDinrrDiVrr<&is8N)ss8N)u
+s8N)us8N)rs8N)ts8N)ss8N*!s8N*!s8N)hrrN1NJF3@:!;uls!;uls!<3#u!<)rt!<)rt!<3#u
+!<<*!!<<*!!<<*!!<<*!!<<*!!<<*!!;uls!<<*!!<<*!!<3#u!<)rt!<<*!!!*&u!;uiu!.]UM
+rr<&ps8N)ss8N)us8N)ts8N)ts8N)us8N*!s8N*!s8N*!s8N*!s8N*!s8N*!s8N)ss8N)orrN1N
+JDC/)!;uls!;uls!<3#u!;uls!<)rt!<3#u!!`H'!<<'!!<)rt!;uls!<3#u!<<*!!<<*!!;QQq
+!.]T`s*t~>
+pAY*mJcGQGrr@]O!s&B$!;$3j!:0[b!;lcr!:Kje!;c]q!<2uu!<2uu!9X:]!:p0e!<<)u!<<)u
+!!*&r!<<*!!;ulq!<<*!!<<*!!<3#t!;$6i!:Bdd!;ulo!<<)u!<<)u!<<*!!<)rt!<3#u!<3#s
+!<)rr!<3#u!<3#u!!*&t!<3#r!<)rt!<)rt!<3#u!!<0#!;ulr!7h)L!;ZZl!<<)u!<<)u!<<*!
+!<)rt!<3#u!<3#s!<)rr!<3#u!<3#u!!*&t!;HNm!8RSS!;ulo!<<)u!<<)u!<3#u!<)rt!<)rq
+!<<)t!<<)t!<<*!!<3#u!<<*!!<3#s!;lfq!0dG5~>
+pAY*mJcGQGrr@]O!s&B$!;$3j!:0[b!;lcr!:Kje!;c]q!<2uu!<2uu!9X:]!:p0e!<<)u!<<)u
+!!*&r!<<*!!;ulq!<<*!!<<*!!<3#t!;$6i!:Bdd!;ulo!<<)u!<<)u!<<*!!<)rt!<3#u!<3#s
+!<)rr!<3#u!<3#u!!*&t!<3#r!<)rt!<)rt!<3#u!!<0#!;ulr!7h)L!;ZZl!<<)u!<<)u!<<*!
+!<)rt!<3#u!<3#s!<)rr!<3#u!<3#u!!*&t!;HNm!8RSS!;ulo!<<)u!<<)u!<3#u!<)rt!<)rq
+!<<)t!<<)t!<<*!!<3#u!<<*!!<3#s!;lfq!0dG5~>
+pAY*mJcGQG!<@Y&rr`&rs7l3c!;Pm[s7lKk!;Q!^!;QEj!;QQn!;QQn!;P^V!!)TiqZ-ZrrW)uu
+rVuruqZ-ZrrrDusr;cltrrE*!rrE&urW)Qi!W[b$mJd.dr;ZWos8W&us8W&us8W*!rVultrr;uu
+rr;osrVufrrr;uurr;uu!<;utrr;lrrVultrVultrr;uu!ri6#r;QfuJ:Q2M!!)ipqZ-ZrrW)uu
+rW)uurrE#trrE&urrE&ur;cfrr;cisrrE&urr<'!r;cTl!W[b$h#@?Sr;ZWos8W&us8W&urr;uu
+rVultrVucqs8W#ts8W#ts8W*!rr;uus8W*!rr;osqu6]tJ:Nj`J,~>
+pAY*mJcGQGrr@ZNrrE#t!!*#u!!)utquH0b!!)lq!!)KfquH]q!!)ut!!)ut!!)3^!!'>)rW)?c
+!!'A*rrDKerW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@ZNrrE#t!!*#u!!)utquH0b!!)lq!!)KfquH]q!!)ut!!)ut!!)3^!!'>)rW)?c
+!!'A*rrDKerW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y%s8VlmrrDinrrDims8;Z[rrDijrrDi_s8;ZjrrDimrrDimrrDiWrr<&)rrN1N
+JF3@:!42_*!:Kjg!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrr@WMh#@?Sh>[HTrVlitrVlitkPkM^ZN'n(mJd.d[/^.+mJm.cec,ULZN'n(h#@?S
+ZN'n(PQ-.~>
+pAY*mJcGQGrr@WMh#@?Sh>[HTrVlitrVlitkPkM^ZN'n(mJd.d[/^.+mJm.cec,ULZN'n(h#@?S
+ZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s4mVSptbrMq#13mq#13mpuhYW!4)V+!.]Uerr<&+s8N)drrN1NJCXZ"!4)V+
+!.]UTrr<&)rrN1NJ<U"`~>
+pAY*mJcGQGrr@WMhZ*TUfDbgNir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMhZ*TUfDbgNir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s5*eUpt,NGpu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMhu<ZVec,ULir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMhu<ZVec,ULir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s53hVpsoBEpu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMi;WcWeGfLKir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMi;WcWeGfLKir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s5<nWpsf<Dpu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMirB#Ye,KCJir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMirB#Ye,KCJir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s5O(Yps]6Cpu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMj8T)ZdJj1Hir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMj8T)ZdJj1Hir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s5X+ZpsK*Apu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMjSo2[d/O(Gir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMjSo2[d/O(Gir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s5a1[psB$@pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMk5YG]ci3tFir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMk5YG]ci3tFir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s5s@]ps8s?pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMkPkM^c2RbDir?.]mJiUTec2cPh#FMWPQ-.~>
+pAY*mJcGQGrr@WMkPkM^c2RbDir?.]mJiUTec2cPh#FMWPQ-.~>
+pAY*mJcGQG!<@Y$s6'C^ps&g=pu;=X!<7T:s-s)hJCX\(!<7T)s0)M'J<U"`~>
+pAY*mJcGQGrr@WMkl1V_bl7YCir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMkl1V_bl7YCir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s60I_prra<pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMlMpkabPqPBir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMlMpkabPqPBir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s6BXapri[;pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMli-qbao;>@ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMli-qbao;>@ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s6K[bprWO9pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMm/I%caSu5?ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMm/I%caSu5?ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s6TacprNI8pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMmf3:ea8Z,>ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMmf3:ea8Z,>ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s6fpeprEC7pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMn,E@f`W#o<ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMn,E@f`W#o<ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s6osfpr375pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMnG`Ig`;]f;ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMnG`Ig`;]f;ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s7$$gpr*14pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMo)J^i_uB]:ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMo)J^i_uB]:ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s763ipr!+3pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMoD\dj_>aK8ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMoD\dj_>aK8ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s7?6jpqct1pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMo`"mk_#FB7ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMo`"mk_#FB7ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s7H<kpqZn0pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMpAb-m^]+96ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMpAb-m^]+96ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s7ZKmpqQh/pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMp\t3n^&J'4ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMp\t3n^&J'4ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s7cNnpq?\-pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMq#:<o]`.s3ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMq#:<o]`.s3ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s7lTopq6V,pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMqZ$Qq]Dhj2ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMqZ$Qq]Dhj2ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s8)cqpq-P+pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMqu6Wr\c2X0ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMqu6Wr\c2X0ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s82frpppD)pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMr;Q`s\GlO/ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMr;Q`s\GlO/ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s8;lsppg>(pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMrr;uu\,QF.ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMrr;uu\,QF.ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s8N&upp^8'pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WMs8N'![Jp4,ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrr@WMs8N'![Jp4,ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Y$s8W*!ppL,%pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrr@WM!WN/,rr<&Yrr<&)s8E#crr<%js8E#Krr<&)s8E#Rrr<&)s8E"^s*t~>
+pAY*mJcGQGrr@WM!WN/,rr<&Yrr<&)s8E#crr<%js8E#Krr<&)s8E#Rrr<&)s8E"^s*t~>
+pAY*mJcGQG!<@Y$rrN/p[/U.$ir8uYZMst+J:R%e!!&Vj!W[b$ec,ULZMst+J:QGT!!'>)!W[b$
+PQ-.~>
+pAY*mJcGQGrr@ZNrrBD*!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@ZNrrBD*!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y%s8Vl#rrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrr@]O!!';(!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@]O!!';(!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y&rrDi!rrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrr@`P!!'8'!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@`P!!'8'!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y'rrDhurrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrr@fRrrB8&!!)$YXoRkhRK1n<XoR8WXoO[cJ,~>
+pAY*mJcGQGrr@fRrrB8&!!)$YXoRkhRK1n<XoR8WXoO[cJ,~>
+pAY*mJcGQG!<@Y)s8VktrrDiRs0)M'JF3B,!<7T"s0)M'JDC1/!<7S5s*t~>
+pAY*mJcGQGrr@iS!!'/$!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@iS!!'/$!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y*rrDhrrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrr@lT!!',#!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@lT!!',#!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y+rrDhqrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrr@rVrrB,"!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@rVrrB,"!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y-s8VkprrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrr@uW!!'"u!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrr@uW!!'"u!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Y.rrDhnrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`
+s*t~>
+pAY*mJcGQGrrCFGJH5QIl2L_`ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFGJH5QIl2L_`ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Yss+(1I!9sL`pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1N
+J<U"`~>
+pAY*mJcGQGrrCFG!!%TMrVlitl2L_`ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVlitl2L_`ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Drt!9sL`pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)
+rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!%TMrVlitl2L_`ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVlitl2L_`ir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Drt!9sL`pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)
+rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)
+!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCFG!!(dRrrDEcq#J;3rW)9a!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)
+rW&/^J,~>
+pAY*mJcGQGrrCFG!!(dRrrDEcq#J;3rW)9a!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)
+rW&/^J,~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)cs7lZ3rrN1NJF!48pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+
+!.]UTrr<&)rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrD`lrrBh6rW)9a!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)
+rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrD`lrrBh6rW)9a!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)
+rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ss8N)us8N)ls8N)6rrN1NJF!48pu;;R!4)V+!.]Uerr<%jrrN1N
+JCXZ"!4)V+!.]UTrr<&)rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!(dRrrE#tr;Zitr;Zp!!!*#u!!)utrrE#trr<-#!<;utrVufrs8W&ug&M$O
+li-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!(dRrrE#tr;Zitr;Zp!!!*#u!!)utrrE#trr<-#!<;utrVufrs8W&ug&M$O
+li-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ts8;ots8;p!rr<&urr<&ts8N)ts8N'#rrE)t!<)rr!<<)u!87AR
+!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE*!rrE&u!!)utrrE#trW)lrrrE*!rrE#trr<-#!!(aQ
+rW)9a!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE*!rrE&u!!)utrrE#trW)lrrrE*!rrE#trr<-#!!(aQ
+rW)9a!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ss8N)us8N*!s8N)urr<&ts8N)ts8E#rs8N*!s8N)ts8N'#rr<&Q
+rrN1NJF!48pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE&urr<*"!;uls!<)rt!;lfr!<<*!!<)rt!!<0#!8@JP
+!:0Xb!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(!8RSS!4)Y(!0dG5~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE&urr<*"!;uls!<)rt!;lfr!<<*!!<)rt!!<0#!8@JP
+!:0Xb!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(!8RSS!4)Y(!0dG5~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ss8N)us8N)us8N'"rrDusrrE#trrDrrrrE*!rrE#trr<-#!!(aQ
+!W[b$li-t[ir8uYZMst+J:R%e!!&Vj!W[b$ec,ULZMst+J:QGT!!'>)!W[b$PQ-.~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE&urr<*"!;uls!<)rt!<)rr!<<*!!<)rq!8@JP!:0Xb
+!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(!8RSS!4)Y(!0dG5~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE&urr<*"!;uls!<)rt!<)rr!<<*!!<)rq!8@JP!:0Xb
+!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(!8RSS!4)Y(!0dG5~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ss8N)us8N)us8N'"rrDusrrE#trrE#tr;cltrrE#tquGIN!W[b$
+li-t[ir8uYZMst+J:R%e!!&Vj!W[b$ec,ULZMst+J:QGT!!'>)!W[b$PQ-.~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE&urr<*"!;uls!<)rt!<3#u!!`H'!<<'!!<)rt!8%8M
+!:0Xb!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(!8RSS!4)Y(!0dG5~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE&urr<*"!;uls!<)rt!<3#u!!`H'!<<'!!<)rt!8%8M
+!:0Xb!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(!8RSS!4)Y(!0dG5~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ss8N)us8N)us8N'"rrDusrrE#trrE&urr<9'!!*'!!!)utrrC[N
+!W[b$li-t[ir8uYZMst+J:R%e!!&Vj!W[b$ec,ULZMst+J:QGT!!'>)!W[b$PQ-.~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE#trrDrrrrE#trrE&urr<9'!!*'!!!)utrrC[NrW)9a
+!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrrCFG!!(dRrrDusrrE&urrE#trrDrrrrE#trrE&urr<9'!!*'!!!)utrrC[NrW)9a
+!!)$Y!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Ysrr<&Rs8N)ss8N)us8N)ts8N)rs8N)ts8N)us8N''rr<'!rr<&ts8N)NrrN1N
+JF!48pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!(dRqZ-ZrrW)uurW)uurrDrrrrE#trrE#tquHcsr;cltr;bROrW)9a!!)$Y
+!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQGrrCFG!!(dRqZ-ZrrW)uurW)uurrDrrrrE#trrE#tquHcsr;cltr;bROrW)9a!!)$Y
+!!'>)rW)?c!!&VjrW(LK!!'>)rW(aR!!'>)rW&/^J,~>
+pAY*mJcGQG!<@Ysrr<&Rs8)frs8E#us8E#us8N)rs8N)ts8N)ts82lss8;rts8;rOrrN1NJF!48
+pu;;R!4)V+!.]Uerr<%jrrN1NJCXZ"!4)V+!.]UTrr<&)rrN1NJ<U"`~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)
+!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)
+!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDHdrrDZjrrDcm!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?S
+ZN'n(PQ-.~>
+pAY*mJcGQGrrDHdrrDZjrrDcm!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?S
+ZN'n(PQ-.~>
+pAY*mJcGQG!<@Z;s8Vlcs8Vlfrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)
+rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDKe!s&B$!;6?n!<3&mrr<%Ms8Dus!:0Xb!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(
+!8RSS!4)Y(!0dG5~>
+pAY*mJcGQGrrDKe!s&B$!;6?n!<3&mrr<%Ms8Dus!:0Xb!94"Y!4)Y(!:Bdd!1s5i!7h)L!4)Y(
+!8RSS!4)Y(!0dG5~>
+pAY*mJcGQG!<@Z<rr`&rs7l9e!r2fjpAY*mJcG]K!W[b$li-t[ir8uYZMst+J:R%e!!&Vj!W[b$
+ec,ULZMst+J:QGT!!'>)!W[b$PQ-.~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Z=rrDimrrDidrrDifrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UM
+rr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Z=rrDimrrDidrrDifrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UM
+rr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Z=rrDimrrDidrrDifrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UM
+rr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Z=rrDimrrDidrrDifrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UM
+rr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrDNf!!)ut!!)Zk!!)`m!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(
+h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Z=rrDimrrDidrrDifrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UM
+rr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrDKe!s&B$!;$3j!;?GD!;QW\rr<&Yrr<&)s8E#crr<%js8E#Krr<&)s8E#Rrr<&)
+s8E"^s*t~>
+pAY*mJcGQGrrDKe!s&B$!;$3j!;?GD!;QW\rr<&Yrr<&)s8E#crr<%js8E#Krr<&)s8E#Rrr<&)
+s8E"^s*t~>
+pAY*mJcGQG!<@Z<rr`&rs7l3c!;Q9fJH5QIs+'G8!;PRR!!'>)!W[b$mJd.dT)SilJ:Q2M!!'>)
+!W[b$h#@?SZMst+J:Nj`J,~>
+pAY*mJcGQGrrDHdrrE#t!!*#u!!)utquHNl!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,UL
+ZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrDHdrrE#t!!*#u!!)utquHNl!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,UL
+ZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Z;s8VlmrrDinrrDims8;Zerr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l
+!.]UMrr<&)rrN1NJDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)
+!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(PQ-.~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1NJDC/)
+!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCjSrrDfn!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(
+PQ-.~>
+pAY*mJcGQGrrCjSrrDfn!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(
+PQ-.~>
+pAY*mJcGQG!<@Z*s8Vlgrr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1N
+JDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrCdQrrDlp!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(
+PQ-.~>
+pAY*mJcGQGrrCdQrrDlp!!%TMrVuisli-qbir8uYZN'n(mJd.dT)\ciec,ULZN'n(h#@?SZN'n(
+PQ-.~>
+pAY*mJcGQG!<@Z(s8Vlirr<%Ms8Ds!!.]UcrrDiRrr<&)rrN1NJF3@:!1s2l!.]UMrr<&)rrN1N
+JDC/)!4)V+!.]T`s*t~>
+pAY*mJcGQGrrC^OrW)lr!!%TMrVuisli-qbir?.]mJiUTec2cPh#FMWPQ-.~>
+pAY*mJcGQGrrC^OrW)lr!!%TMrVuisli-qbir?.]mJiUTec2cPh#FMWPQ-.~>
+pAY*mJcGQG!<@Z&s8Mfkrr<%Ms8Ds!!.]UcrrDiRs0)M'JF3B,!<7T"s0)M'JDC1/!<7S5s*t~>
+pAY*mJcGQGrrCULrrE&u!!%TMrVuisli-qbhuBq]lMmCTdf6QPg&J;WPQ-.~>
+pAY*mJcGQGrrCULrrE&u!!%TMrVuisli-qbhuBq]lMmCTdf6QPg&J;WPQ-.~>
+pAY*mJcGQG!<@Z#s8Vlnrr<%Ms8Ds!!.]UcrrDiOs07+>s.+\gs07+-s07*<s*t~>
+pAY*mJcGQGrrCOJrr<*"!.k1Ks8E#arr<&Vs02Rhs.'/<s02RWs02Qfs*t~>
+pAY*mJcGQGrrCOJrr<*"!.k1Ks8E#arr<&Vs02Rhs.'/<s02RWs02Qfs*t~>
+pAY*mJcGQG!<@Z!s8Viprr@WMrVlp!J:Qtc!;PIOZ%2->SUf/gZ%1O-Z%/&<J,~>
+pAY*mJcGQGblE=prVuisli-qb\c2X0S,WHgJcG6>rrA/\q>c*HlMlA~>
+pAY*mJcGQGblE=prVuisli-qb\c2X0S,WHgJcG6>rrA/\q>c*HlMlA~>
+pAY*mJcGQG!<@Ysp](;Fs8Ds!!.]UcrrDi)rrDh`rrDhFs7$'gplPOPpjrJ1s*t~>
+pAY*mJcGQGrrCOJrr<*"!.k1Ks8E#arr<&0s8N(hrr<%Ms763g!13`^!<)rt!.k17s*t~>
+pAY*mJcGQGrrCOJrr<*"!.k1Ks8E#arr<&0s8N(hrr<%Ms763g!13`^!<)rt!.k17s*t~>
+pAY*mJcGQG!<@Z!s8Viprr@WMrVlp!J:Qtc!;O,)s7i,a!;M-Fo)J[`QiHpWrVuomJcG!7J,~>
+pAY*mJcGQGrrCULrrE&u!!%TMrVuisli-qb\c;U.TE"ljJcGECrr<-#!!&#YrW%NLkl6/~>
+pAY*mJcGQGrrCULrrE&u!!%TMrVuisli-qb\c;U.TE"ljJcGECrr<-#!!&#YrW%NLkl6/~>
+pAY*mJcGQG!<@Z#s8Vlnrr<%Ms8Ds!!.]UcrrDi)s8D_bs8MeEs7QElp]CKjpl5=QpjrJ/s*t~>
+pAY*mJcGQGrrC^OrW)lr!!((>!!)<a!!(CGrW)9a!!(%=rrDcm"9AH%rrB/#rrDfnrW&&[rrDBb
+rW)uu!W`6#\GuR/gAh0Qs8N'!JcFs6J,~>
+pAY*mJcGQGrrC^OrW)lr!!((>!!)<a!!(CGrW)9a!!(%=rrDcm"9AH%rrB/#rrDfnrW&&[rrDBb
+rW)uu!W`6#\GuR/gAh0Qs8N'!JcFs6J,~>
+pAY*mJcGQG!<@Z&s8Mfkrr<&>rr<&arr<&GrrN1NJF!48pr<@6q"F^jq#C-hpoOMqq"OgfplPOU
+q!7tZq#C?qq#C-!s8VlJs8VlorrDhFs60K5~>
+pAY*mJcGQGrrCdQrrDlp!!((>!!)BcquG1FrW)9a!!((>!W`6#pAY9rrrE*!!3Z>'!<3&orr`?%
+!<3%^rrN3#!:Bgd!<)p!!<3&/rrN3#!8RVS!<2uu!.k15s*t~>
+pAY*mJcGQGrrCdQrrDlp!!((>!!)BcquG1FrW)9a!!((>!W`6#pAY9rrrE*!!3Z>'!<3&orr`?%
+!<3%^rrN3#!:Bgd!<)p!!<3&/rrN3#!8RVS!<2uu!.k15s*t~>
+pAY*mJcGQG!<@Z(s8Vlirr<&>rr<&cs82lFrrN1NJF!48prEC9q#C-_rrr2tq#CBhY5\Rus7lBh
+"Si#ls7hcW!r2fjmJm4]rVlros7j,(!r2fjh#IELrr2unJcFp5J,~>
+pAY*mJcGQGrrCjSrrDfn!!)fo!!)or!s&?$!<)rs!<3!'!<3$!s8N'!rVuisrr2rurVuiss8N0$
+rr<&ts8E#trrW9$!!)rsrrCFGrW)9a!!("<!!)`m"p"]'!<<'!XoAA$q#:HsrrE'!OT,:\n,NCf
+r;Qj!s8N)-rr<&Trr<&trr<%Ms5s?3~>
+pAY*mJcGQGrrCjSrrDfn!!)fo!!)or!s&?$!<)rs!<3!'!<3$!s8N'!rVuisrr2rurVuiss8N0$
+rr<&ts8E#trrW9$!!)rsrrCFGrW)9a!!("<!!)`m"p"]'!<<'!XoAA$q#:HsrrE'!OT,:\n,NCf
+r;Qj!s8N)-rr<&Trr<&trr<%Ms5s?3~>
+pAY*mJcGQG!<@Z*s8Vlgrr<&orr<&rrrW9$!!)utrW)rt#6=c(!<<'!!<)rs!<2uu!<)rs!<<'$
+!<3$!rVuisrr3'#rr<&ss8N)GrrN1NJF!48pr375q"F^lq#CBhs8VkrrrDihrri,sq#C,NrrDi_
+s8Vllrr`&rs7j&&!;PCM!;QNm!;M-Fk5Tr~>
+pAY*mJcGQGrrCFG!!)fo!!)orrrE*!!s&B$!<3!.!<<'!!<<'!!<<'!s8N)urr<&rrr<&ss8N*!
+rrW9$rrE&u"9AK%!!)lq!W`6#dJs1Gli-qb`W#o<pAY3ps8N)us8N)&rr<&prrrK'rrE*!!0R9]
+!9sLc!<<'![Jp4,huE]VrVlitJcFj3J,~>
+pAY*mJcGQGrrCFG!!)fo!!)orrrE*!!s&B$!<3!.!<<'!!<<'!!<<'!s8N)urr<&rrr<&ss8N*!
+rrW9$rrE&u"9AK%!!)lq!W`6#dJs1Gli-qb`W#o<pAY3ps8N)us8N)&rr<&prrrK'rrE*!!0R9]
+!9sLc!<<'![Jp4,huE]VrVlitJcFj3J,~>
+pAY*mJcGQG!<@Ysrr<&orr<&rs8N*!rrW9$rrE&u%KQP/!!*'!!!*'!!<<'!rr2ruqu6Wrr;Zcs
+s8N0$s8N)urr`?%rr<&qrrN3#!7CfJ!.]UcrrDi5rrDifrr`&rs7lTns7iet!;QBi#5J5uq#CBh
+OoGFVl2Lk\s8Vl%rrDiOs8VlmrrDhFs5j92~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!!)or!s&B$!<2uu!<3!#!<<'!rr2ruqu6Wrr;Q`srr2ru
+qu6`us8N)=s8E#arr<&<rr<&lrrW9$rrE#t!!'8'!!)ip"p"]'!<<'!OoGC]lMgharr2ru[Jp4,
+iW&oXr;Q`sJcFg2J,~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!!)or!s&B$!<2uu!<3!#!<<'!rr2ruqu6Wrr;Q`srr2ru
+qu6`us8N)=s8E#arr<&<rr<&lrrW9$rrE#t!!'8'!!)ip"p"]'!<<'!OoGC]lMgharr2ru[Jp4,
+iW&oXr;Q`sJcFg2J,~>
+pAY*mJcGQG!<@Ysrr<&orr<&rrr<&urr<&rrrW9$rrE&u!!*#u!s&B$!<2uu!;lcr!;uis!<2uu
+!;lcu!<<'!`r?)?J:Qtc!;OP5!;Q6e"8Morq#13mposbuq"apoq#CBhs8VkVrrDiZrrDinrrDi%
+rrDiQs8VllrrDhFs5a31~>
+pAY*mJcGQGrrCFG!!)orq>gNp!!*#u!!*#ur;clt!!*#u!!*#u!W`9#quHWo!!)rs!!*#u!!*#u
+r;clt!!(%=rW)9a!!("<!!)]l!s&B$!;uis!3uP(!;ZX!!<<'!s8N(]rr<&brr<&trr<&,rr<&Z
+s8N)qrr<%Ms5a31~>
+pAY*mJcGQGrrCFG!!)orq>gNp!!*#u!!*#ur;clt!!*#u!!*#u!W`9#quHWo!!)rs!!*#u!!*#u
+r;clt!!(%=rW)9a!!("<!!)]l!s&B$!;uis!3uP(!;ZX!!<<'!s8N(]rr<&brr<&trr<&,rr<&Z
+s8N)qrr<%Ms5a31~>
+pAY*mJcGQG!<@Ysrr<&rs7u`prr<&urr<&us8;rtrr<&urr<&urrN3#s82lorr<&srr<&urr<&u
+s8;rtrr<&=rrN1NJF!48pr375q"=Xhq#CBhr;QclZ2Xh!q>UZos8Vlos7h`V!;Pm[!;QNm!;Nu%
+!;PUSs7lHj!;M-FjSs`~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urrW9$
+rrE&u!s&B$!65'<!:0Xb!6+s<!;6?l!<2uu!3H2#!;c]q!<2uu!<2uu!0[?^!:9^c!<)ot!4;b+
+!9O7\!;ZWp!.k11s*t~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urrW9$
+rrE&u!s&B$!65'<!:0Xb!6+s<!;6?l!<2uu!3H2#!;c]q!<2uu!<2uu!0[?^!:9^c!<)ot!4;b+
+!9O7\!;ZWp!.k11s*t~>
+pAY*mJcGQG!<@Ysrr<&orr<&rrr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!p\t3nr;Q`srr3'#
+s8N)urrW9$rrC(=!W[b$li-t[`W#r5p&>$err2unXT&:qqYpQjrr2unrr2unP5bOWm/I(\rVllm
+[/U.$jo>AUq>UHiJcFd1J,~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urrW9$
+rrE&u!s&B$!65'<!:0Xb!6+s<!;6?l!<)ot!3Q8$!;c]q!<2uu!<2uu!0[?^!:Bdd!;uis!4;b+
+!9X:]!;QQo!.k10s*t~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urrW9$
+rrE&u!s&B$!65'<!:0Xb!6+s<!;6?l!<)ot!3Q8$!;c]q!<2uu!<2uu!0[?^!:Bdd!;uis!4;b+
+!9X:]!;QQo!.k10s*t~>
+pAY*mJcGQG!<@Ysrr<&orr<&rrr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!p\t3nr;Q`srr3'#
+s8N)urrW9$rrC(=!W[b$li-t[`W#r5p&>$erVllmXoACrqYpQjrr2unrr2unP5bOWmJd1]r;Qcl
+[/U.$k5PGVq#:?hJcFa0J,~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!!*#uqu?ct!<2uu!<2uu!<3#s!<<'!!<)rs!<<'!!<2uu
+!<3#r!!3*"`rH#<li-qba8c&;p\t3nrVlitYQ+M#rVlitrVlitrVlitQ2ga^nG`Igr;Q`s[K$.)
+lMpkaJcF@%J,~>
+pAY*mJcGQGrrCFG!!)fo!!)or!!*#u!!*#uqu?ct!<2uu!<2uu!<3#s!<<'!!<)rs!<<'!!<2uu
+!<3#r!!3*"`rH#<li-qba8c&;p\t3nrVlitYQ+M#rVlitrVlitrVlitQ2ga^nG`Igr;Q`s[K$.)
+lMpkaJcF@%J,~>
+pAY*mJcGQG!<@Ysrr<&orr<&rrr<&urr<&us82itrrE&u!!*#u!!*#ur;clt!!)utrW)uu!!*#u
+!!*#uqu?ct!65$?!.]UcrrDi7s8;ZdrrDimrrDhts8;ZjrrDimrrDimrrDhZs8;Z]rrDilrrDi%
+s8;ZWs8VkFs4@:$~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qb\GlO/r;Q`sVuH_srVlitrVlitJc>cN!;lcr!1X#g!.k1#
+s*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qb\GlO/r;Q`sVuH_srVlitrVlitJc>cN!;lcr!1X#g!.k1#
+s*t~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDi(rrDilrrDhlrrDimrrDimrrDhFrrN/pqu6ZkS,`N`
+JcF:#J,~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qb\GlO/r;Q`sUAk2nJcGZJ!!&;arr@WMe,Op~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qb\GlO/r;Q`sUAk2nJcGZJ!!&;arr@WMe,Op~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDi(rrDilrrDhgrrDhFs8;lspm(mZpjrIos*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbZ2Xe(U]1;oJcG]K!!&>brr@WMdJn^~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbZ2Xe(U]1;oJcG]K!!&>brr@WMdJn^~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDi!rrDhhrrDhFs8Drtpm1s[pjrIms*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbZ2Xe(U]1;oJcG`L!!&>b!!%TMci8L~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbZ2Xe(U]1;oJcG`L!!&>b!!%TMci8L~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDi!rrDhhrrDhFs8N#upm1p[pjrIks*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbYl=\'V#LDpJcGcM!!&Acrr@WMcMrC~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbYl=\'V#LDpJcGcM!!&Acrr@WMcMrC~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDhurrDhirrDhFs8W*!pm;$\pjrIjs*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbYl=\'V#LDpJc>cN!1<fd!.k0os*t~>
+pAY*mJcGQGrrCFG!!%TMrVuisli-qbYl=\'V#LDpJc>cN!1<fd!.k0os*t~>
+pAY*mJcGQG!<@Ysrr<%Ms8Ds!!.]UcrrDhurrDhirrDhFrrN/pR/d3]JcEsoJ,~>
+pAY*mJcGQGrrCFG!!)3^!!)6_!!)?b!!)Ng!s&B$!9a@^!;ZZo!:0Xb!3cD&!2]\q!.k.M!1Ele
+!.k0ms*t~>
+pAY*mJcGQGrrCFG!!)3^!!)6_!!)?b!!)Ng!s&B$!9a@^!;ZZo!:0Xb!3cD&!2]\q!.k.M!1Ele
+!.k0ms*t~>
+pAY*mJcGQG!<@Ysrr<&^rr<&_rr<&brr<&grrW9$rrD6^!!)ip!W[b$li-t[YQ"UtV>gPjJc>`F
+RK*<^JcEmmJ,~>
+pAY*mJcGQGrrCFG!!(:D!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquHWorW)9a!!'5&
+!!&kq!!%WN!!&Jfrr@WMaT$b~>
+pAY*mJcGQGrrCFG!!(:D!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquHWorW)9a!!'5&
+!!&kq!!%WN!!&Jfrr@WMaT$b~>
+pAY*mJcGQG!<@Ysrr<&Drr<&srr<&urr<&lrr<&trr<&urr<&mrr<&jrr<&os82lorrN1NJF!48
+poj\tpndujpk&MGpmV6_pjrIds*t~>
+pAY*mJcGQGrrCFG!!)Zk!<E0!!<3!'!<3$!rrE'!r;Q`sqZ$Nprr2rurr2rurVuis!<<#u!WN/t
+rs&Q(rrE'!s8W&u!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDlprW)9a!!'2%
+!!&nr!!%ZO!!&Mgrr@WM`rCP~>
+pAY*mJcGQGrrCFG!!)Zk!<E0!!<3!'!<3$!rrE'!r;Q`sqZ$Nprr2rurr2rurVuis!<<#u!WN/t
+rs&Q(rrE'!s8W&u!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDlprW)9a!!'2%
+!!&nr!!%ZO!!&Mgrr@WM`rCP~>
+pAY*mJcGQG!<@Ysrr<&krrE-"rW)rt#6=c(!<3'!!;uis!;c`p!<2uu!<2uu!<)rs!!*&u!!3*"
+r;R!%s8N*!!<<)u!!*&u!<<'*!<3$!rrE*!!<<#urr2rurr3!!s8E#ts8E#ts8N)prrN1NJF!48
+poaVspnn&kpk/SHpm_<`pjrIbs*t~>
+pAY*mJcGQGrrCFG!!)ZkrrE&u"9AK%!!*#u!s&B$!<2uu!;c]q!<2uu!;lcr!;uis!<2uu!<2uu
+!<2uu!<3!"!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoq
+rW)9a!!'/$!!&qs!!%]P!!&Mg!!%TM`;b>~>
+pAY*mJcGQGrrCFG!!)ZkrrE&u"9AK%!!*#u!s&B$!<2uu!;c]q!<2uu!;lcr!;uis!<2uu!<2uu
+!<2uu!<3!"!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoq
+rW)9a!!'/$!!&qs!!%]P!!&Mg!!%TM`;b>~>
+pAY*mJcGQG!<@Ysrr<&ks8N)urr`?%rr<&urrW9$rrE&u!!)lq!!*#u!!)or!!)rs!!*#u!!*#u
+!!*#u!!*#u!W`6#rr2rurr2rurr;uurr3*$s8N'!rr3'#s8N)urrW9$rrE&u!!*#u"T\T&!<3&q
+rrN1NJF!48poXPrpo",lpk8YIpm_9`pjrI`s*t~>
+pAY*mJcGQGrrCFG!!)Zk!!)ut!s&B$!<)p"!<<'!rr2rupAY*mqu6Wrr;Q`srr2rurr2rurr3'#
+s8N)urrW9$rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&ls8E#arr<&$rr<%s
+rr<%Qrr<%hs8N(Ms24ke~>
+pAY*mJcGQGrrCFG!!)Zk!!)ut!s&B$!<)p"!<<'!rr2rupAY*mqu6Wrr;Q`srr2rurr2rurr3'#
+s8N)urrW9$rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&ls8E#arr<&$rr<%s
+rr<%Qrr<%hs8N(Ms24ke~>
+pAY*mJcGQG!<@Ysrr<&krr<&trrW9$rrE#t!s&B$!<2uu!;?Em!;lcr!;uis!<2uu!<2uu!<3!#
+!<<'!rr3'#s8N)urr<&urr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2rurr2rup&>'nJ:Qtc!;N\r
+!;NJl!;M9J!;N)as7h0F_uG5~>
+pAY*mJcGQGrrCFG!!)orquHcs!!)ut!s&B$!<)ot!<3!"!<3&os8;rprr<&srr<&urr<&trrN3#
+!<2uu!<3!#!<<'!rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<3#r!;6Bk!:0Xb!3H2#!3#nt
+!/CLR!1j/i!.k0ds*t~>
+pAY*mJcGQGrrCFG!!)orquHcs!!)ut!s&B$!<)ot!<3!"!<3&os8;rprr<&srr<&urr<&trrN3#
+!<2uu!<3!#!<<'!rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<3#r!;6Bk!:0Xb!3H2#!3#nt
+!/CLR!1j/i!.k0ds*t~>
+pAY*mJcGQG!<@Ysrr<&rs82lsrr<&trrW9$rrE#t!!*#u!W`6#q#C9mqu6Wrr;Q`srr2rurVlp!
+rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHEi!W[b$li-t[XT&:q
+W;ckmLAq8KScA`bJcERdJ,~>
+pAY*mJcGQGrrCFG!!)Zk!!)ut!s&B$!<)ot!<3!"!<3&prr<&urr<&rrr<&srr<&urr<&trr`?%
+!<<)q!!3*"rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<2uu!:g*g!:0Xb!3H2#!3#nt!/LRS
+!1s5j!.k0bs*t~>
+pAY*mJcGQGrrCFG!!)Zk!!)ut!s&B$!<)ot!<3!"!<3&prr<&urr<&rrr<&srr<&urr<&trr`?%
+!<<)q!!3*"rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<2uu!:g*g!:0Xb!3H2#!3#nt!/LRS
+!1s5j!.k0bs*t~>
+pAY*mJcGQG!<@Ysrr<&krr<&trrW9$rrE#t!!*#u!W`6#q>UEprr2ruqu6Wrr;Q`srr2rurVm!#
+rrE*!q>^Qr!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!)Qh!W[b$li-t[XT&:qW;ckm
+L]7ALT)\icJcELbJ,~>
+pAY*mJcGQGrrCFG!!)ZkrrE&u!s&B$!<)ot!<3!"!<3&prr<&urr<&rrr<&srr<&urr<&trriE&
+!<<'!r;QfurrE&u!!*#u!!)ut"9AK%!!*#u$3:,+!<<'!!<<'!rr2runc/Rgli-qbX8`/"WW)qu
+M#RGTTE"okJcEF`J,~>
+pAY*mJcGQGrrCFG!!)ZkrrE&u!s&B$!<)ot!<3!"!<3&prr<&urr<&rrr<&srr<&urr<&trriE&
+!<<'!r;QfurrE&u!!*#u!!)ut"9AK%!!*#u$3:,+!<<'!!<<'!rr2runc/Rgli-qbX8`/"WW)qu
+M#RGTTE"okJcEF`J,~>
+pAY*mJcGQG!<@Ysrr<&ks8N)urrW9$rrE#t!!*#u!W`6#q>UEprr2ruqu6Wrr;Q`srr2rurVm$$
+rrE*!!;uiu!<3&urr<&urr<&trr`?%rr<&ursAc+rrE*!!!*'!!<2uu!:g'j!.]UcrrDhprrDhn
+rrDhMrrDhds8VkFs1SG_~>
+pAY*mJcGQGrrCFG!!)Zk!<E0!!<2uu!<)ot!<)ot!;HNk!!3*"rr;lrs8N'!rr2rurVls"s8N)q
+rrN3#!<3!#!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;6Bk!:0Xb!3?,"!3,tu!/^^U!2'8k
+!.k0^s*t~>
+pAY*mJcGQGrrCFG!!)Zk!<E0!!<2uu!<)ot!<)ot!;HNk!!3*"rr;lrs8N'!rr2rurVls"s8N)q
+rrN3#!<3!#!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;6Bk!:0Xb!3?,"!3,tu!/^^U!2'8k
+!.k0^s*t~>
+pAY*mJcGQG!<@Ysrr<&krrE-"rW)rt!!)ut!!)ut!!)cnqu?ct!<3#r!<<'!!<2uu!<)p"!<<'!
+qYpTsrrE&u!s&B$!<)p#!<<'!s8E#ss8N'"rrE&u!!*#ur;cNj!W[b$li-t[X8`1pWW)tnM>mSN
+TDnodJcE@^J,~>
+pAY*mJcGQGrrCFG!!)Zk!!)Bcr;`YnrW)9a!!'&!!!'&!!!%oV!!&\lrr@WM])R9~>
+pAY*mJcGQGrrCFG!!)Zk!!)Bcr;`YnrW)9a!!'&!!!'&!!!%oV!!&\lrr@WM])R9~>
+pAY*mJcGQG!<@Ysrr<&krr<&cs8;qnrrN1NJF!48po=>opo=>opko(Opn7ZepjrIVs*t~>
+pA][Dp&NJ>!!)Zk!!%rWrW)9a!!'&!!!'&!!!%rW!!&_mrr@WM\Gq'~>
+pA][Dp&NJ>!!)Zk!!%rWrW)9a!!'&!!!'&!!!%rW!!&_mrr@WM\Gq'~>
+pA][DpAb2Dd/O(Go`"mkMuNhYJ:Qtc!;NSo!;NSo!;MKP!;N8fs7h0F\Gq'~>
+oDa@Aq#JeA!!%TMrVuisli-qbWW)quX8`/"N;ikXUAt5nJcE1YJ,~>
+oDa@Aq#JeA!!%TMrVuisli-qbWW)quX8`/"N;ikXUAt5nJcE1YJ,~>
+oDaAlq1-il!!%TMrVlp!J:Qtc!;NPn!;NVp!;MNQ!;N;gs7h0F[f:j~>
+oDa@Aq#JeA!!%TMrVuisli-qbW;chtXT&8#NW/tYU]:>oJcE+WJ,~>
+oDa@Aq#JeA!!%TMrVuisli-qbW;chtXT&8#NW/tYU]:>oJcE+WJ,~>
+oDaAlq1-il!!%TMrVlp!J:Qtc!;NMm!;NYq!;MQR!;N>hs7h0F[/YX~>
+PQ1X_WrE&!JcG]KrW)9a!!&tt!!',#!!&&Z!!&eo!!%TMZN#F~>
+PQ1X_WrE&!JcG]KrW)9a!!&tt!!',#!!&&Z!!&eo!!%TMZN#F~>
+PQ1[XWrE&!JcG]K!W[b$li-t[W;ckmXT&:qNrK+SU]1>hJcE%UJ,~>
+PQ1X_WrE&!JcG]KrW)9a!!&qs!!'/$!!&)[!!&hprr@WMZ2]=~>
+PQ1X_WrE&!JcG]KrW)9a!!&qs!!'/$!!&)[!!&hprr@WMZ2]=~>
+PQ1[XWrE&!JcG]K!W[b$li-t[VuHblXoACrO8f4TV#UJiJcE"TJ,~>
+PQ([arrB,"!!%TMrVuisli-qbVuH_sXoAA$OT,:\V>pPqJcDqRJ,~>
+PQ([arrB,"!!%TMrVuisli-qbVuH_sXoAA$OT,:\V>pPqJcDqRJ,~>
+PQ(^Zs7iYp!!%TMrVlp!J:Qtc!;NJl!;N\r!;MZU!;NDjs7h0FYQ'+~>
+YQ+V&oDegjp\t9prrB,"!!%TMrVuisli-qbVZ-VrY5\J%OoGC]VZ6YrJcDkPJ,~>
+YQ+V&oDegjp\t9prrB,"!!%TMrVuisli-qbVZ-VrY5\J%OoGC]VZ6YrJcDkPJ,~>
+YQ+XtoDejcp\t<is7iYp!!%TMrVlp!J:Qtc!;NGk!;N_s!;M]V!;NGks7h0FXoEn~>
+Yl=e*s8N)lrrN3#!;QTo!<<'!!3H2#!.k1Ks8E#arr<%rrr<&%rr<%^rr<%ss8N(Ms/Z0M~>
+Yl=e*s8N)lrrN3#!;QTo!<<'!!3H2#!.k1Ks8E#arr<%rrr<&%rr<%^rr<%ss8N(Ms/Z0M~>
+Yl=h#s8VlerrVuqq"Xmhq#C?opoOJq!.k1KrrN1NJF!48pnn&kpoaVsplbXWpo"/lpjrIGs*t~>
+Z2Xe(rVlito`"mkq#C?os8N'!XT&8#JcG]KrW)9a!!&kq!!'5&!!&5_!!&qs!!%TMWW.J~>
+Z2Xe(rVlito`"mkq#C?os8N'!XT&8#JcG]KrW)9a!!&kq!!'5&!!&5_!!&qs!!%TMWW.J~>
+Z2Xh!rVllmo`"pdq#CBhs8N)oXT&8#JcG]K!W[b$li-t[V>gPjYQ"UtPQ(XXVuHblJcD_LJ,~>
+Z2Xe(rVlito`"mkq>UKrrrE&u!!'/$JH5KGli-qbV>gMqYQ"S&PlC^`W;lktJcD\KJ,~>
+Z2Xe(rVlito`"mkq>UKrrrE&u!!'/$JH5KGli-qbV>gMqYQ"S&PlC^`W;lktJcD\KJ,~>
+Z2Xh!rVllmo`"pdq>UNks7lTn!;N\rJH5QIs+'G8!;NDj!;Nbt!;MfY!;NMms7h0FW;hA~>
+Z2Xe(rVlito`"mkq>UKrrrE&u!!'/$!!%TMrVuisli-qbV#LDpYl=\'Q2^gaWW2tuJcDVIJ,~>
+Z2Xe(rVlito`"mkq>UKrrrE&u!!'/$!!%TMrVuisli-qbV#LDpYl=\'Q2^gaWW2tuJcDVIJ,~>
+Z2Xh!rVllmo`"pdq>UNks7lTn!;N\r!!%TMrVlp!J:Qtc!;NAi!;Neu!;MiZ!;NPns7h0FVZ2/~>
+Z2Xe(rVlito`"mkq>UKrrrE&u!!'/$!!%TMrVuisli-qbV#LDpYl=\'QN$pbWrN)!JcDPGJ,~>
+Z2Xe(rVlito`"mkq>UKrrrE&u!!'/$!!%TMrVuisli-qbV#LDpYl=\'QN$pbWrN)!JcDPGJ,~>
+Z2Xh!rVllmo`"pdq>UNks7lTn!;N\r!!%TMrVlp!J:Qtc!;NAi!;Neu!;Ml[!;NSos7h0FV#Pr~>
+Z2Xe(rVlito`"mkqYpWts8N)trr<&%rr<%Ms8Dus!:0Xb!2KPo!3uP(!13]c!3?/"!.k0Es*t~>
+Z2Xe(rVlito`"mkqYpWts8N)trr<&%rr<%Ms8Dus!:0Xb!2KPo!3uP(!13]c!3?/"!.k0Es*t~>
+Z2Xh!rVllmo`"pdqYpZms8VlmrrDhsrr<%Ms8Ds!!.]UcrrDhhrrDi!rrDh\rrDhps8VkFs.]OD~>
+Yl=e*s8N)jrr<&qrrW9$rrE#t!!'2%!!%TMrVuisli-qbUAk2nZMsn)R/[-dX8`/"i;\?.ciEY:
+J,~>
+Yl=e*s8N)jrr<&qrrW9$rrE#t!!'2%!!%TMrVuisli-qbUAk2nZMsn)R/[-dX8`/"i;\?.ciEY:
+J,~>
+Yl=h#s8VlcrrDijrr`&rs7lQm!;N_s!!%TMrVlp!J:Qtc!;N;g!;Nl"!;Mr]!;NVp!;PLPJH4$s
+o)F4~>
+YQ+V&rVlitrr2rurVucqrVlitrr2rur;Q`sYQ"S&JcG]KrW)9a!!&bn!!'>)!!&Ge!!',#rrCsV
+!!%TMdf0:Io)F4~>
+YQ+V&rVlitrr2rurVucqrVlitrr2rur;Q`sYQ"S&JcG]KrW)9a!!&bn!!'>)!!&Ge!!',#rrCsV
+!!%TMdf0:Io)F4~>
+YQ+XtrVllmrr2unrVufjrVllmrr2unr;QclYQ"S&JcG]K!W[b$li-t[UAk5gZMsq"RK!9^XT/=q
+hu<ZVJcF0u!!)TiJ,~>
+Qi@$crr2rur;Q`sYQ"S&JcG]KrW)9a!!&_m!!'A*!!&Jf!!'/$rrCmT!!%TMdf0:Io)F4~>
+Qi@$crr2rur;Q`sYQ"S&JcG]KrW)9a!!&_m!!'A*!!&Jf!!'/$rrCmT!!%TMdf0:Io)F4~>
+Qi@'\rr2unr;QclYQ"S&JcG]K!W[b$li-t[U&P,fZi:%#Rf<B_XoJFrh>[HTJcF0u!!)TiJ,~>
+PQ(U_WW)quJcG]KrW)9a!!&_m!!'A*!!&Mg!!'2%rrCgR!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&_m!!'A*!!&Mg!!'2%rrCgR!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[U&P,fZi:%#S,WK`Y5eOsg]%6RJcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&\l!!'D+!!&Ph!!'5&rrCaP!!)$YrrDBbqZ,ORrrDNfr;at>rW)Tj
+J,~>
+PQ(U_WW)quJcG]KrW)9a!!&\l!!'D+!!&Ph!!'5&rrCaP!!)$YrrDBbqZ,ORrrDNfr;at>rW)Tj
+J,~>
+PQ(XXWW)quJcG]K!W[b$li-t[T`5#e[/U.$SGrTaYQ+Xtg&D$PirB#Yli6h^huE]Vn,N=dao;DB
+J:R:lJ,~>
+PQ(U_WW)quJcG]KrW)9a!!&\l!!'D+!!&Si!!'5&!!(XN!!)$YrrDusrrE&urrDfnrrD!WrrDBb
+rrE&u"9AK%!!)cnrrCdQrW)TjJ,~>
+PQ(U_WW)quJcG]KrW)9a!!&\l!!'D+!!&Si!!'5&!!(XN!!)$YrrDusrrE&urrDfnrrD!WrrDBb
+rrE&u"9AK%!!)cnrrCdQrW)TjJ,~>
+PQ(XXWW)quJcG]K!W[b$li-t[T`5#e[/U.$Sc8]bYQ"UtfDbgNirB#Yr;Zcsrr;uup](6ni;`fW
+li6tbrr3*$s8N'!p](6ngA_3SJ:R:lJ,~>
+PQ(U_WW)quJcG]KrW)9a!!&Yk!!'G,!!&Vj!!'8'rrCXM!!)$YrrE#tr;Zitr;Zp!!!*#u"9AK%
+!!)utrrE#t!W`9#rW)osr;[*&!!*'!!!*&t!<<*!!<3#s!<3#u!!`H'!<<'!!;ulq!<<)t!<<)t
+!<3#t!9*tW!;-;A~>
+PQ(U_WW)quJcG]KrW)9a!!&Yk!!'G,!!&Vj!!'8'rrCXM!!)$YrrE#tr;Zitr;Zp!!!*#u"9AK%
+!!)utrrE#t!W`9#rW)osr;[*&!!*'!!!*&t!<<*!!<3#s!<3#u!!`H'!<<'!!;ulq!<<)t!<<)t
+!<3#t!9*tW!;-;A~>
+PQ(XXWW)quJcG]K!W[b$li-t[TDnod[Jp7%T)SfcYlFauf)G^MirB#YrVufr!<;ut!ri6#rr3*$
+s8N'!rVultrVlp!s8W&urVufr#QFc(s8N'!s8;rts8N)us8;rss8N''rr<'!rr<&ss8;rts8;rt
+s8;rss8E#WrrN1NJFrkl~>
+PQ(U_WW)quJcG]KrW)9a!!&Yk!!'G,!!&Yk!!';(rrCRK!!)$YrrDusrrE&urrE*!rrE&u"9AK%
+!!)rsrrE*!$NU5,!!*$!!<<'!!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<)u!!E6$!<<#ur;Zcs
+qu?Zrs8W*!rr;uu!ri6#irAuXo`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Yk!!'G,!!&Yk!!';(rrCRK!!)$YrrDusrrE&urrE*!rrE&u"9AK%
+!!)rsrrE*!$NU5,!!*$!!<<'!!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<)u!!E6$!<<#ur;Zcs
+qu?Zrs8W*!rr;uu!ri6#irAuXo`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[TDnod[Jp7%TDnodZ2ak!eGfLKirB#Yr;Zcsrr;uus8W*!rr3*$
+s8N'!r;Zcss8NH,s8N'!rr<'!rr<&ts8N*!s8N*!s8N)us8N*!s8N*!s8N*!s8E!#rr<'!rW)lr
+rrDrrrrE*!rrE&urr<-#!!)$Y!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Vj!!'J-!!&\l!!'>)rrCLI!!)$YrrDusrrE&urrE&urr<*"!<3#r
+!<3#t!<3#u!!`H'!<<'!!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<*!!<<*!!<<)t!<3#u!;lfr
+!<<*!!<3#u!!<0#!94%X!;-;A~>
+PQ(U_WW)quJcG]KrW)9a!!&Vj!!'J-!!&\l!!'>)rrCLI!!)$YrrDusrrE&urrE&urr<*"!<3#r
+!<3#t!<3#u!!`H'!<<'!!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<*!!<<*!!<<)t!<3#u!;lfr
+!<<*!!<3#u!!<0#!94%X!;-;A~>
+PQ(XXWW)quJcG]K!W[b$li-t[T)Sfc[f6@&T`5#eZN't"df0:IirB#Yr;Zcsrr;uurr;uu!WN0!
+s82lrs8E#ts8N''rr<'!rr<&ts8N*!s8N*!s8N)us8N*!s8N*!s8N*!s8N*!s8N*!s8;rss8N)r
+s8N*!s8N)us8N'#rr<&YrrN1NJFrkl~>
+PQ(U_WW)quJcG]KrW)9a!!&Si!!'M.!!&_m!!'A*rrCFG!!)$YrrDusrrE&urrE&urr<*"!<3#u
+!;lfq!<3#r!<<*!!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<*!!<<*!!<)rs!<<*!!<)rr!<<*!
+!<3#r!94%X!;-;A~>
+PQ(U_WW)quJcG]KrW)9a!!&Si!!'M.!!&_m!!'A*rrCFG!!)$YrrDusrrE&urrE&urr<*"!<3#u
+!;lfq!<3#r!<<*!!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<*!!<<*!!<)rs!<<*!!<)rr!<<*!
+!<3#r!94%X!;-;A~>
+PQ(XXWW)quJcG]K!W[b$li-t[Sc8]b\,QI'U&P,fZiC(#d/O(GirB#Yr;Zcsrr;uurr;uu!WN0!
+s8N)rs8E#ts82lss8N)ts8N*!s8N*!s8N)us8N*!s8N*!s8N*!s8N*!s8N)ts8E#us8N)ts8;rt
+s8N)us82lVrrN1NJFrkl~>
+PQ(U_WW)quJcG]KrW)9a!!&Si!!'M.!!&bn!!'D+rrC@E!!)$YrrDusrrE&urrE&urr<*"!<3#u
+!;lfq!<3#u!;uls!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<*!!<<*!!;uls!<<*!!<3#u!!`H'
+!<<'!!<3#u!8mhU!;-;A~>
+PQ(U_WW)quJcG]KrW)9a!!&Si!!'M.!!&bn!!'D+rrC@E!!)$YrrDusrrE&urrE&urr<*"!<3#u
+!;lfq!<3#u!;uls!<)rt!<<*!!<<*!!<3#u!<<*!!<<*!!<<*!!<<*!!;uls!<<*!!<3#u!!`H'
+!<<'!!<3#u!8mhU!;-;A~>
+PQ(XXWW)quJcG]K!W[b$li-t[Sc8]b\,QI'UAk5g[/^1$cMmkEirB#Yr;Zcsrr;uurr;uu!WN0!
+s8N)rs8E#ts8N)ss8N)ts8N*!s8N*!s8N)us8N*!s8N*!s8N*!s8N*!s8N)ss8N*!s8N)us8N''
+rr<'!rr<&us8N)VrrN1NJFrkl~>
+PQ(U_WW)quJcG]KrW)9a!!&Ph!!'P/!!&eo!!'D+!!(7C!!)$YrrDusrrE&urrE#trrE#trrDus
+#QXo)!!*'!!!)rsrrE#trr<'!rW)uurrE&urrE*!rrE*!rrE*!rrE*!rr<*"!<3#u!<<*!!<3#u
+!!`H'!<<'!!<3#u!8mhU!;-;A~>
+PQ(U_WW)quJcG]KrW)9a!!&Ph!!'P/!!&eo!!'D+!!(7C!!)$YrrDusrrE&urrE#trrE#trrDus
+#QXo)!!*'!!!)rsrrE#trr<'!rW)uurrE&urrE*!rrE*!rrE*!rrE*!rr<*"!<3#u!<<*!!<3#u
+!!`H'!<<'!!<3#u!8mhU!;-;A~>
+PQ(XXWW)quJcG]K!W[b$li-t[SGrTa\GlR(U]1>h[/U.$bl7YCirB#Yr;Zcsrr;uurVultrVult
+r;R$&s8N'!s8N'!r;ZcsrVult!<<#us8W*!rr;uus8W*!s8W*!s8W*!s8W*!!WN0!s8N*!s8N)u
+s8N''rr<'!rr<&us8N)VrrN1NJFrkl~>
+PQ(U_WW)quJcG]KrW)9a!!&Ph!!'P/!!&hp!!'G,rrC7B!!)$YqZ-ZrrW)uurW)uurrE#tq>gKo
+rrE*!r;cisr;cltrr<-#!!*#urW!$"!!*#ur;cisrrE*!rrE*!r;cfrrW)uuquHcsrW)uur;bjW
+rW)TjJ,~>
+PQ(U_WW)quJcG]KrW)9a!!&Ph!!'P/!!&hp!!'G,rrC7B!!)$YqZ-ZrrW)uurW)uurrE#tq>gKo
+rrE*!r;cisr;cltrr<-#!!*#urW!$"!!*#ur;cisrrE*!rrE*!r;cfrrW)uuquHcsrW)uur;bjW
+rW)TjJ,~>
+PQ(XXWW)quJcG]K!W[b$li-t[SGrTa\GlR(V#LGi[K$:%bPqPBirAlUs8W&us8W&us8W*!rVu]o
+rVults8W#trr;oss8W*!!ri6#rr;rt!ri6#rr;osrr;uus8W*!s8W#trVuiss8Vuss8W&us8W#t
+ir9&[J:R:lJ,~>
+PQ(U_WW)quJcG]KrW)9a!!&Mg!!'S0!!&kq!!'J-rrC1@!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Mg!!'S0!!&kq!!'J-rrC1@!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[S,WK`\c2[)V>gPj[f?C&ao;>@JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Mg!!'S0!!&nr!!'M.rrC+>!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Mg!!'S0!!&nr!!'M.rrC+>!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[S,WK`\c2[)VZ-Yk\,ZL'a8Z,>JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Jf!!'V1!!&qs!!'P/rrC%<!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Jf!!'V1!!&qs!!'P/rrC%<!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[Rf<B_])Md*VuHbl\GuU(`W#o<JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Jf!!'V1!!&tt!!'P/!!'q:!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Jf!!'V1!!&tt!!'P/!!'q:!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[Rf<B_])Md*W;ckm\GlR(_uB]:JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ge!!'Y2!!'"u!!'S0rrBq9!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ge!!'Y2!!'"u!!'S0rrBq9!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[RK!9^]Dhm+WW)tn\c;^)_Z'T9JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ge!!'Y2!!'&!!!'V1rrBk7!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ge!!'Y2!!'&!!!'V1rrBk7!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[RK!9^]Dhm+WrE(o])Vg*_#FB7JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Dd!!'\3!!')"!!'Y2rrBe5!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Dd!!'\3!!')"!!'Y2rrBe5!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[R/[0]]`/!,X8`1p]Dqp+^Ae05JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ac!!'_4!!',#!!'\3rrB_3!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ac!!'_4!!',#!!'\3rrB_3!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[Qi@'\^&J*-XT&:q]`8$,]`.s3JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ac!!'_4!!'/$!!'\3!!'V1!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&Ac!!'_4!!'/$!!'\3!!'V1!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[Qi@'\^&J*-XoACr]`/!,])Ma1JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&>b!!'b5!!'2%!!'_4rrBV0JH3sqo`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&>b!!'b5!!'2%!!'_4rrBV0JH3sqo`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[QN$s[^Ae3.Y5\Ls^&S--\c73\ciF)ro`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&>b!!'b5!!'8'rrBe5rrBP.!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&>b!!'b5!!'8'rrBe5rrBP.!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[QN$s[^Ae3.YlFau^An6.\,QF.JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&;a!!'e6!!';(!!'b5rrBJ,!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&;a!!'e6!!';(!!'b5rrBJ,!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[Q2^jZ^]+</Z2Xh!^An6.[Jp4,JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&;a!!'e6!!'>)!!'e6rrBD*!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&;a!!'e6!!'>)!!'e6rrBD*!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[Q2^jZ^]+</ZMsq"^]4?/Zi:"*JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&8`!!'h7!!'A*!!'e6!!';(!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&8`!!'h7!!'A*!!'e6!!';(!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[PlCaY_#FE0Zi:%#^]+</Z2Xe(JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&8`!!'h7!!'D+!!'h7rrB;'!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&8`!!'h7!!'D+!!'h7rrB;'!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[PlCaY_#FE0[/U.$_#OH0Yl=\'JcF0u!W[b$o`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&5_!!'k8!!'G,!!'k8rrB5%!!%TMdf9:Ho`'F~>
+PQ(U_WW)quJcG]KrW)9a!!&5_!!'k8!!'G,!!'k8rrB5%!!%TMdf9:Ho`'F~>
+PQ(XXWW)quJcG]K!W[b$li-t[PQ(XX_>aN1[Jp7%_>jQ1Y5\J%JcF0u!W[b$o`'F~>
+PQ(U_WW.MLq#Ka\!!&2^!!'n9!!'J-!!'n9rrB/#!!%TMdf9:Ho`'F~>
+PQ(U_WW.MLq#Ka\!!&2^!!'n9!!'J-!!'n9rrB/#!!%TMdf9:Ho`'F~>
+PQ(XXWW.MLqZ-YHli-t[P5bOW_Z'W2[f6@&_Z0Z2XT&8#JcF0u!W[b$o`'F~>
+PQ(U_VZ22IquH'_!!&2^!!'n9!!'M.!!'q:rrB)!!!%TMdf9:Ho`'F~>
+PQ(U_VZ22IquH'_!!&2^!!'n9!!'M.!!'q:rrB)!!!%TMdf9:Ho`'F~>
+PQ(XXVZ23tr.+,5!;M`W!;OG2!;O&'!;OJ3s7iVo!!%TMdf0@KJ:R:lJ,~>
+PQ(U_VZ22IquH'_!!&/]!!'q:!!'P/!!'q:!!&tt!!%TMdf9:Ho`'F~>
+PQ(U_VZ22IquH'_!!&/]!!'q:!!'P/!!'q:!!&tt!!%TMdf9:Ho`'F~>
+PQ(XXVZ23tr.+,5!;M]V!;OJ3!;O)(!;OJ3!;NMm!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!&/]!!'q:!!'S0!!'t;rrAts!!%TMdf9:Ho`'F~>
+PQ(U_JcEC_!!(FH!!&/]!!'q:!!'S0!!'t;rrAts!!%TMdf9:Ho`'F~>
+PQ(XXJcEC_!;OtA!;M]V!;OJ3!;O,)!;OM4s7iMl!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!&,\!!'t;!!'V1!!("<rrAnq!!%TMdf9:Ho`'F~>
+PQ(U_JcEC_!!(FH!!&,\!!'t;!!'V1!!("<rrAnq!!%TMdf9:Ho`'F~>
+PQ(XXJcEC_!;OtA!;MZU!;OM4!;O/*!;OP5s7iGj!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEF`rW(CH!!&,\!!'t;!!'Y2!!(%=rrAho!!)9`!!)HeqZ,UT!!)Qh!!)rs!!)Ti!!(7C
+rW)TjJ,~>
+PQ(U_JcEF`rW(CH!!&,\!!'t;!!'Y2!!(%=rrAho!!)9`!!)HeqZ,UT!!)Qh!!)rs!!)Ti!!(7C
+rW)TjJ,~>
+PQ(XXJcEF`rqOqA!;MZU!;OM4!;O2+!;OS6s7iAh!!)9`!!)HeqZ,UT!!)Qh!!)rs!!)Ti!!(7C
+!W[b$o`'F~>
+PQ(U_JcEjlrrDfnrW(CH!!&)[!!("<!!'\3!!((>rrAbm!!)Qh!!)lq!!)rs!!*#u!!)fo!!(sW
+!!)EdrrE&urrDWi!!(7CrW)TjJ,~>
+PQ(U_JcEjlrrDfnrW(CH!!&)[!!("<!!'\3!!((>rrAbm!!)Qh!!)lq!!)rs!!*#u!!)fo!!(sW
+!!)EdrrE&urrDWi!!(7CrW)TjJ,~>
+PQ(XXJcEjls7l?grqOqA!;MWT!;OP5!;O5,!;OV7s7i;f!!)Qh!!)lq!!)rs!!*#u!!)fo!!(sW
+!!)EdrrE&urrDWi!!(7C!W[b$o`'F~>
+PQ(U_JcEmm!W`6#q#:HsrrE'!e,KCJO8f1[`W#o<^&J'4a8Z,>TDnlkq#:<or;Z`rs8N'!rr2ru
+rVuis!<<#u!WN/ts8N)rrr<&urr<&us8E#ss8E#urr<&urrE-"rW)uu!!*#urW)rt!s&?$!<3#u
+!<3#u!<)rs!<)rs!!3*"rr;rtdf9:Ho`'F~>
+PQ(U_JcEmm!W`6#q#:HsrrE'!e,KCJO8f1[`W#o<^&J'4a8Z,>TDnlkq#:<or;Z`rs8N'!rr2ru
+rVuis!<<#u!WN/ts8N)rrr<&urr<&us8E#ss8E#urr<&urrE-"rW)uu!!*#urW)rt!s&?$!<3#u
+!<3#u!<)rs!<)rs!!3*"rr;rtdf9:Ho`'F~>
+PQ(XXJcEmm!r2fjq#:Kls7lWhe,KFCO8f4T`W#r5^&J*-a8Z/7TDnlkq#:<or;Z`rs8N'!rr2ru
+rVuis!<<#u!WN/ts8N)rrr<&urr<&us8E#ss8E#urr<&urrE-"rW)uu!!*#urW)rt!s&?$!<3#u
+!<3#u!<)rs!<)rs!!3*"rr;rtdf0@KJ:R:lJ,~>
+PQ(U_JcEgk!!)fo"9AH%rrCOJ!!&&Z!!(%=!!'b5!!(+?rrAYj!!)fo!!)or!!)lq!!)rs!!*#u
+!!*#u!!*#u!W`6#qYpTsrrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)urt#21rr<'!rrE*!
+!<3'!!<3&urr<&urrW9$rrE&urrE*!!!*#u!!(LJrW)TjJ,~>
+PQ(U_JcEgk!!)fo"9AH%rrCOJ!!&&Z!!(%=!!'b5!!(+?rrAYj!!)fo!!)or!!)lq!!)rs!!*#u
+!!*#u!!*#u!W`6#qYpTsrrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)urt#21rr<'!rrE*!
+!<3'!!<3&urr<&urrW9$rrE&urrE*!!!*#u!!(LJrW)TjJ,~>
+PQ(XXJcEgk!;Q?h"Si#ls7k(C!;MTS!;OS6!;O;.!;OY8s7i2c!!)fo!!)or!!)lq!!)rs!!*#u
+!!*#u!!*#u!W`6#qYpTsrrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)urt#21rr<'!rrE*!
+!<3'!!<3&urr<&urrW9$rrE&urrE*!!!*#u!!(LJ!W[b$o`'F~>
+PQ(U_JcEgk!!)ip"p"]'!<<'!eGfLKNrK(Z`r?#=^]+96aoDA@SGrQhq#:<oqu6WrqYpNqr;Q`s
+rr2rurr2rurr3!!s82lrrrN3#!<2uu!<3!#!<<'!r;Q`srr3'#s8N)urrW9$rrE&u!s&B$!<3!)
+!<<'!rrE'!rrE&u!!*#u!s&B$!<)p"!<<'!rr2rue,TCIo`'F~>
+PQ(U_JcEgk!!)ip"p"]'!<<'!eGfLKNrK(Z`r?#=^]+96aoDA@SGrQhq#:<oqu6WrqYpNqr;Q`s
+rr2rurr2rurr3!!s82lrrrN3#!<2uu!<3!#!<<'!r;Q`srr3'#s8N)urrW9$rrE&u!s&B$!<3!)
+!<<'!rrE'!rrE&u!!*#u!s&B$!<)p"!<<'!rr2rue,TCIo`'F~>
+PQ(XXJcEgk!;QBi#5J5uq#CBheGfODNrK+S`r?&6^]+</aoDD9SGrQhq#:<oqu6WrqYpNqr;Q`s
+rr2rurr2rurr3!!s82lrrrN3#!<2uu!<3!#!<<'!r;Q`srr3'#s8N)urrW9$rrE&u!s&B$!<3!)
+!<<'!rrE'!rrE&u!!*#u!s&B$!<)p"!<<'!rr2rue,KILJ:R:lJ,~>
+PQ(U_JcEgk!!)ip"p"]'!<<'!eGfLKNW/tYa8Z,>_#FB7b5_JARf<?fqu?Kmrr2ruqYpNqr;Q`s
+rr2rurVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u#lt#*!<3'!
+!<3&urr<&urrW9$rrE#t!W`9#quG4GrW)TjJ,~>
+PQ(U_JcEgk!!)ip"p"]'!<<'!eGfLKNW/tYa8Z,>_#FB7b5_JARf<?fqu?Kmrr2ruqYpNqr;Q`s
+rr2rurVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u#lt#*!<3'!
+!<3&urr<&urrW9$rrE#t!W`9#quG4GrW)TjJ,~>
+PQ(XXJcEgk!;QBi#5J5uq#CBheGfODNW0"Ra8Z/7_#FE0b5_M:Rf<?fqu?Kmrr2ruqYpNqr;Q`s
+rr2rurVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u#lt#*!<3'!
+!<3&urr<&urrW9$rrE#t!W`9#quG4G!W[b$o`'F~>
+PQ(U_JcEgk!!)ip"p"]'!<<'!eGfLKN;ikXaSu5?_>aK8bQ%SBR/[-dq#:<oqu6WrqYpNqr;Q`s
+rr2rurVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr39)s8N*!
+rrE*!!<2uu!<3!#!<<'!rVls"s8N)Fs8E#js*t~>
+PQ(U_JcEgk!!)ip"p"]'!<<'!eGfLKN;ikXaSu5?_>aK8bQ%SBR/[-dq#:<oqu6WrqYpNqr;Q`s
+rr2rurVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr39)s8N*!
+rrE*!!<2uu!<3!#!<<'!rVls"s8N)Fs8E#js*t~>
+PQ(XXJcEgk!;QBi#5J5uq#CBheGfODN;inQaSu88_>aN1bQ%V;R/[-dq#:<oqu6WrqYpNqr;Q`s
+rr2rurVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr39)s8N*!
+rrE*!!<2uu!<3!#!<<'!rVls"s8N)FrrN1NJFrkl~>
+PQ(U_JcEgk!!)lq!!*#u!!*#u!!(RL!!%uX!!(+?!!'n9!!(7CrrAAb!!)fo!!)or!!)lq!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uj%!<<'!!<<'!rr3'#s8N)urrW9$rrE&u#lt#*
+!<<'!s8N)urr<&urrW9$rrE&urrE*!!!(@FrW)TjJ,~>
+PQ(U_JcEgk!!)lq!!*#u!!*#u!!(RL!!%uX!!(+?!!'n9!!(7CrrAAb!!)fo!!)or!!)lq!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uj%!<<'!!<<'!rr3'#s8N)urrW9$rrE&u#lt#*
+!<<'!s8N)urr<&urrW9$rrE&urrE*!!!(@FrW)TjJ,~>
+PQ(XXJcEgk!;QEj!;QQn!;QQn!;P+E!;MNQ!;OY8!;OG2!;Oe<s7ho[!!)fo!!)or!!)lq!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uj%!<<'!!<<'!rr3'#s8N)urrW9$rrE&u#lt#*
+!<<'!s8N)urr<&urrW9$rrE&urrE*!!!(@F!W[b$o`'F~>
+PQ(U_JcEgk!!)lq!!*#u!!*#u!!(RL!!%rW!!(.@!!'q:!!(7C!!&8`!!)fo!!)lq!s&B$!<3#r
+!<<'!!<2uu!<)ot!<3#q!!3*"rr2rurr;osrr;rtrr;uu!WN0!rrW9$rrE&urW)rt!!*#u!s&B$
+!;uis!<)rs!<)rs!!3*"rr;ose,TCIo`'F~>
+PQ(U_JcEgk!!)lq!!*#u!!*#u!!(RL!!%rW!!(.@!!'q:!!(7C!!&8`!!)fo!!)lq!s&B$!<3#r
+!<<'!!<2uu!<)ot!<3#q!!3*"rr2rurr;osrr;rtrr;uu!WN0!rrW9$rrE&urW)rt!!*#u!s&B$
+!;uis!<)rs!<)rs!!3*"rr;ose,TCIo`'F~>
+PQ(XXJcEgk!;QEj!;QQn!;QQn!;P+E!;MKP!;O\9!;OJ3!;Oe<!;MfY!!)fo!!)lq!s&B$!<3#r
+!<<'!!<2uu!<)ot!<3#q!!3*"rr2rurr;osrr;rtrr;uu!WN0!rrW9$rrE&urW)rt!!*#u!s&B$
+!;uis!<)rs!<)rs!!3*"rr;ose,KILJ:R:lJ,~>
+PQ(U_JcEmmquH]q!!)ut!!)ut!!(UM!!%rW!!(.@!!'t;!!(:DrrA8_!!%TMdf9:Ho`'F~>
+PQ(U_JcEmmquH]q!!)ut!!)ut!!(UM!!%rW!!(.@!!'t;!!(:DrrA8_!!%TMdf9:Ho`'F~>
+PQ(XXJcEmmr:p6j!;QNm!;QNm!;P.F!;MKP!;O\9!;OM4!;Oh=s7hfX!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcERd!!)ut!!)ut!!(UM!!%oV!!(1A!!("<!!(=ErrA2]!!%TMdf9:Ho`'F~>
+PQ(U_JcERd!!)ut!!)ut!!(UM!!%oV!!(1A!!("<!!(=ErrA2]!!%TMdf9:Ho`'F~>
+PQ(XXJcERd!;QNm!;QNm!;P.F!;MHO!;O_:!;OP5!;Ok>s7h`V!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!%oV!!(1A!!(%=!!(@FrrA,[!!%TMdf9:Ho`'F~>
+PQ(U_JcEC_!!(FH!!%oV!!(1A!!(%=!!(@FrrA,[!!%TMdf9:Ho`'F~>
+PQ(XXJcEC_!;OtA!;MHO!;O_:!;OS6!;On?s7hZT!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!%lU!!(4B!!((>!!(CGrrA&Y!!%TMdf9:Ho`'F~>
+PQ(U_JcEC_!!(FH!!%lU!!(4B!!((>!!(CGrrA&Y!!%TMdf9:Ho`'F~>
+PQ(XXJcEC_!;OtA!;MEN!;Ob;!;OV7!;Oq@s7hTR!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!%lU!!(4B!!(+?!!(CG!!%rW!!%TMdf9:Ho`'F~>
+PQ(U_JcEC_!!(FH!!%lU!!(4B!!(+?!!(CG!!%rW!!%TMdf9:Ho`'F~>
+PQ(XXJcEC_!;OtA!;MEN!;Ob;!;OY8!;Oq@!;MKP!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!%iT!!(7C!!(.@!!(FHrr@rV!!%TMdf9:Ho`'F~>
+PQ(U_JcEC_!!(FH!!%iT!!(7C!!(.@!!(FHrr@rV!!%TMdf9:Ho`'F~>
+PQ(XXJcEC_!;OtA!;MBM!;Oe<!;O\9!;OtAs7hKO!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!%fS!!(:D!!(1A!!(IIrr@lT!!)0]!!)HeqZ,UT!!)QhquHQm!!)'Z!!)-\
+rW)TjJ,~>
+PQ(U_JcEC_!!(FH!!%fS!!(:D!!(1A!!(IIrr@lT!!)0]!!)HeqZ,UT!!)QhquHQm!!)'Z!!)-\
+rW)TjJ,~>
+PQ(XXJcEC_!;OtA!;M?L!;Oh=!;O_:!;P"Bs7hEM!!)0]!!)HeqZ,UT!!)QhquHQm!!)'Z!!)-\
+!W[b$o`'F~>
+PQ(U_JcEC_!!(FH!!%fS!!(:D!!(4B!!(LJrr@fR!!)0]!!)rs!!*#u!!)fo!!(sW!!)He!!)Zk
+!!)'Z!!)-\rW)TjJ,~>
+PQ(U_JcEC_!!(FH!!%fS!!(:D!!(4B!!(LJrr@fR!!)0]!!)rs!!*#u!!)fo!!(sW!!)He!!)Zk
+!!)'Z!!)-\rW)TjJ,~>
+PQ(XXJcEC_!;OtA!;M?L!;Oh=!;Ob;!;P%Cs7h?K!!)0]!!)rs!!*#u!!)fo!!(sW!!)He!!)Zk
+!!)'Z!!)-\!W[b$o`'F~>
+PQ(U_JcEC_!!(FH!!%cR!!(=E!!(7C!!(OKrr@`P!!)fo!!)or!s&?$!<2uu!<2uu!<)rs!!*&u
+!!3*"r;Zcsqu6Wrrr2rurr;rtrVuiss8N'!rr3!!s8E#urr<&us8E#trrrK'!!*'!!;lcr!<3!$
+!<<'!s8E#trs&Q(!!*'!!!)utrW)osrW!!!!<3#t!:0[a!;-;A~>
+PQ(U_JcEC_!!(FH!!%cR!!(=E!!(7C!!(OKrr@`P!!)fo!!)or!s&?$!<2uu!<2uu!<)rs!!*&u
+!!3*"r;Zcsqu6Wrrr2rurr;rtrVuiss8N'!rr3!!s8E#urr<&us8E#trrrK'!!*'!!;lcr!<3!$
+!<<'!s8E#trs&Q(!!*'!!!)utrW)osrW!!!!<3#t!:0[a!;-;A~>
+PQ(XXJcEC_!;OtA!;M<K!;Ok>!;Oe<!;P(Ds7h9I!!)fo!!)or!s&?$!<2uu!<2uu!<)rs!!*&u
+!!3*"r;Zcsqu6Wrrr2rurr;rtrVuiss8N'!rr3!!s8E#urr<&us8E#trrrK'!!*'!!;lcr!<3!$
+!<<'!s8E#trs&Q(!!*'!!!)utrW)osrW!!!!<3#t!:0Xd!.]Uls*t~>
+PQ(U_JcEC_!!(FH!!%cR!!(=E!!(:D!!(OK!!%WN!!)fo!!)orrrE*!!!)or!!)rs!!*#u!!*#u
+!!*#u!W`6#qYpTsrrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)ursAc+rr<'!rrE*!!;uis
+!<3!$!<<'!!<3!.!<<'!!<<'!!<<'!s8N)urrW9$rrE&urrE*!!!*#u!!)BcrW)TjJ,~>
+PQ(U_JcEC_!!(FH!!%cR!!(=E!!(:D!!(OK!!%WN!!)fo!!)orrrE*!!!)or!!)rs!!*#u!!*#u
+!!*#u!W`6#qYpTsrrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)ursAc+rr<'!rrE*!!;uis
+!<3!$!<<'!!<3!.!<<'!!<<'!!<<'!s8N)urrW9$rrE&urrE*!!!*#u!!)BcrW)TjJ,~>
+PQ(XXJcEC_!;OtA!;M<K!;Ok>!;Oh=!;P(D!;M0G!!)fo!!)orrrE*!!!)or!!)rs!!*#u!!*#u
+!!*#u!W`6#qYpTsrrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)ursAc+rr<'!rrE*!!;uis
+!<3!$!<<'!!<3!.!<<'!!<<'!!<<'!s8N)urrW9$rrE&urrE*!!!*#u!!)Bc!W[b$o`'F~>
+PQ(U_JcEC_!!(FH!!%`Q!!(@F!!(=E!!(RLrr@WM!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!*#u
+!!*#u!<E/t!<3!"!<3&urr<&urrW9$rrDus!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&us8N)u
+rr<&urrW9$rrE#t!s&B$!<2uu!<3!#!<<'!rr3'#s8N)trrW9$rrE&u!!)BcrW)TjJ,~>
+PQ(U_JcEC_!!(FH!!%`Q!!(@F!!(=E!!(RLrr@WM!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!*#u
+!!*#u!<E/t!<3!"!<3&urr<&urrW9$rrDus!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&us8N)u
+rr<&urrW9$rrE#t!s&B$!<2uu!<3!#!<<'!rr3'#s8N)trrW9$rrE&u!!)BcrW)TjJ,~>
+PQ(XXJcEC_!;OtA!;M9J!;On?!;Ok>!;P+Es7h0F!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!*#u
+!!*#u!<E/t!<3!"!<3&urr<&urrW9$rrDus!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&us8N)u
+rr<&urrW9$rrE#t!s&B$!<2uu!<3!#!<<'!rr3'#s8N)trrW9$rrE&u!!)Bc!W[b$o`'F~>
+PQ(U_JcEC_!!(FH!!%`Q!!(@F!!(@F!!(UMrr@WMs8N'!qu?Kmrr2rurr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs!s&B$!<3!#
+!<<'!rVls"s8N)urr<&urrW9$rrE&u!s&B$!<)p!!<<)s!:9ab!;-;A~>
+PQ(U_JcEC_!!(FH!!%`Q!!(@F!!(@F!!(UMrr@WMs8N'!qu?Kmrr2rurr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs!s&B$!<3!#
+!<<'!rVls"s8N)urr<&urrW9$rrE&u!s&B$!<)p!!<<)s!:9ab!;-;A~>
+PQ(XXJcEC_!;OtA!;M9J!;On?!;On?!;P.Fs7h0Fs8N'!qu?Kmrr2rurr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs!s&B$!<3!#
+!<<'!rVls"s8N)urr<&urrW9$rrE&u!s&B$!<)p!!<<)s!:9^e!.]Uls*t~>
+PQ(U_JcEC_!!(FH!!%]P!!(CG!!(CG!!(XNrr@WMrVlitq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2rur;Qj!s8N)u
+rrW9$rrE#t!s&B$!<2uu!<3!#!<<'!rr3'#s8N)trrW9$rrD9_rW)TjJ,~>
+PQ(U_JcEC_!!(FH!!%]P!!(CG!!(CG!!(XNrr@WMrVlitq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2rur;Qj!s8N)u
+rrW9$rrE#t!s&B$!<2uu!<3!#!<<'!rr3'#s8N)trrW9$rrD9_rW)TjJ,~>
+PQ(XXJcEC_!;OtA!;M6I!;Oq@!;Oq@!;P1Gs7h0FrVlitq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2rur;Qj!s8N)u
+rrW9$rrE#t!s&B$!<2uu!<3!#!<<'!rr3'#s8N)trrW9$rrD9_!W[b$o`'F~>
+PQ(U_JcEC_!!(FH!!%]P!!(CG!!(FH!!([Orr@WMqu6Wrq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;c]s!<3&urr<&rrr<&srs&Q(rr<'!rrE&u!s&B$!<3!#!<<'!rr2rur;R-)s8N*!
+rr<'!rr<&urrW9$rrE&u!!*#u!s&B$!<3!#!<<'!rr;uus8N'!kl:V^o`'F~>
+PQ(U_JcEC_!!(FH!!%]P!!(CG!!(FH!!([Orr@WMqu6Wrq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;c]s!<3&urr<&rrr<&srs&Q(rr<'!rrE&u!s&B$!<3!#!<<'!rr2rur;R-)s8N*!
+rr<'!rr<&urrW9$rrE&u!!*#u!s&B$!<3!#!<<'!rr;uus8N'!kl:V^o`'F~>
+PQ(XXJcEC_!;OtA!;M6I!;Oq@!;OtA!;P4Hs7h0Fqu6Wrq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2ru
+rVm$$rrE*!!;c]s!<3&urr<&rrr<&srs&Q(rr<'!rrE&u!s&B$!<3!#!<<'!rr2rur;R-)s8N*!
+rr<'!rr<&urrW9$rrE&u!!*#u!s&B$!<3!#!<<'!rr;uus8N'!kl1\aJ:R:lJ,~>
+PQ(U_JcEC_!!(FH!!%ZO!!(FH!!(II!!([O!!%TMq>UEpq#:<oqu6Wrrr3'#s8N)us82lsrr<&u
+rr<&trr<&us8)csrrE&u!!*#ur;cisrW)rtrr<*"!<3!#!<<'!rr;rtrr2rurr3!!s8;rrs8N'&
+rrE*!!<<#urr2rurr2rurr2rurr;rtrVuis!WN0!s8;ras8E#js*t~>
+PQ(U_JcEC_!!(FH!!%ZO!!(FH!!(II!!([O!!%TMq>UEpq#:<oqu6Wrrr3'#s8N)us82lsrr<&u
+rr<&trr<&us8)csrrE&u!!*#ur;cisrW)rtrr<*"!<3!#!<<'!rr;rtrr2rurr3!!s8;rrs8N'&
+rrE*!!<<#urr2rurr2rurr2rurr;rtrVuis!WN0!s8;ras8E#js*t~>
+PQ(XXJcEC_!;OtA!;M3H!;OtA!;P"B!;P4H!;M-Fq>UEpq#:<oqu6Wrrr3'#s8N)us82lsrr<&u
+rr<&trr<&us8)csrrE&u!!*#ur;cisrW)rtrr<*"!<3!#!<<'!rr;rtrr2rurr3!!s8;rrs8N'&
+rrE*!!<<#urr2rurr2rurr2rurr;rtrVuis!WN0!s8;rarrN1NJFrkl~>
+PQ(U_JcF@%M?'dY!!(FH!!(LJ!!(^Prr@WMq#:<oJcF0urW)TjJ,~>
+PQ(U_JcF@%M?'dY!!(FH!!(LJ!!(^Prr@WMq#:<oJcF0urW)TjJ,~>
+PQ(XXJcF@%M?'dY!;OtA!;P%C!;P7Is7h0Fq#:<oJcF0u!W[b$o`'F~>
+PQ(U_JcF@%!!%uX!!',#!!(II!!(OK!!(aQrr@WMpAY*mJcF0urW)TjJ,~>
+PQ(U_JcF@%!!%uX!!',#!!(II!!(OK!!(aQrr@WMpAY*mJcF0urW)TjJ,~>
+PQ(XXJcF@%!!%uX!!',#!;P"B!;P(D!;P:Js7h0FpAY*mJcF0u!W[b$o`'F~>
+PQ(U_JcF@%!!%uX!!')"!!(LJ!!(RL!!(dRrr@WMo`"mkJcF0urW)TjJ,~>
+PQ(U_JcF@%!!%uX!!')"!!(LJ!!(RL!!(dRrr@WMo`"mkJcF0urW)TjJ,~>
+PQ(XXJcF@%!!%uX!!')"!;P%C!;P+E!;P=Ks7h0Fo`"mkJcF0u!W[b$o`'F~>
+PQ(U_JcF@%!!%uXrW')#!!(LJ!!(UM!!(gSrr@WMo)A[iJcF0urW)TjJ,~>
+PQ(U_JcF@%!!%uXrW')#!!(LJ!!(UM!!(gSrr@WMo)A[iJcF0urW)TjJ,~>
+PQ(XXJcF@%!!%uX!W[b$XoACre,KFCf)GaFh#IELJcG<@!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcF@%!!)Ngq#KOVr;ah:rW'&"!!(OK!!(XN!!(gS!!%TMnG`IgJcF0urW)TjJ,~>
+PQ(U_JcF@%!!)Ngq#KOVr;ah:rW'&"!!(OK!!(XN!!(gS!!%TMnG`IgJcF0urW)TjJ,~>
+PQ(XXJcF@%!!)Ngq#KOVr;ah:!W[b$XT&:qeGfODfDbjGh#@BLJcG6>!!%TMdf0@KJ:R:lJ,~>
+PQ(U_JcF@%!!)EdrrD*ZrrE&u!!)KfrrDQgrrDHdrW'&"!!(OK!!([O!!(jTrr@WMn,E@fJcF0u
+rW)TjJ,~>
+PQ(U_JcF@%!!)EdrrD*ZrrE&u!!)KfrrDQgrrDHdrW'&"!!(OK!!([O!!(jTrr@WMn,E@fJcF0u
+rW)TjJ,~>
+PQ(XXJcF@%!!)EdrrD*ZrrE&u!!)KfrrDQgrrDHd!W[b$XT&:qeGfODf`(sHh>dNMJcG3=!!%TM
+df0@KJ:R:lJ,~>
+PQ(U_JcF@%!!)EdrrE#trr<-#!<;utrVufrs8W&urr;uuq>^Bnrr;uu"TJH%s8W#trr;rts8W*!
+rVucqmf37dX8`/"ec,ULg&D$PhZ*TUJcG-;!!(CG!!)]lq>gQq!!&JfrW)TjJ,~>
+PQ(U_JcF@%!!)EdrrE#trr<-#!<;utrVufrs8W&urr;uuq>^Bnrr;uu"TJH%s8W#trr;rts8W*!
+rVucqmf37dX8`/"ec,ULg&D$PhZ*TUJcG-;!!(CG!!)]lq>gQq!!&JfrW)TjJ,~>
+PQ(XXJcF@%!!)EdrrE#trr<-#!<;utrVufrs8W&urr;uuq>^Bnrr;uu"TJH%s8W#trr;rts8W*!
+rVucqmf*=gJ:O^#!;P+E!;P7I!;PFNs7h0FmJd.dd/O(Gp&Fjgs8N'!Rf<EhJ:R:lJ,~>
+PQ(U_JcF@%!!)EdrrE#trW)lrrrE*!rrE#trr<9'!!*'!!!)lqrrE*!rrE*!rW!0&!!*'!!!*#u
+rr<N.!!*'!!!*'!!<<'!!:Bgc!3?,"!7h)L!8@GQ!8mhV!.k19rr<&Zrr<&frr<&srr<&urr<&s
+rr<%`s8E#js*t~>
+PQ(U_JcF@%!!)EdrrE#trW)lrrrE*!rrE#trr<9'!!*'!!!)lqrrE*!rrE*!rW!0&!!*'!!!*#u
+rr<N.!!*'!!!*'!!<<'!!:Bgc!3?,"!7h)L!8@GQ!8mhV!.k19rr<&Zrr<&frr<&srr<&urr<&s
+rr<%`s8E#js*t~>
+PQ(XXJcF@%!!)EdrrE#trW)lrrrE*!rrE#trr<9'!!*'!!!)lqrrE*!rrE*!rW!0&!!*'!!!*#u
+rr<N.!!*'!!!*'!!<<'!!:Bdf!.]U#rrDiErrDiJrrDiOs8VkFs6K[b!9=(Z!:Tpf!;uis!<2uu
+!;uis!0mKb!.]Uls*t~>
+PQ(U_JcF@%!!)EdrrE#trrDrrrrE*!rrE#trr<9'!!*'!!!)lqrrE*!rrE*!rrE*!rrE*!rrE&u
+rr<-#!!*#urW)rtrrDHdrW&tu!!(UM!!(dR!!(sWrr@WMl2L_`q#:<oqZ$Nprr3-%rr<'!s8E#u
+rrE-"rW)lrrrE&u!!)utrVururW)os!!)rs$3:,+!<3$!s8N'!rVuisX8i/!o`'F~>
+PQ(U_JcF@%!!)EdrrE#trrDrrrrE*!rrE#trr<9'!!*'!!!)lqrrE*!rrE*!rrE*!rrE*!rrE&u
+rr<-#!!*#urW)rtrrDHdrW&tu!!(UM!!(dR!!(sWrr@WMl2L_`q#:<oqZ$Nprr3-%rr<'!s8E#u
+rrE-"rW)lrrrE&u!!)utrVururW)os!!)rs$3:,+!<3$!s8N'!rVuisX8i/!o`'F~>
+PQ(XXJcF@%!!)EdrrE#trrDrrrrE*!rrE#trr<9'!!*'!!!)lqrrE*!rrE*!rrE*!rrE*!rrE&u
+rr<-#!!*#urW)rtrrDHd!W[b$WrE(of)GaFg]%9Ki;`iPJcG!7!!)fo!!)lqrW)rt"T\Q&!<<)u
+!<<'"!<<#ur;Zcsrr2rurVuis!<<#urVlitr;R*(s8N*!!!*'!!!)utrW'#!!W[b$o`'F~>
+PQ(U_JcF@%!!)EdrrE#trrE#tr;cltrrE#tquHcsrrDoqrrE*!rrE*!rrE*!rrE*!rrE&uquH`r
+rW)rtrrDHdrW&tu!!(UM!!(gS!!(sW!!%TMkPkM^q#:<oqu6Wrrr3<*s8N'!s8N*!rrE&urrE*!
+!!)rs!!)ut!!)rs!!*#u!!)rs!!)rs%KQP/!!*'!!!*'!!<<'!rr2ruXT/8"o`'F~>
+PQ(U_JcF@%!!)EdrrE#trrE#tr;cltrrE#tquHcsrrDoqrrE*!rrE*!rrE*!rrE*!rrE&uquH`r
+rW)rtrrDHdrW&tu!!(UM!!(gS!!(sW!!%TMkPkM^q#:<oqu6Wrrr3<*s8N'!s8N*!rrE&urrE*!
+!!)rs!!)ut!!)rs!!*#u!!)rs!!)rs%KQP/!!*'!!!*'!!<<'!rr2ruXT/8"o`'F~>
+PQ(XXJcF@%!!)EdrrE#trrE#tr;cltrrE#tquHcsrrDoqrrE*!rrE*!rrE*!rrE*!rrE&uquH`r
+rW)rtrrDHd!W[b$WrE(of)GaFh#@BLi;WfPJcFp5!!)fo!!)or!!*#u$3:,+!!*'!!<<'!rr;uu
+s8N'!r;Q`srVlitr;Q`srr2rur;Q`sr;R6,s8N'!s8N'!s8N*!rrE&u!!',#!W[b$o`'F~>
+PQ(U_JcF@%!!)EdrrE#trrE&urr<9'!!*'!!!)utrrDusrrDoqrrE*!rrE*!rrE*!rrE*!rrE&u
+rrDrrrW)rtrrDHdrW&qt!!(XN!!(jT!!)!Xrr@WMk5PD]q#:<oqu6Wrrr3'#s8N)urrW9$rrE&u
+!!)ut!!*#u!!)rs!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruXT/8"o`'F~>
+PQ(U_JcF@%!!)EdrrE#trrE&urr<9'!!*'!!!)utrrDusrrDoqrrE*!rrE*!rrE*!rrE*!rrE&u
+rrDrrrW)rtrrDHdrW&qt!!(XN!!(jT!!)!Xrr@WMk5PD]q#:<oqu6Wrrr3'#s8N)urrW9$rrE&u
+!!)ut!!*#u!!)rs!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruXT/8"o`'F~>
+PQ(XXJcF@%!!)EdrrE#trrE&urr<9'!!*'!!!)utrrDusrrDoqrrE*!rrE*!rrE*!rrE*!rrE&u
+rrDrrrW)rtrrDHd!W[b$WW)tnfDbjGh>[KMiW&rQJcFm4!!)fo!!)or!!*#u!s&B$!<3!#!<<'!
+rr2rurVlitrr2rur;Q`sr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrE&u!!',#!W[b$o`'F~>
+f`-L&joDL_!!)EdrrE#trrE&urr<9'!!*'!!!)utrrDrrrrE&u'EJ15!!*'!!!*'!!!*'!!!*'!
+!!*#urrDus#QXo)!!*'!!!)EdrW&ns!!([O!!(mU!!)$Yrr@WMjSo2[qu?Kmrr;lrs8N'!rr3'#
+s8N)urr<&trr<&urr<&srr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quEhurW)TjJ,~>
+f`-L&joDL_!!)EdrrE#trrE&urr<9'!!*'!!!)utrrDrrrrE&u'EJ15!!*'!!!*'!!!*'!!!*'!
+!!*#urrDus#QXo)!!*'!!!)EdrW&ns!!([O!!(mU!!)$Yrr@WMjSo2[qu?Kmrr;lrs8N'!rr3'#
+s8N)urr<&trr<&urr<&srr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quEhurW)TjJ,~>
+f`-L&joDL_!!)EdrrE#trrE&urr<9'!!*'!!!)utrrDrrrrE&u'EJ15!!*'!!!*'!!!*'!!!*'!
+!!*#urrDus#QXo)!!*'!!!)Ed!W[b$W;ckmf`(sHhZ!TNirB&RJcFg2!!)orq>gNpquHcs!!*#u
+!s&B$!<2uu!<)ot!<2uu!;uis!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3$"s8VusXT&>%J:R:l
+J,~>
+f`(pOJcFs6!!',#!!)EdrrE#trrE#tquHcsr;cltr;cfrr;cfrr;cisrrE*!rrE&urW)uur;Zlu
+!<)rt!<<)u!:Tse!3#nt!8.;O!8meV!9=+Z!.k10rr<&orr<&rrr<&rrr<&urrW9$rrE&u!!)rs
+!W`6#qu6Wrr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrB"trW)TjJ,~>
+f`(pOJcFs6!!',#!!)EdrrE#trrE#tquHcsr;cltr;cfrr;cfrr;cisrrE*!rrE&urW)uur;Zlu
+!<)rt!<<)u!:Tse!3#nt!8.;O!8meV!9=+Z!.k10rr<&orr<&rrr<&rrr<&urrW9$rrE&u!!)rs
+!W`6#qu6Wrr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrB"trW)TjJ,~>
+f`(pOJcFs6!!',#!!)EdrrE#trrE#tquHcsr;cltr;cfrr;cfrr;cisrrE*!rrE&urW)uur;Zlu
+!<)rt!<<)u!:Tph!.]TurrDiHrrDiOrrDiSs8VkFs5O%Y!;QQo!;lcr!;lcr!<3!#!<<'!rr2ru
+r;QfurrDrr!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!W;co!J:R:lJ,~>
+f`(pOJcFs6!!',#!!%uXrW&kr!!(^P!!(sW!!)*[rr@WMi;WcWq#:<oqu6Wrqu6Wrrr3'#s8N)u
+rr<&srrN3#!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N(ts8E#js*t~>
+f`(pOJcFs6!!',#!!%uXrW&kr!!(^P!!(sW!!)*[rr@WMi;WcWq#:<oqu6Wrqu6Wrrr3'#s8N)u
+rr<&srrN3#!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N(ts8E#js*t~>
+f`(pOJcFs6!!',#!!%uX!W[b$VuHblg&D'Ii;WfPjT#8TJcF[.!!)fo!!)or!!)or!!*#u!s&B$
+!<2uu!;uiu!<3&rrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!s&B$!3#o!!.]Uls*t~>
+f`(pOJcFs6rW',$!!%uXrW&kr!!(^P!!)!X!!)-\rr@WMhZ!QUq#:<oqZ$Kos8N'!rr2rurr3'#
+s8N)rrr<&urr<&us82lsrr<&urr<&trr<&srrW9$rrE&u!!*#u!!*#ur;`r!rW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW&kr!!(^P!!)!X!!)-\rr@WMhZ!QUq#:<oqZ$Kos8N'!rr2rurr3'#
+s8N)rrr<&urr<&us82lsrr<&urr<&trr<&srrW9$rrE&u!!*#u!!*#ur;`r!rW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:OQt!;P7I!;POQ!;P[Us7h0FhZ!QUq#:<oqZ$Kos8N'!rr2ru
+rr3'#s8N)rrr<&urr<&us82lsrr<&urr<&trr<&srrW9$rrE&u!!*#u!!*#ur;`r!!W[b$o`'F~>
+f`(pOkPt>Xdf97G^&S'3Y5\J%N;rkWVZ-VrgA_-Qir8uYjo5;\JcFO*!!([O!!%TMr;Z`ro`'F~>
+f`(pOkPt>Xdf97G^&S'3Y5\J%N;rkWVZ-VrgA_-Qir8uYjo5;\JcFO*!!([O!!%TMr;Z`ro`'F~>
+f`(pOkPt>Xdf97G^&J-6J:Og&!!%uX!W[b$VZ-YkgA_0Jir9#Rjo5>UJcFO*!!([O!!%TMr;Qfu
+J:R:lJ,~>
+f`(pOjT#5[f)PaMrVultrr2run,NCfnGiLgjo>;[Y5\J%N;rkWVZ-VrgA_-Qj8T)Zk5YG]JcFL)
+!!(^P!!%TMqu?Wqo`'F~>
+f`(pOjT#5[f)PaMrVultrr2run,NCfnGiLgjo>;[Y5\J%N;rkWVZ-VrgA_-Qj8T)Zk5YG]JcFL)
+!!(^P!!%TMqu?Wqo`'F~>
+f`(pOjT#5[f)PaMrVultrr2run,NCfnGiLgjo5A^J:Og&!!%uX!W[b$VZ-YkgA_0Jj8T,Sk5YJV
+JcFL)!!(^P!!%TMqu6]tJ:R:lJ,~>
+f`(pOjT#5[rVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;cltrrDlpr;cisrr<3%!!*'!r;cis
+rW)uurrE#tquGmZrW',$!!%uXrW&ep!!(dR!!)*[!!)3^rr@WMg&D$PJcF0urW)TjJ,~>
+f`(pOjT#5[rVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;cltrrDlpr;cisrr<3%!!*'!r;cis
+rW)uurrE#tquGmZrW',$!!%uXrW&ep!!(dR!!)*[!!)3^rr@WMg&D$PJcF0urW)TjJ,~>
+f`(pOjT#5[rVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;cltrrDlpr;cisrr<3%!!*'!r;cis
+rW)uurrE#tquGmZ!W[b$Y5\J%N;iqZJ:OKr!;P=K!;PXT!;PaWs7h0Fg&D$PJcF0u!W[b$o`'F~>
+f`(pOjT#5[rVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#6+Z's8N'!rr;uuqZ$Qqs8W*!s8W&u
+#6+Z's8N'!rr;uu%K?D.s8N'!s8N*!rr<&\s8E#$rr<%Xs8E"prr<&Rrr<&\rr<&_s8N(Ms4@8N
+!.k0us8E#js*t~>
+f`(pOjT#5[rVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#6+Z's8N'!rr;uuqZ$Qqs8W*!s8W&u
+#6+Z's8N'!rr;uu%K?D.s8N'!s8N*!rr<&\s8E#$rr<%Xs8E"prr<&Rrr<&\rr<&_s8N(Ms4@8N
+!.k0us8E#js*t~>
+f`(pOjT#5[rVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#6+Z's8N'!rr;uuqZ$Qqs8W*!s8W&u
+#6+Z's8N'!rr;uu%K?D.s8N'!s8N*!rr<&\rrN1NJ?JnP!0$pZ!.]TrrrDiKrrDiUrrDiXs8VkF
+s4@8N!.k0urrN1NJFrkl~>
+f`(pOjT#5[rVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;uuqZ$Qqs8W*!s8W*!
+s8W*!s8W*!rr;uu!ri6#rr;rtrr;uujo>;[Y5\J%N;rkWV#LDph#@?Sk5PD]l2Ub`JcF:#!!%TM
+df9:Ho`'F~>
+f`(pOjT#5[rVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;uuqZ$Qqs8W*!s8W*!
+s8W*!s8W*!rr;uu!ri6#rr;rtrr;uujo>;[Y5\J%N;rkWV#LDph#@?Sk5PD]l2Ub`JcF:#!!%TM
+df9:Ho`'F~>
+f`(pOjT#5[rVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;uuqZ$Qqs8W*!s8W*!
+s8W*!s8W*!rr;uu!ri6#rr;rtrr;uujo5A^J:Og&!!%uX!W[b$V#LGih#@BLk5PGVl2UeYJcF:#
+!!%TMdf0@KJ:R:lJ,~>
+f`(pOjT#5[rVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!rr;uuqZ$Qqs8W*!s8W*!s8W*!s8W*!
+rr;lrrr;rtrr;uujo>;[Y5\J%N;rkWV#LDph#@?SkPkM^l2L_`JcF4!!!%TMdf9:Ho`'F~>
+f`(pOjT#5[rVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!rr;uuqZ$Qqs8W*!s8W*!s8W*!s8W*!
+rr;lrrr;rtrr;uujo>;[Y5\J%N;rkWV#LDph#@?SkPkM^l2L_`JcF4!!!%TMdf9:Ho`'F~>
+f`(pOjT#5[rVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!rr;uuqZ$Qqs8W*!s8W*!s8W*!s8W*!
+rr;lrrr;rtrr;uujo5A^J:Og&!!%uX!W[b$V#LGih#@BLkPkPWl2LbYJcF4!!!%TMdf0@KJ:R:l
+J,~>
+f`(pOjT#5[rVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsrr;uuqZ$Qqs8W*!s8W*!s8W*!
+s8W*!rr;uuqu?Wqrr;uujo>;[Y5\J%N;rkWU]1;oh>[HTkl1V_lMpkaJcF0u!!)?b!!(dR!!)]l
+q>gQq!!&nrrW)TjJ,~>
+f`(pOjT#5[rVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsrr;uuqZ$Qqs8W*!s8W*!s8W*!
+s8W*!rr;uuqu?Wqrr;uujo>;[Y5\J%N;rkWU]1;oh>[HTkl1V_lMpkaJcF0u!!)?b!!(dR!!)]l
+q>gQq!!&nrrW)TjJ,~>
+f`(pOjT#5[rVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsrr;uuqZ$Qqs8W*!s8W*!s8W*!
+s8W*!rr;uuqu?Wqrr;uujo5A^J:Og&!!%uX!W[b$U]1>hh>[KMkl1YXlMpnZJcF0u!!)?b!!(dR
+!!)]lq>gQq!!&nr!W[b$o`'F~>
+f`(pOjT#5[rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;ZcsrVultrr3Z4s8N'!s8N'!s8N'!
+s8N'!s8N'!rr;uur;R$&s8N'!s8N'!jo>;[Y5a:XUAk2nhZ!QUl2L_`li6tbJcF*s!!)?b!!(dR
+!!)rs!!*#u!!)rs!!&\lrW)TjJ,~>
+f`(pOjT#5[rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;ZcsrVultrr3Z4s8N'!s8N'!s8N'!
+s8N'!s8N'!rr;uur;R$&s8N'!s8N'!jo>;[Y5a:XUAk2nhZ!QUl2L_`li6tbJcF*s!!)?b!!(dR
+!!)rs!!*#u!!)rs!!&\lrW)TjJ,~>
+f`(pOjT#5[rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;ZcsrVultrr3Z4s8N'!s8N'!s8N'!
+s8N'!s8N'!rr;uur;R$&s8N'!s8N'!jo5A^J:Og&M?*[,UAk5ghZ!TNl2LbYli7"[JcF*s!!)?b
+!!(dR!!)rs!!*#u!!)rs!!&\l!W[b$o`'F~>
+f`(pOjT#5[rVultrVucqs8W#ts8W#ts8W#trVufrrr;rtrr;osrVufrrr;uus8W*!rr;rts8W#t
+!WN/us8N*!s8E#]s8E#$rr<%Xs8E"mrr<&Urr<&arr<&cs8N(Ms3CWE!;QQo!;c`p!<<'$!<3$!
+rVuisrr3'#rr<&ts8;rss8E#trr<&urr<&ts8Duus8E#srr<&srsAc+rrE'!!<<'!!<)rs!4W"-
+!;-;A~>
+f`(pOjT#5[rVultrVucqs8W#ts8W#ts8W#trVufrrr;rtrr;osrVufrrr;uus8W*!rr;rts8W#t
+!WN/us8N*!s8E#]s8E#$rr<%Xs8E"mrr<&Urr<&arr<&cs8N(Ms3CWE!;QQo!;c`p!<<'$!<3$!
+rVuisrr3'#rr<&ts8;rss8E#trr<&urr<&ts8Duus8E#srr<&srsAc+rrE'!!<<'!!<)rs!4W"-
+!;-;A~>
+f`(pOjT#5[rVultrVucqs8W#ts8W#ts8W#trVufrrr;rtrr;osrVufrrr;uus8W*!rr;rts8W#t
+!WN/us8N*!s8E#]rrN1NJ?JnP!0$pZ!.]TorrDiNrrDiZrrDi\s8VkFs3CWE!;QQo!;c`p!<<'$
+!<3$!rVuisrr3'#rr<&ts8;rss8E#trr<&urr<&ts8Duus8E#srr<&srsAc+rrE'!!<<'!!<)rs
+!4Vt0!.]Uls*t~>
+f`(pOJcFs6rW',$!!%uXrW&Yl!!(pV!!)?b!!)Edrr@WMbl7YCq#:<oqu6Wrr;Zcss8N0$s8N)u
+rsAc+rr<'!rrE*!!<3!#!<<'!rr2ruqu6Wrr;Q`srr2rur;Q`sr;R6,s8N'!s8N'!s8N*!rrE&u
+!!'P/rW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW&Yl!!(pV!!)?b!!)Edrr@WMbl7YCq#:<oqu6Wrr;Zcss8N0$s8N)u
+rsAc+rr<'!rrE*!!<3!#!<<'!rr2ruqu6Wrr;Q`srr2rur;Q`sr;R6,s8N'!s8N'!s8N*!rrE&u
+!!'P/rW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:O?n!;PIO!;Pm[!;Ps]s7h0Fbl7YCq#:<oqu6Wrr;Zcss8N0$
+s8N)ursAc+rr<'!rrE*!!<3!#!<<'!rr2ruqu6Wrr;Q`srr2rur;Q`sr;R6,s8N'!s8N'!s8N*!
+rrE&u!!'P/!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW&Yl!!(pV!!)Bc!!)Ed!!%TMb5VGAq#:<oqu6Wrr;Q`srr2ruqu6`u
+s8N)urrW9$rrE&u!s&B$!<2uu!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)urr<&/
+s8E#js*t~>
+f`(pOJcFs6rW',$!!%uXrW&Yl!!(pV!!)Bc!!)Ed!!%TMb5VGAq#:<oqu6Wrr;Q`srr2ruqu6`u
+s8N)urrW9$rrE&u!s&B$!<2uu!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)urr<&/
+s8E#js*t~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:O?n!;PIO!;Pp\!;Ps]!;M-Fb5VGAq#:<oqu6Wrr;Q`srr2ru
+qu6`us8N)urrW9$rrE&u!s&B$!<2uu!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)u
+rr<&/rrN1NJFrkl~>
+f`(pOJcFs6rW',$!!%uXrW&Vk!!(sW!!)Ed!!)Herr@WMao;>@qu?Kmrr2rur;Q`srr2rurr;os
+s8N'!rr3'#s8N)urrN3#s82lorr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quF8,rW)Tj
+J,~>
+f`(pOJcFs6rW',$!!%uXrW&Vk!!(sW!!)Ed!!)Herr@WMao;>@qu?Kmrr2rur;Q`srr2rurr;os
+s8N'!rr3'#s8N)urrN3#s82lorr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quF8,rW)Tj
+J,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:O<m!;PLP!;Ps]!;Q!^s7h0Fao;>@qu?Kmrr2rur;Q`srr2ru
+rr;oss8N'!rr3'#s8N)urrN3#s82lorr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quF8,
+!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW&Vk!!(sW!!)He!!)Kfrr@WMa8Z,>q#:<oqu6Wrr;Q`srr3'#s8N)u
+rrW9$rrE&u!s&B$!<3!#!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrBG+rW)Tj
+J,~>
+f`(pOJcFs6rW',$!!%uXrW&Vk!!(sW!!)He!!)Kfrr@WMa8Z,>q#:<oqu6Wrr;Q`srr3'#s8N)u
+rrW9$rrE&u!s&B$!<3!#!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrBG+rW)Tj
+J,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:O<m!;PLP!;Q!^!;Q$_s7h0Fa8Z,>q#:<oqu6Wrr;Q`srr3'#
+s8N)urrW9$rrE&u!s&B$!<3!#!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrBG+
+!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW&Sj!!)!X!!)Kf!!)Ngrr@WM`W#o<q#:<oqu6Wrr;Q`srr3'#s8N)u
+rrW9$rrE&u$3:,+!<<'!!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrBG+rW)Tj
+J,~>
+f`(pOJcFs6rW',$!!%uXrW&Sj!!)!X!!)Kf!!)Ngrr@WM`W#o<q#:<oqu6Wrr;Q`srr3'#s8N)u
+rrW9$rrE&u$3:,+!<<'!!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrBG+rW)Tj
+J,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:O9l!;POQ!;Q$_!;Q'`s7h0F`W#o<q#:<oqu6Wrr;Q`srr3'#
+s8N)urrW9$rrE&u$3:,+!<<'!!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrBG+
+!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW&Sj!!)!X!!)Ng!!)Qhrr@WM_uB]:q#:<oqZ$Nps8N'!rr2rurr;lr
+!WN0!rr<&us8N'"rrE&ur;clt!!*#uquHcs!!*#u!!)ut!!)rs!s&B$!<2uu!<2uu!<3#s!4`(.
+!;-;A~>
+f`(pOJcFs6rW',$!!%uXrW&Sj!!)!X!!)Ng!!)Qhrr@WM_uB]:q#:<oqZ$Nps8N'!rr2rurr;lr
+!WN0!rr<&us8N'"rrE&ur;clt!!*#uquHcs!!*#u!!)ut!!)rs!s&B$!<2uu!<2uu!<3#s!4`(.
+!;-;A~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:O9l!;POQ!;Q'`!;Q*as7h0F_uB]:q#:<oqZ$Nps8N'!rr2ru
+rr;lr!WN0!rr<&us8N'"rrE&ur;clt!!*#uquHcs!!*#u!!)ut!!)rs!s&B$!<2uu!<2uu!<3#s
+!4`%1!.]Uls*t~>
+f`(pOJcFs6rW',$!!%uXrW'\4JH5]MJcF[.!!(II!!%WNrW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4JH5]MJcF[.!!(II!!%WNrW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6JH5]MJcF[.!!(II!!%WN!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TM!!%TMi;WcWf)P[KJcG]Lo`'F~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TM!!%TMi;WcWf)P[KJcG]Lo`'F~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!%TM!!%TMi;WcWf)P[KJc>cOJ:R:lJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TM!!%TMi;WcWJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TM!!%TMi;WcWJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!%TM!!%TMi;WcWJcF0u!W[b$o`'F~>
+g&HU'irH7^!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+g&HU'irH7^!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+g&HU'jT,=2Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!)0]!!)?b!!)Ng!s&B$!9a@^!:Tse!5AI5!;-<e!9X=\!!`H'!<<'!!;?Hk
+!6Y?@!.k10rr<%Ms3grH!;-;A~>
+f`(pOJcFs6rW',$!!)0]!!)?b!!)Ng!s&B$!9a@^!:Tse!5AI5!;-<e!9X=\!!`H'!<<'!!;?Hk
+!6Y?@!.k10rr<%Ms3grH!;-;A~>
+f`(pOJcFs6!W[b$Y5\J%k5PD]li-qbnG`Rjs8N)^rr<&frrN1NJA2$`!;-<e!9X=\!!`H'!<<'!
+!;?Hk!6Y<C!.]TNs5O%Y!.k0urrN1NJFrkl~>
+f`(pOJcFs6rW',$!!)0]!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquH9erW'\4!!)Qh
+rrD-[rrDoqrrDfnrrE&u!!)KfrrDQgrrDWirW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!)0]!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquH9erW'\4!!)Qh
+rrD-[rrDoqrrDfnrrE&u!!)KfrrDQgrrDWirW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%k5PD]r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lnc&XjJ:PB6
+!!)QhrrD-[rrDoqrrDfnrrE&u!!)KfrrDQgrrDWi!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!)fo!!)lqrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rVururW)uu
+#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uun,N@e^Ae05nc/UhrVult!ri9#r;cfrr;clt
+rW)uuqu?s$!!*'!!!*#urW)rtrrDlpr;cisrr<3%!!*'!r;cisrW)uurrE#tquH?grW%NLir8uY
+kPkM^mf34cg&LsMZ2ae'o`'F~>
+f`(pOJcFs6rW',$!!)fo!!)lqrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rVururW)uu
+#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uun,N@e^Ae05nc/UhrVult!ri9#r;cfrr;clt
+rW)uuqu?s$!!*'!!!*#urW)rtrrDlpr;cisrr<3%!!*'!r;cisrW)uurrE#tquH?grW%NLir8uY
+kPkM^mf34cg&LsMZ2ae'o`'F~>
+f`(pOJcFs6!W[b$Y5\J%q#:<oqZ$Nprr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#u
+s8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDNf!W[b$^Ae05nc/UhrVult!ri9#r;cfr
+r;cltrW)uuqu?s$!!*'!!!*#urW)rtrrDlpr;cisrr<3%!!*'!r;cisrW)uurrE#tquH?g!W[b$
+JcFa0!!)3^!!)Her;bONquF#%!W[b$o`'F~>
+f`(pOJcFs6rW',$!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!*#u!!*#u!!*#u!W`6#rr2rurr2ru
+rr;uurr3*$s8N'!rr3'#s8N)urrW9$rrE&u!!*#u"T\T&!<3&gs8E#4rr<&hs8N)ts8E#rs8N*!
+s8N)ts8N''rr<'!rr<&us8N*!s8N*!s8N''rr<'!rr<&qs8N*!s8N*!s8E!&rr<'!rr<&us8N'.
+rr<'!rr<'!rrE*!!!)TirW%NLir8uYkPkM^r;Q`srr2ruq#:<orr2rug]%6Rqu6Wrp\t3n^An04
+o`'F~>
+f`(pOJcFs6rW',$!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!*#u!!*#u!!*#u!W`6#rr2rurr2ru
+rr;uurr3*$s8N'!rr3'#s8N)urrW9$rrE&u!!*#u"T\T&!<3&gs8E#4rr<&hs8N)ts8E#rs8N*!
+s8N)ts8N''rr<'!rr<&us8N*!s8N*!s8N''rr<'!rr<&qs8N*!s8N*!s8E!&rr<'!rr<&us8N'.
+rr<'!rr<'!rrE*!!!)TirW%NLir8uYkPkM^r;Q`srr2ruq#:<orr2rug]%6Rqu6Wrp\t3n^An04
+o`'F~>
+f`(pOJcFs6!W[b$Y5\J%q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u
+!!*#urrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!:^!i!.]U6rr<&hs8N)ts8E#r
+s8N*!s8N)ts8N''rr<'!rr<&us8N*!s8N*!s8N''rr<'!rr<&qs8N*!s8N*!s8E!&rr<'!rr<&u
+s8N'.rr<'!rr<'!rrE*!!!)Ti!W[b$JcFa0!!)3^!!)rs!!*#u!!)fo!!*#u!!(dR!!)or!!)cn
+!!'b5!W[b$o`'F~>
+f`(pOJcFs6rW',$!!)fo!!)cn!!)or!!)rs!!*#u!!*#u!!*#u!s&B$!<3!#!<<'!rr2rurr2ru
+rVls"s8N)trrW9$rrE&u!s&B$!<2uu!<2uu!:0[a!5AI5!:g*h!<)rt!;lfr!<<*!!<)rt!!`H'
+!<<'!!<3#u!<<*!!<<*!!!`H'!<<'!!;c`q!<<*!!<<*!!<<*!!<<*!!<3#u!!<0#!<3#t!<3#u
+!:p0h!.k10rr<&orr<&qs8E#urr<&urr<&ts8Duus8E!!rrDusrrE&u#QXo)!<3$!s8W&urVuis
+rr;rtrVuisrr;rt!WN/ts8E#ts8E#us8E#urr<&urr<&us8E#Bs8E#js*t~>
+f`(pOJcFs6rW',$!!)fo!!)cn!!)or!!)rs!!*#u!!*#u!!*#u!s&B$!<3!#!<<'!rr2rurr2ru
+rVls"s8N)trrW9$rrE&u!s&B$!<2uu!<2uu!:0[a!5AI5!:g*h!<)rt!;lfr!<<*!!<)rt!!`H'
+!<<'!!<3#u!<<*!!<<*!!!`H'!<<'!!;c`q!<<*!!<<*!!<<*!!<<*!!<3#u!!<0#!<3#t!<3#u
+!:p0h!.k10rr<&orr<&qs8E#urr<&urr<&ts8Duus8E!!rrDusrrE&u#QXo)!<3$!s8W&urVuis
+rr;rtrVuisrr;rt!WN/ts8E#ts8E#us8E#urr<&urr<&us8E#Bs8E#js*t~>
+f`(pOJcFs6!W[b$Y5\J%q#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u
+!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&brrN1NJA2$`!:g*h!<)rt!;lfr!<<*!!<)rt
+!!`H'!<<'!!<3#u!<<*!!<<*!!!`H'!<<'!!;c`q!<<*!!<<*!!<<*!!<<*!!<3#u!!<0#!<3#t
+!<3#u!:p-k!.]TNs5O%Y!;QQo!;c`p!<<'!!<2uu!<)rs!!*&u!!3*"r;Zcsrr36(s8N*!!!*'!
+rW)osrW)rtrW)osrW)rtrW!!!!;ulr!<3#t!<<)u!<<'!!<2uu!<3#t!6kHE!.]Uls*t~>
+f`(pOJcFs6rW',$!!)orq>gKor;c`p!!)rs!!*#u!!)ut!W`6#rr2rurr3'#s8N)urr<&urr<&t
+rrW9$rrE#t!s&B$!<3!#!<<'!rr;lrli6qa^Ae05nc/UhrVultrVufrs8W*!rVucqs8W*!rr;uu
+s8W*!s8Vuss8W*!qZ$Qqs8W*!s8W*!s8W*!s8W*!rr;lrrr;rtrr;uuo)J[hJcFa0!!)fo!!)or
+!!)fo!!)rs!!*#u!!*#u!!*#u!W`6#rr3*$s8N'!rr2rurr3'#s8N)srr<&urrW9$rrDus!!)rs
+!!)rs!!*#u!!*#u!s&B$!<2uu!<3!#!<<'!aoD>?o`'F~>
+f`(pOJcFs6rW',$!!)orq>gKor;c`p!!)rs!!*#u!!)ut!W`6#rr2rurr3'#s8N)urr<&urr<&t
+rrW9$rrE#t!s&B$!<3!#!<<'!rr;lrli6qa^Ae05nc/UhrVultrVufrs8W*!rVucqs8W*!rr;uu
+s8W*!s8Vuss8W*!qZ$Qqs8W*!s8W*!s8W*!s8W*!rr;lrrr;rtrr;uuo)J[hJcFa0!!)fo!!)or
+!!)fo!!)rs!!*#u!!*#u!!*#u!W`6#rr3*$s8N'!rr2rurr3'#s8N)srr<&urrW9$rrDus!!)rs
+!!)rs!!*#u!!*#u!s&B$!<2uu!<3!#!<<'!aoD>?o`'F~>
+f`(pOJcFs6!W[b$Y5\J%qu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu
+!<)p"!<<'!rVls"s8N)urrW9$rrE&uquH'_!W[b$^Ae05nc/UhrVultrVufrs8W*!rVucqs8W*!
+rr;uus8W*!s8Vuss8W*!qZ$Qqs8W*!s8W*!s8W*!s8W*!rr;lrrr;rtrr;uuo)AakJ:N4Nir8uY
+q#:<oqu6Wrq#:<or;Q`srr2rurr2rurr3$"rrE&u"9AK%!!*#u!!*#u!s&B$!;uis!<3!#!<<'!
+r;Q`sr;Q`sr;Q`srr2rurr3'#s8N)urr<&urrW9$rrC1@!W[b$o`'F~>
+f`(pOJcFs6rW',$!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&urr<&t
+rrW9$rrE#t!s&B$!<3!#!<<'!rr2rukPtM]^Ae05nc/UhrVultrr;uu#6+Z's8N'!rVultr;Zcs
+rr;uus8W*!s8W*!r;ZcsqZ$Qqs8W*!s8W*!s8W*!s8W*!rr;uuqu?Wqrr;uuo)J[hJcFa0!!)fo
+!!)or!!)fo!!)rs!!*#u!!*#u!!*#u!<E/u!<2uu!<)ot!<3!#!<<'!r;Q`srr3'#s8N)srr<&r
+s8N)urr<&qrrW9$rrE&u!!*#u!s&B$!6P9?!;-;A~>
+f`(pOJcFs6rW',$!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&urr<&t
+rrW9$rrE#t!s&B$!<3!#!<<'!rr2rukPtM]^Ae05nc/UhrVultrr;uu#6+Z's8N'!rVultr;Zcs
+rr;uus8W*!s8W*!r;ZcsqZ$Qqs8W*!s8W*!s8W*!s8W*!rr;uuqu?Wqrr;uuo)J[hJcFa0!!)fo
+!!)or!!)fo!!)rs!!*#u!!*#u!!*#u!<E/u!<2uu!<)ot!<3!#!<<'!r;Q`srr3'#s8N)srr<&r
+s8N)urr<&qrrW9$rrE&u!!*#u!s&B$!6P9?!;-;A~>
+f`(pOJcFs6!W[b$Y5\J%q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu
+!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!)3^!W[b$^Ae05nc/UhrVultrr;uu#6+Z's8N'!rVult
+r;Zcsrr;uus8W*!s8W*!r;ZcsqZ$Qqs8W*!s8W*!s8W*!s8W*!rr;uuqu?Wqrr;uuo)AakJ:N4N
+ir8uYq#:<oqu6Wrq#:<or;Q`srr2rurr2rurr3!!s8;rsrr<&trr<&urrW9$rrDus!!*#u!s&B$
+!;uis!;lfr!<2uu!;c]t!<<'!rr2rurr3'#s8N)@rrN1NJFrkl~>
+f`(pOJcFs6rW)ZlrrCXMrrD]k!!)`m!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)s
+rrN3#!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&^s8E#4rr<&hs8N)ts8N)us8N''
+rr<'!rr<&ts8N)ss8N)us8N*!s8N*!s8N)rs8N)urtGJ5rr<'!rr<'!rr<'!rr<'!rr<&us8N)s
+rs/W)rr<'!rr<&is8E"Ls5O%Y!;lfm!<)rt!;c]q!;uis!<2uu!<)p$!<3'!rrDrr!!)ut!!*#u
+!s&B$!;ulp!<3#u!<)rt!;lcu!<<'!rVufrs8N'!rr2rurr2rurr;uubQ%PAo`'F~>
+f`(pOJcFs6rW)ZlrrCXMrrD]k!!)`m!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)s
+rrN3#!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&^s8E#4rr<&hs8N)ts8N)us8N''
+rr<'!rr<&ts8N)ss8N)us8N*!s8N*!s8N)rs8N)urtGJ5rr<'!rr<'!rr<'!rr<'!rr<&us8N)s
+rs/W)rr<'!rr<&is8E"Ls5O%Y!;lfm!<)rt!;c]q!;uis!<2uu!<)p$!<3'!rrDrr!!)ut!!*#u
+!s&B$!;ulp!<3#u!<)rt!;lcu!<<'!rVufrs8N'!rr2rurr2rurr;uubQ%PAo`'F~>
+f`(pOJcFs6!W[b$pAb0ff)PdFo`"pdpAY*mq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm$$rrE*!
+!;uiu!<3&urr<&urr<&trr`?%rr<&ursAc+rrE*!!!*'!!<2uu!9a@`!.]U6rr<&hs8N)ts8N)u
+s8N''rr<'!rr<&ts8N)ss8N)us8N*!s8N*!s8N)rs8N)urtGJ5rr<'!rr<'!rr<'!rr<'!rr<&u
+s8N)srs/W)rr<'!rr<&irrN1NJ:[a[rr<&rs7u`os8N)qrr<&srr<&urr<&trriE&!<<'!qu6Wr
+rVlitrr3'#s8N)ss82lrs8N)ts8N)rrrW9$rrE#tr;clt!!*#u!!*#u!!*#urrC7B!W[b$o`'F~>
+f`(pOJcFs6rW)]m!W`6#fDbpQs8N)ns82llrr<&orr<&qs82itrrE&uquHcs!!*#u!!)ut!s&B$
+!;c]s!<3&urrW9$rrE#t"9AK%!<<#urVult!WN0!rr<&us8;r`s8E#4rr<&hs8N)ts8N)ts82ls
+s8;rts8;rts8N)us8N*!s8N)us8;rrs8;rrs8;rss8N*!s8N)us8E#us8;ourrE#trrE*!rW)Tj
+rW%NLir8uYq#:<oq#:<oqu6Wrr;Q`srr2rurVm$$rrE*!!;lcr!<)ot!<3!#!<<'!r;Q`sq#:<o
+r;Q`sr;Qj!s8N)urr<&urrW9$rrE&u!!*#u!!)rs!!(7CrW)TjJ,~>
+f`(pOJcFs6rW)]m!W`6#fDbpQs8N)ns82llrr<&orr<&qs82itrrE&uquHcs!!*#u!!)ut!s&B$
+!;c]s!<3&urrW9$rrE#t"9AK%!<<#urVult!WN0!rr<&us8;r`s8E#4rr<&hs8N)ts8N)ts82ls
+s8;rts8;rts8N)us8N*!s8N)us8;rrs8;rrs8;rss8N*!s8N)us8E#us8;ourrE#trrE*!rW)Tj
+rW%NLir8uYq#:<oq#:<oqu6Wrr;Q`srr2rurVm$$rrE*!!;lcr!<)ot!<3!#!<<'!r;Q`sq#:<o
+r;Q`sr;Qj!s8N)urr<&urrW9$rrE&u!!*#u!!)rs!!(7CrW)TjJ,~>
+f`(pOJcFs6!W[b$p\t<is7k4G"8Morq"Ogdq"Xjh!;QQo!;c`n!!3*"rr;lrs8N'!rr2rurVls"
+s8N)qrrN3#!<3!#!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!:0Xd!.]U6rr<&hs8N)ts8N)t
+s82lss8;rts8;rts8N)us8N*!s8N)us8;rrs8;rrs8;rss8N*!s8N)us8E#us8;ourrE#trrE*!
+rW)Tj!W[b$JcFa0!!)fo!!)fo!!)or!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus
+!!)fo!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2rurr2rur;Q`sbl7_EJ:R:lJ,~>
+f`(pOJcFs6rW)Wk!!([O!!)ut!!)cnrrDcm!!%uXrW'\4!!%TMrW%NLir8uYq#:<oq#:<oqu6Wr
+r;Q`srr2rurVm$$rrE*!!;lcr!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`sr;Qj!s8N)urr<&urrW9$
+rrE&u"9AK%!!)rs!!(7CrW)TjJ,~>
+f`(pOJcFs6rW)Wk!!([O!!)ut!!)cnrrDcm!!%uXrW'\4!!%TMrW%NLir8uYq#:<oq#:<oqu6Wr
+r;Q`srr2rurVm$$rrE*!!;lcr!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`sr;Qj!s8N)urr<&urrW9$
+rrE&u"9AK%!!)rs!!(7CrW)TjJ,~>
+f`(pOJcFs6!W[b$p&>$ef`(sHrVllmp](9gpAY*mN;iqZJ:PB6!!%TM!W[b$JcFa0!!)fo!!)fo
+!!)or!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus!!)fo!!)rs!!)rs!s&B$!<2uu
+!<3!#!<<'!rr3*$s8N'!r;Q`sbl7_EJ:R:lJ,~>
+f`(pOJcFs6rW)Wk!!([O!!)ut!!)cn!W`6#p\t3nN;rkW^Ae05JcG]LJcFa0!!)fo!!)orrW)rt
+!!*#uquHcs!!*#u!!)ut!!*#u!!)or!!)rsrW)osrW)rtr;cltrW)rtrW)uur;cfr!!*#uquHcs
+!!*#urr<0$!<<)u!6bEA!;-;A~>
+f`(pOJcFs6rW)Wk!!([O!!)ut!!)cn!W`6#p\t3nN;rkW^Ae05JcG]LJcFa0!!)fo!!)orrW)rt
+!!*#uquHcs!!*#u!!)ut!!*#u!!)or!!)rsrW)osrW)rtr;cltrW)rtrW)uur;cfr!!*#uquHcs
+!!*#urr<0$!<<)u!6bEA!;-;A~>
+f`(pOJcFs6!W[b$p&>$ef`(sHrVllmp\t<is7l?g!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYq#:<o
+qu?Wqrr2rurr;lrs8N'!rr2rurVlitrr2ruqu6Wrr;Z`rrVuisrr;oss8W&urr;rts8W#trVlit
+rr;lrs8N'!rr;uu"9/B$s8E#ArrN1NJFrkl~>
+f`(pOk5PD]li-qbnG`Rjs8N)^rr<&Bs8E#krr<&Orr<&trr<&arr<%Xs8E#4rr<%Ms8E"Ls5O%Y
+!.k0us8E#js*t~>
+f`(pOk5PD]li-qbnG`Rjs8N)^rr<&Bs8E#krr<&Orr<&trr<&arr<%Xs8E#4rr<%Ms8E"Ls5O%Y
+!.k0us8E#js*t~>
+f`(pOk5PD]li-qbnG`Rjs8N)^rr<&BrrN1NJG&pBpt5THq#13mq!.kZ!0$pZ!.]U6rr<%MrrN1N
+J:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOk5PD]r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lc2[bCp&>!lf`(pOrVlitlMgha
+N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOk5PD]r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lc2[bCp&>!lf`(pOrVlitlMgha
+N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOk5PD]r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lc2RhFJ:R=m!;P4H!;QNm!;PjZ
+!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqZ$Nprr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#us8NB*rr<'!!<<'!
+s8E#trr<&urrE-"rW)rtrW)rtrrC7BrW)Wk!!([O!!)ut!!)<a!!%uXrW'\4!!%TMrW%NLir8uY
+JcF0urW)TjJ,~>
+f`(pOq#:<oqZ$Nprr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#us8NB*rr<'!!<<'!
+s8E#trr<&urrE-"rW)rtrW)rtrrC7BrW)Wk!!([O!!)ut!!)<a!!%uXrW'\4!!%TMrW%NLir8uY
+JcF0urW)TjJ,~>
+f`(pOq#:<oqZ$Nprr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#us8NB*rr<'!!<<'!
+s8E#trr<&urrE-"rW)rtrW)rtrrC7B!W[b$p&>$ef`(sHrVllmlMghaN;iqZJ:PB6!!%TM!W[b$
+JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#urrE&u"9AK%
+!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!6kKB!;6?l!8%5Q!<<'!l2L_`N;rkW^Ae05JcG]L
+JcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#urrE&u"9AK%
+!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!6kKB!;6?l!8%5Q!<<'!l2L_`N;rkW^Ae05JcG]L
+JcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#urrE&u"9AK%
+!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!6kHE!.]UmrrDiGrr`&rs7kjY!!%uX!W[b$^Ae05
+Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut!s&B$!<)p"
+!<<'!rr3'#s8N)urr<&urr<&>s8E#ms82lLs8N)trr<&urr<&hrr<&Srr<&brr<&grrW9$rrD6^
+!!)iprW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOq#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut!s&B$!<)p"
+!<<'!rr3'#s8N)urr<&urr<&>s8E#ms82lLs8N)trr<&urr<&hrr<&Srr<&brr<&grrW9$rrD6^
+!!)iprW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOq#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut!s&B$!<)p"
+!<<'!rr3'#s8N)urr<&urr<&>rrN1NJG9*Apt5WHq#13mq#:9nq!n@a!8RSS!:0Xb!:^!j!<<'!
+kPkM^q>UKrJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOqu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&uquFe;rW',$!!)Qh!!)Ed!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)fo
+quHWorW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOqu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&uquFe;rW',$!!)Qh!!)Ed!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)fo
+quHWorW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOqu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&uquFe;!W[b$Y5\J%nc&RhmJd.dr;Q`srr2rup&>!lrVlitrr2rupAY*moD\dj
+q#C6lqu6]tJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&u!!'q:rW',$!!)fo!!)rsrW)`nrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!
+rrE*!rVururW)uu#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uuq>^EopAb-mk5YG]o`"mk
+pAY*mJcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&u!!'q:rW',$!!)fo!!)rsrW)`nrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!
+rrE*!rVururW)uu#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uuq>^EopAb-mk5YG]o`"mk
+pAY*mJcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&u!!'q:!W[b$Y5\J%q#:<or;Z`rq#C<nrr2rurr2rurVuis!<<#u!WN/trs&Q(
+rrE'!s8W&u!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDlp!W[b$pAb0fk5YJV
+o`"pdpAY*mJc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&urr<&urr<&trr`?%rr<&u
+rsAc+rrE*!!!*'!!<2uu!5nj9!3Z>%!;QQo!;lcr!;QQo!<2uu!;lcr!;uis!<2uu!<2uu!<2uu
+!<3!"!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoqrW)]m
+!W`6#kPkVas8N)ns82lls+(1K!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&urr<&urr<&trr`?%rr<&u
+rsAc+rrE*!!!*'!!<2uu!5nj9!3Z>%!;QQo!;lcr!;QQo!<2uu!;lcr!;uis!<2uu!<2uu!<2uu
+!<3!"!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoqrW)]m
+!W`6#kPkVas8N)ns82lls+(1K!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&urr<&urr<&trr`?%rr<&u
+rsAc+rrE*!!!*'!!<2uu!5ng<!.]U&rr<&orr<&rrr<&orr<&urr<&rrr<&srr<&urr<&urr<&u
+rr<&urrN3#!<2uu!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!qYpTs
+J:RCo!r2fjkPkYZs8Vlgs8;Zes+(1M!<7S#s5O%Y!.k0urrN1NJFrkl~>
+f`(pOq#:<oqZ$Hn!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%rrE)u!<)rt
+!!3*"rr2rurr;osa8c,=Y5\J%q#:<oqu6Wro`"mkqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$
+rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&ls8E#krr<&_rr<&trr<&ns8N)m
+rr<%Ms8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqZ$Hn!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%rrE)u!<)rt
+!!3*"rr2rurr;osa8c,=Y5\J%q#:<oqu6Wro`"mkqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$
+rrE&u!!*#u!!)ut!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&ls8E#krr<&_rr<&trr<&ns8N)m
+rr<%Ms8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqZ$Hn!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%rrE)u!<)rt
+!!3*"rr2rurr;osa8Z2@J:Og&!!)fo!!)or!!)Zk!!)or!!)rs!!*#u!!*#u!!*#u!s&B$!<3!#
+!<<'!rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$!<2uu!<2uu!;6?n!.]UmrrDiXrrDimrrDig
+s8Vlfrr<%MrrN1NJ:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOJcFs6rW',$!!)orq>gNp!!)cnr;c`p!!)rs!!*#u!!)ut!W`6#rr2rurr3'#s8N)urr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr;lrp&G!kp&>!lkl1V_rVlitp\t9prrDfn!!%TMrW%NL
+ir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!)orq>gNp!!)cnr;c`p!!)rs!!*#u!!)ut!W`6#rr2rurr3'#s8N)urr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr;lrp&G!kp&>!lkl1V_rVlitp\t9prrDfn!!%TMrW%NL
+ir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%qu?Kmrr2rup](0lqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHEi!W[b$p&>$ekl1YXrVllmp\t<is7l?g!!%TM
+!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!)fo!!)or!!)fo!!*#u!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2runc/Rgp&>!lkl1V_rVlitlMghaJcG]LJcFa0JH3sq
+o`'F~>
+f`(pOJcFs6rW',$!!)fo!!)or!!)fo!!*#u!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2runc/Rgp&>!lkl1V_rVlitlMghaJcG]LJcFa0JH3sq
+o`'F~>
+f`(pOJcFs6!W[b$Y5\J%q#:<oqu6Wrq#:<orr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!)Qh!W[b$p&>$ekl1YXrVllmlMghaJc>cOJ:N4N
+ir=Q0ciF)ro`'F~>
+f`(pOJcFs6rW',$!!)fo!!)or!!)fo!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#!<2uu
+!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&hs8E#krr<&_rr<&trr<&arr<%Ms8E"Ls5O%Y
+!.k0us8E#js*t~>
+f`(pOJcFs6rW',$!!)fo!!)or!!)fo!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#!<2uu
+!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&hs8E#krr<&_rr<&trr<&arr<%Ms8E"Ls5O%Y
+!.k0us8E#js*t~>
+f`(pOJcFs6!W[b$Y5\J%q#:<oqu6Wrq#:<orr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&u
+rr<&urr<&trr`?%rr<&ursAc+rrE*!!!*'!!<2uu!:g'j!.]UmrrDiXrrDimrrDiZrr<%MrrN1N
+J:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOJcFs6WW;ho!!)lq!!)foqu?ct!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u!s&B$!<)p#
+!<<'!s8E#ss8N'"rrE&u!!*#ur;cNjrW)Wk!!)6_!!)ut!!)<a!!%TMrW%NLir8uYJcF0urW)Tj
+J,~>
+f`(pOJcFs6WW;ho!!)lq!!)foqu?ct!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u!s&B$!<)p#
+!<<'!s8E#ss8N'"rrE&u!!*#ur;cNjrW)Wk!!)6_!!)ut!!)<a!!%TMrW%NLir8uYJcF0urW)Tj
+J,~>
+f`(pOJcFs6!W[b$Y4qtsq#:<oqYpNqq#C6l!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#
+s8N)trr`?%rrE)u!<)rt!!3*"rr2rurr;osp&>'nJ:R=m!;PdX!;QNm!;PjZ!!%TM!W[b$JcFa0
+!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!)Edr;`YnrW)Wk!!)3^!s&B$!9sL`!.k1L!.k10rr<%Ms3grH!;-;A~>
+f`(pOJcFs6rW',$!!)Edr;`YnrW)Wk!!)3^!s&B$!9sL`!.k1L!.k10rr<%Ms3grH!;-;A~>
+f`(pOJcFs6!W[b$Y5\J%mJm+bV#LJrJ:R=m!;PaW"8Morq!%eY!.k.O!.]TNs5O%Y!.k0urrN1N
+JFrkl~>
+f`(pOJcFs6rW',$!!%uXrW)]mquGs\rrE#t!!*#u!!)Qh!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW)]mquGs\rrE#t!!*#u!!)Qh!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:RCor:oLUs7lQm!;QQn!;Q*a!!%TM!W[b$JcFa0!!%TMdf0@K
+J:R:lJ,~>
+f`(pOf)G^Mli-qbnG`Rjs8N)^rr<&Rs8E#$rr<%Xs8E#4rr<%Ms8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOf)G^Mli-qbnG`Rjs8N)^rr<&Rs8E#$rr<%Xs8E#4rr<%Ms8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOf)G^Mli-qbnG`Rjs8N)^rr<&RrrN1NJ?JnP!0$pZ!.]U6rr<%MrrN1NJ:[a[rr<%Ms3goK
+!.]Uls*t~>
+f`(pOnc&RhkPkM^r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lh>dHSY5\J%N;rkW^Ae05
+JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&RhkPkM^r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lh>dHSY5\J%N;rkW^Ae05
+JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&RhkPkM^r;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lh>[NVJ:Og&!!%uX!W[b$
+^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<or;Z`rrr;rtq#C<nrr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#us8NB*
+rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrCgRrW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0u
+rW)TjJ,~>
+f`(pOq#:<or;Z`rrr;rtq#C<nrr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#us8NB*
+rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrCgRrW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0u
+rW)TjJ,~>
+f`(pOq#:<or;Z`rrr;rtq#C<nrr2rurr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#us8NB*
+rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrCgR!W[b$Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0
+!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6Wrrr2rupAY*mrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#u
+rrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!8RVR!3Z>%!0$sW!5AI5!.k1L!.k10
+rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr2rupAY*mrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#u
+rrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!8RVR!3Z>%!0$sW!5AI5!.k1L!.k10
+rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr2rupAY*mrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#u
+rrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!8RSU!.]U&rr<%XrrN1NJA2$`!.k.O
+!.]TNs5O%Y!.k0urrN1NJFrkl~>
+f`(pOq#:<oqu6Wrrr2ruo)A[iqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut
+!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&Ns8E#$rr<%Xs8E#4rr<&drr<&<rr<&ls7u`qrr<&`
+s8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqu6Wrrr2ruo)A[iqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut
+!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&Ns8E#$rr<%Xs8E#4rr<&drr<&<rr<&ls7u`qrr<&`
+s8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqu6Wrrr2ruo)A[iqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut
+!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&NrrN1NJ?JnP!0$pZ!.]U6rr<&drr<&<rr<&ls7u`q
+rr<&`rrN1NJ:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOqu?Kmrr2rurVultp](0lqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&uquG@KrW',$!!%uXrW'\4!!)Qh!!)'Z!!(sW!!)rs!!*#u!!)rs
+!!)'ZrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOqu?Kmrr2rurVultp](0lqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&uquG@KrW',$!!%uXrW'\4!!)Qh!!)'Z!!(sW!!)rs!!*#u!!)rs
+!!)'ZrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOqu?Kmrr2rurVultp](0lqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&uquG@K!W[b$Y5\J%N;iqZJ:PB6!!)Qh!!)'Z!!(sW!!)rs!!*#u
+!!)rs!!)'Z!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6Wrqu6Wrq>UEprr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&u!!(LJrW',$!!%uXrW'\4!!)fo!!)rsrW)uu$3:,+!<3$!s8N'!
+rVuisrVuis!<<#urr;rtrr33'rr<'!rr<&urrE-"rW)rt!!*#u!!)utrVururW)os!!)rs$3:,+
+!<3$!s8N'!rVuisqZ$NpJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrqu6Wrq>UEprr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&u!!(LJrW',$!!%uXrW'\4!!)fo!!)rsrW)uu$3:,+!<3$!s8N'!
+rVuisrVuis!<<#urr;rtrr33'rr<'!rr<&urrE-"rW)rt!!*#u!!)utrVururW)os!!)rs$3:,+
+!<3$!s8N'!rVuisqZ$NpJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrqu6Wrq>UEprr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&u!!(LJ!W[b$Y5\J%N;iqZJ:PB6!!)fo!!)rsrW)uu$3:,+!<3$!
+s8N'!rVuisrVuis!<<#urr;rtrr33'rr<'!rr<&urrE-"rW)rt!!*#u!!)utrVururW)os!!)rs
+$3:,+!<3$!s8N'!rVuisqYpTsJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqu6Wrqu6Wrq>UEprr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&urr<&urr<&t
+rr`?%rr<&ursAc+rrE*!!!*'!!<2uu!7UuI!3Z>%!0$rh!;QQo!;lcr!<3!.!<<'!!<<'!!<<'!
+s8N)urrW9$rrDus!!*#u!!*#u%flY0!!*'!!!*'!!<<'!!<2uu!;lcr!;uis!<2uu!;uis!;uj,
+!<<'!!<<'!!<<'!s8N)urr<&rs8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqu6Wrqu6Wrq>UEprr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&urr<&urr<&t
+rr`?%rr<&ursAc+rrE*!!!*'!!<2uu!7UuI!3Z>%!0$rh!;QQo!;lcr!<3!.!<<'!!<<'!!<<'!
+s8N)urrW9$rrDus!!*#u!!*#u%flY0!!*'!!!*'!!<<'!!<2uu!;lcr!;uis!<2uu!;uis!;uj,
+!<<'!!<<'!!<<'!s8N)urr<&rs8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqu6Wrqu6Wrq>UEprr2ruqu6Wrr;Q`srr2rurVm$$rrE*!!;uiu!<3&urr<&urr<&t
+rr`?%rr<&ursAc+rrE*!!!*'!!<2uu!7UrL!.]U&rr<%XrrN1NJA1dY!;QQo!;lcr!<3!.!<<'!
+!<<'!!<<'!s8N)urrW9$rrDus!!*#u!!*#u%flY0!!*'!!!*'!!<<'!!<2uu!;lcr!;uis!<2uu
+!;uis!;uj,!<<'!!<<'!!<<'!s8N)urr<&rrrN1NJ:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOq#:<oqYpTss8W&up](-k!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%
+rrE)u!<)rt!!3*"rr2rurr;osfDkgMY5a:X^Ae05q#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrE&u
+!s&B$!;uis!;c]t!<<'!rr2rurr3'#s8N)trr<&rrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u
+!s&B$!<2uu!;lfq!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqYpTss8W&up](-k!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%
+rrE)u!<)rt!!3*"rr2rurr;osfDkgMY5a:X^Ae05q#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrE&u
+!s&B$!;uis!;c]t!<<'!rr2rurr3'#s8N)trr<&rrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u
+!s&B$!<2uu!;lfq!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqYpTss8W&up](-k!WN0!s82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%
+rrE)u!<)rt!!3*"rr2rurr;osfDbmPJ:Og&M?*[,^Ae05q#:<oqu6Wrrr3'#s8N)urr<&urrW9$
+rrE&u!s&B$!;uis!;c]t!<<'!rr2rurr3'#s8N)trr<&rrr<&srr<&urr<&srr<&srrW9$rrE&u
+!!*#u!s&B$!<2uu!;lct!.]TNs5O%Y!.k0urrN1NJFrkl~>
+f`(pOkPtJ\LB%5QY5\J%N;rkW^Ae05qu?Kmrr2rurr3'#s8N)urr<&urrN3#s82lrs8N)urr<&t
+s8;rtrr<&urr<&urrW9$rrE#t!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!"!<<)s!;lfq
+!.k10rr<%Ms3grH!;-;A~>
+f`(pOkPtJ\LB%5QY5\J%N;rkW^Ae05qu?Kmrr2rurr3'#s8N)urr<&urrN3#s82lrs8N)urr<&t
+s8;rtrr<&urr<&urrW9$rrE#t!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!"!<<)s!;lfq
+!.k10rr<%Ms3grH!;-;A~>
+f`(pOkPtJ\LAq;TJ:Og&!!%uX!W[b$^Ae05qu?Kmrr2rurr3'#s8N)urr<&urrN3#s82lrs8N)u
+rr<&ts8;rtrr<&urr<&urrW9$rrE#t!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!"!<<)s
+!;lct!.]TNs5O%Y!.k0urrN1NJFrkl~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)or!!*#u!s&B$!<2uu!<3!#!<<'!q#:Ers8N)urr<&u
+rrW9$rrE&u!!*#u!s&B$!<)ot!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)ns8E"L
+s5O%Y!.k0us8E#js*t~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)or!!*#u!s&B$!<2uu!<3!#!<<'!q#:Ers8N)urr<&u
+rrW9$rrE&u!!*#u!s&B$!<)ot!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)ns8E"L
+s5O%Y!.k0us8E#js*t~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!)fo!!)or!!*#u!s&B$!<2uu!<3!#!<<'!q#:Ers8N)u
+rr<&urrW9$rrE&u!!*#u!s&B$!<)ot!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)n
+rrN1NJ:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)or!!*#u!s&B$!<2uu!<3!#!<<'!q#:Ers8N)urr<&u
+rrW9$rrE&u!!*#u"9AK%!!*#u!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!p](3m
+JcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)or!!*#u!s&B$!<2uu!<3!#!<<'!q#:Ers8N)urr<&u
+rrW9$rrE&u!!*#u"9AK%!!*#u!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!p](3m
+JcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!)fo!!)or!!*#u!s&B$!<2uu!<3!#!<<'!q#:Ers8N)u
+rr<&urrW9$rrE&u!!*#u"9AK%!!*#u!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!
+p\t9pJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)lq"p"]'!<<'!rr2rurr2rurr;oss8W&urVlitrr;lr
+!WN0!rr<&urr`?%rrE)u!<2uu!<3#r!<<'!!<2uu!<)ot!;uj!!<<'!rr2rurr2rurr;osqu?Wq
+JcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)lq"p"]'!<<'!rr2rurr2rurr;oss8W&urVlitrr;lr
+!WN0!rr<&urr`?%rrE)u!<2uu!<3#r!<<'!!<2uu!<)ot!;uj!!<<'!rr2rurr2rurr;osqu?Wq
+JcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!)fo!!)lq"p"]'!<<'!rr2rurr2rurr;oss8W&urVlit
+rr;lr!WN0!rr<&urr`?%rrE)u!<2uu!<3#r!<<'!!<2uu!<)ot!;uj!!<<'!rr2rurr2rurr;os
+qu6]tJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!'\3!!((>rW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!'\3!!((>rW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!'\3!!((>!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!'\3!!((>rW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!'\3!!((>rW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!'\3!!((>!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOmJd.daT)):s8N'!mJd.dg]%6Rr;Z`rY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOmJd.daT)):s8N'!mJd.dg]%6Rr;Z`rY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOmJd.daT)):s8N'!mJd.dg]%6Rr;QfuJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u
+!W[b$o`'F~>
+f`(pOnc&Rh_>aK8kPkM^q#:<ojo5;\r;Z`rY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&Rh_>aK8kPkM^q#:<ojo5;\r;Z`rY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&Rh_>aK8kPkM^q#:<ojo5;\r;QfuJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u
+!W[b$o`'F~>
+f`(pOq#:<or;Z`rs8NE+s8N*!!!*'!!!)utrW)]mrW)uu!<E0!!<)rs!<3!#!<3$!rr2rur;Q`s
+r;R*(s8N*!!!*'!!!)utrW)rt#QXo)!<3$!s8W&urr;rtrr3!!s8E#rrrE-"rW)rt!!)rsrW',$
+!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOq#:<or;Z`rs8NE+s8N*!!!*'!!!)utrW)]mrW)uu!<E0!!<)rs!<3!#!<3$!rr2rur;Q`s
+r;R*(s8N*!!!*'!!!)utrW)rt#QXo)!<3$!s8W&urr;rtrr3!!s8E#rrrE-"rW)rt!!)rsrW',$
+!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOq#:<or;Z`rs8NE+s8N*!!!*'!!!)utrW)]mrW)uu!<E0!!<)rs!<3!#!<3$!rr2rur;Q`s
+r;R*(s8N*!!!*'!!!)utrW)rt#QXo)!<3$!s8W&urr;rtrr3!!s8E#rrrE-"rW)rt!!)rs!W[b$
+Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6Wrrr3H.s8N'!s8N'!s8N*!rrE&u!!)ip!!)rsrrE&u!s&B$!<3!'!<<'!!<<'!
+q>UEpr;R6,s8N'!s8N'!s8N*!rrE&u%06G.!<<'!!<<'!s8N)urr<&urr`?%rr<&urr<&urrN3#
+!<3!#!<<'!r;Z`rY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrrr3H.s8N'!s8N'!s8N*!rrE&u!!)ip!!)rsrrE&u!s&B$!<3!'!<<'!!<<'!
+q>UEpr;R6,s8N'!s8N'!s8N*!rrE&u%06G.!<<'!!<<'!s8N)urr<&urr`?%rr<&urr<&urrN3#
+!<3!#!<<'!r;Z`rY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Wrrr3H.s8N'!s8N'!s8N*!rrE&u!!)ip!!)rsrrE&u!s&B$!<3!'!<<'!!<<'!
+q>UEpr;R6,s8N'!s8N'!s8N*!rrE&u%06G.!<<'!!<<'!s8N)urr<&urr`?%rr<&urr<&urrN3#
+!<3!#!<<'!r;QfuJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrE&u!!)ip!!)rs!!)ut!!)or!s&B$!<2uu!;ZWp
+!;uj!!<<'!rr2rurr3'#s8N)urrrK'rrE*!!<3!#!<<'!rr2rurr3'#s8N)trr<&urr<&srrW9$
+rrDusrW',$!!%uXrW'\4!!)0]!!)?b!!)Ng!s&B$!9a@^!9F1Z!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrE&u!!)ip!!)rs!!)ut!!)or!s&B$!<2uu!;ZWp
+!;uj!!<<'!rr2rurr3'#s8N)urrrK'rrE*!!<3!#!<<'!rr2rurr3'#s8N)trr<&urr<&srrW9$
+rrDusrW',$!!%uXrW'\4!!)0]!!)?b!!)Ng!s&B$!9a@^!9F1Z!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrE&u!!)ip!!)rs!!)ut!!)or!s&B$!<2uu!;ZWp
+!;uj!!<<'!rr2rurr3'#s8N)urrrK'rrE*!!<3!#!<<'!rr2rurr3'#s8N)trr<&urr<&srrW9$
+rrDus!W[b$Y5\J%N;iqZJ:PB6!!)0]!!)?b!!)Ng!s&B$!9a@^!9F.]!.]TNs5O%Y!.k0urrN1N
+JFrkl~>
+f`(pOqu?Kmrr2rurr3'#s8N)urr<&urrN3#s82lls8N)urr<&trr<&us8;rtrr<&urr<&prr<&s
+rrW9$rrE&u!!*#u!W`9#quHcs!s&B$!<3!#!<<'!rr;lrs8N'!r;QfurrE&ur;clt!!)rsrW',$
+!!%uXrW'\4!!)0]!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquGmZrW%NLir8uYJcF0u
+rW)TjJ,~>
+f`(pOqu?Kmrr2rurr3'#s8N)urr<&urrN3#s82lls8N)urr<&trr<&us8;rtrr<&urr<&prr<&s
+rrW9$rrE&u!!*#u!W`9#quHcs!s&B$!<3!#!<<'!rr;lrs8N'!r;QfurrE&ur;clt!!)rsrW',$
+!!%uXrW'\4!!)0]!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquGmZrW%NLir8uYJcF0u
+rW)TjJ,~>
+f`(pOqu?Kmrr2rurr3'#s8N)urr<&urrN3#s82lls8N)urr<&trr<&us8;rtrr<&urr<&prr<&s
+rrW9$rrE&u!!*#u!W`9#quHcs!s&B$!<3!#!<<'!rr;lrs8N'!r;QfurrE&ur;clt!!)rs!W[b$
+Y5\J%N;iqZJ:PB6!!)0]!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquGmZ!W[b$JcFa0
+!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrDWi!s&B$!<)p"!<<'!rr3'#s8N)urr<&prr<&s
+rrW9$rrE&u!!*#u!s&B$!;lcu!<<'!rr3'#s8N)urr<&rrr<&srriE&!<<'!rr3'#s8N)ss8E#$
+rr<%Xs8E#4rr<&orr<&qs8E#trr<&urr<&ts8Duus8E!!rrDus#6=f(!<3'!s8Duus8E#urs8]*
+!!*$!s8N*!rW)rt!!*#u!<E0!!<3#t!<3#u!9F1Z!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrDWi!s&B$!<)p"!<<'!rr3'#s8N)urr<&prr<&s
+rrW9$rrE&u!!*#u!s&B$!;lcu!<<'!rr3'#s8N)urr<&rrr<&srriE&!<<'!rr3'#s8N)ss8E#$
+rr<%Xs8E#4rr<&orr<&qs8E#trr<&urr<&ts8Duus8E!!rrDus#6=f(!<3'!s8Duus8E#urs8]*
+!!*$!s8N*!rW)rt!!*#u!<E0!!<3#t!<3#u!9F1Z!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrDWi!s&B$!<)p"!<<'!rr3'#s8N)urr<&prr<&s
+rrW9$rrE&u!!*#u!s&B$!;lcu!<<'!rr3'#s8N)urr<&rrr<&srriE&!<<'!rr3'#s8N)srrN1N
+J?JnP!0$pZ!.]U6rr<&orr<&qs8E#trr<&urr<&ts8Duus8E!!rrDus#6=f(!<3'!s8Duus8E#u
+rs8]*!!*$!s8N*!rW)rt!!*#u!<E0!!<3#t!<3#u!9F.]!.]TNs5O%Y!.k0urrN1NJFrkl~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrDWi"9AK%!!*#u!s&B$!<3!#!<<'!rr2ruq>UEp
+r;Qj!s8N)urr<&urrW9$rrDrr!s&B$!<3!#!<<'!rr2ruqu6Wrr;Qp#rrE*!!<3!#!<<'!r;Z`r
+Y5\J%N;rkW^Ae05q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#u
+rrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!9O7[!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrDWi"9AK%!!*#u!s&B$!<3!#!<<'!rr2ruq>UEp
+r;Qj!s8N)urr<&urrW9$rrDrr!s&B$!<3!#!<<'!rr2ruqu6Wrr;Qp#rrE*!!<3!#!<<'!r;Z`r
+Y5\J%N;rkW^Ae05q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#u
+rrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!9O7[!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu6Wrrr3'#s8N)urr<&urrW9$rrDWi"9AK%!!*#u!s&B$!<3!#!<<'!rr2ruq>UEp
+r;Qj!s8N)urr<&urrW9$rrDrr!s&B$!<3!#!<<'!rr2ruqu6Wrr;Qp#rrE*!!<3!#!<<'!r;Qfu
+J:Og&!!%uX!W[b$^Ae05q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u
+!!*#urrE&u"9AK%!!*#u!s&B$!<3!#!<<'!rr2rurr3-%s8N*!!9O4^!.]TNs5O%Y!.k0urrN1N
+JFrkl~>
+f`(pOq#:<oqYpa"s8N*!rrE&u!!*#u!!*#ur;cZnrW)rt!<E0!!<)rq!!3*"rr3'#s8N)srr<&s
+rrW9$rrE&u!!*#u!!*#ur;clt!s&B$!<2uu!<2uu!<3#s!<<'!!;lcr!<)rq!!3*"r;Z`rY5\J%
+N;rkW^Ae05q#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut!s&B$
+!<)p"!<<'!rr3'#s8N)urr<&urr<&Ws8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqYpa"s8N*!rrE&u!!*#u!!*#ur;cZnrW)rt!<E0!!<)rq!!3*"rr3'#s8N)srr<&s
+rrW9$rrE&u!!*#u!!*#ur;clt!s&B$!<2uu!<2uu!<3#s!<<'!!;lcr!<)rq!!3*"r;Z`rY5\J%
+N;rkW^Ae05q#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut!s&B$
+!<)p"!<<'!rr3'#s8N)urr<&urr<&Ws8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOq#:<oqYpa"s8N*!rrE&u!!*#u!!*#ur;cZnrW)rt!<E0!!<)rq!!3*"rr3'#s8N)srr<&s
+rrW9$rrE&u!!*#u!!*#ur;clt!s&B$!<2uu!<2uu!<3#s!<<'!!;lcr!<)rq!!3*"r;QfuJ:Og&
+!!%uX!W[b$^Ae05q#:<op\t3nqu6Wrr;Q`srr2rurr2rurr3'#s8N)urrW9$rrE&u!!*#u!!)ut
+!s&B$!<)p"!<<'!rr3'#s8N)urr<&urr<&WrrN1NJ:[a[rr<%Ms3goK!.]Uls*t~>
+f`(pOf`1mMq>UEpT)\ciY5\J%N;rkW^Ae05qu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u
+!s&B$!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquG[TrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOf`1mMq>UEpT)\ciY5\J%N;rkW^Ae05qu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u!!*#u
+!s&B$!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquG[TrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOf`1mMq>UEpT)SilJ:Og&!!%uX!W[b$^Ae05qu?KmrVufrqu6Wrr;Q`srr2rurVlp!rrE&u
+!!*#u!s&B$!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquG[T!W[b$JcFa0!!%TMdf0@K
+J:R:lJ,~>
+f`(pObl7YCT)\ciY5\J%N;rkW^Ae05q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!(gSrW%NLir8uYJcF0urW)TjJ,~>
+f`(pObl7YCT)\ciY5\J%N;rkW^Ae05q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!(gSrW%NLir8uYJcF0urW)TjJ,~>
+f`(pObl7YCT)SilJ:Og&!!%uX!W[b$^Ae05q#:<oqu6Wrrr2ruqu6Wrr;Q`srr2rurVm!#rrE*!
+q>^Qr!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!(gS!W[b$JcFa0!!%TMdf0@KJ:R:l
+J,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#
+!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&Ss8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#
+!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&Ss8E"Ls5O%Y!.k0us8E#js*t~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!)fo!!)or!!*#u!!)or!!)rs!!*#u!!)ut"T\Q&s8N)s
+rrN3#!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&SrrN1NJ:[a[rr<%Ms3goK!.]Ul
+s*t~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)lqqu?ct!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u
+!s&B$!<)p#!<<'!s8E#ss8N'"rrE&u!!*#ur;bdUrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!)fo!!)lqqu?ct!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u
+!s&B$!<)p#!<<'!s8E#ss8N'"rrE&u!!*#ur;bdUrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!)fo!!)lqqu?ct!<3#r!<<'!!<2uu!<)p"!<<'!qYpTs
+rrE&u!s&B$!<)p#!<<'!s8E#ss8N'"rrE&u!!*#ur;bdU!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pO^]433!<;lqli-qbcN!kDY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pO^]433!<;lqli-qbcN!kDY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pO^]433!<;lqli-qbcMmqGJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pO_#FB7q#:<olMpb^d/X(FY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pO_#FB7q#:<olMpb^d/X(FY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pO_#FB7q#:<olMpb^d/O.IJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqu6Zss8E#ss8E!$rrE*!!<2uu!<3#t!<2uu!<2uu!<3#t!<2uu!<2uu!;HKn!;uj#
+!<3$!s8W&urVuisrr;uucN!kDY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Zss8E#ss8E!$rrE*!!<2uu!<3#t!<2uu!<2uu!<3#t!<2uu!<2uu!;HKn!;uj#
+!<3$!s8W&urVuisrr;uucN!kDY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6Zss8E#ss8E!$rrE*!!<2uu!<3#t!<2uu!<2uu!<3#t!<2uu!<2uu!;HKn!;uj#
+!<3$!s8W&urVuisrr;uucMmqGJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqu?Zrrr3'#s8N)us8N*!rr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2ruqu6Wrp\t3n
+r;Zcsrr2rurr3'#s8N)urriE&rrE'!ci<tEY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu?Zrrr3'#s8N)us8N*!rr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2ruqu6Wrp\t3n
+r;Zcsrr2rurr3'#s8N)urriE&rrE'!ci<tEY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu?Zrrr3'#s8N)us8N*!rr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2ruqu6Wrp\t3n
+r;Zcsrr2rurr3'#s8N)urriE&rrE'!ci4%HJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u
+!W[b$o`'F~>
+f`(pOq#:<oqu6WrrVls"s8N)trrW9$rrE&u!s&B$!<3!#!<<'!rr3'#s8N)urr<&rrr<&nrr<&s
+rr<&trr<&urrW9$rrE&u!!(1ArW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOq#:<oqu6WrrVls"s8N)trrW9$rrE&u!s&B$!<3!#!<<'!rr3'#s8N)urr<&rrr<&nrr<&s
+rr<&trr<&urrW9$rrE&u!!(1ArW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOq#:<oqu6WrrVls"s8N)trrW9$rrE&u!s&B$!<3!#!<<'!rr3'#s8N)urr<&rrr<&nrr<&s
+rr<&trr<&urrW9$rrE&u!!(1A!W[b$Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:l
+J,~>
+f`(pOqu?Kmrr2rurVls"s8N)trrW9$rrE&u!W`9#quHcs!!*#u!W`9#quHWo!!)rs!!)ut!!)rs
+!!)utquHcsquFn>rW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOqu?Kmrr2rurVls"s8N)trrW9$rrE&u!W`9#quHcs!!*#u!W`9#quHWo!!)rs!!)ut!!)rs
+!!)utquHcsquFn>rW',$!!%uXrW'\4!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOqu?Kmrr2rurVls"s8N)trrW9$rrE&u!W`9#quHcs!!*#u!W`9#quHWo!!)rs!!)ut!!)rs
+!!)utquHcsquFn>!W[b$Y5\J%N;iqZJ:PB6!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOq#:<oqu6WrrVls"s8N)trrW9$rrE&u!s&B$!;lcr!<3!#!<<'!p\t3nr;Q`srVlitr;Q`s
+rVlitqu6Wr`rH#<Y5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6WrrVls"s8N)trrW9$rrE&u!s&B$!;lcr!<3!#!<<'!p\t3nr;Q`srVlitr;Q`s
+rVlitqu6Wr`rH#<Y5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOq#:<oqu6WrrVls"s8N)trrW9$rrE&u!s&B$!;lcr!<3!#!<<'!p\t3nr;Q`srVlitr;Q`s
+rVlitqu6Wr`r?)?J:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOq#:<oqu?Zrrr3'#s8N)us8N*!rs&Q(rr<'!rrDrr#6=f(!!*'!!;?Em!<)ot!<)ot!;uis
+!<)ot!;lcr!65'<!3Z>%!0$sW!5AI5!.k1L!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu?Zrrr3'#s8N)us8N*!rs&Q(rr<'!rrDrr#6=f(!!*'!!;?Em!<)ot!<)ot!;uis
+!<)ot!;lcr!65'<!3Z>%!0$sW!5AI5!.k1L!.k10rr<%Ms3grH!;-;A~>
+f`(pOq#:<oqu?Zrrr3'#s8N)us8N*!rs&Q(rr<'!rrDrr#6=f(!!*'!!;?Em!<)ot!<)ot!;uis
+!<)ot!;lcr!65$?!.]U&rr<%XrrN1NJA2$`!.k.O!.]TNs5O%Y!.k0urrN1NJFrkl~>
+f`(pOq#:<oqu6Zss8E#ss8E!!rrE&urr<*"!<3#s!<3#u!!3*"rr;oss8N'!r;ZZprVlitr;Q`s
+r;Z]qrr;osb5_G@Y5\J%N;rkW^Ai`ar;_EKir8uYJcF0urW)TjJ,~>
+f`(pOq#:<oqu6Zss8E#ss8E!!rrE&urr<*"!<3#s!<3#u!!3*"rr;oss8N'!r;ZZprVlitr;Q`s
+r;Z]qrr;osb5_G@Y5\J%N;rkW^Ai`ar;_EKir8uYJcF0urW)TjJ,~>
+f`(pOq#:<oqu6Zss8E#ss8E!!rrE&urr<*"!<3#s!<3#u!!3*"rr;oss8N'!r;ZZprVlitr;Q`s
+r;Z]qrr;osb5VMCJ:Og&!!%uX!W[b$^Ai`arrE(LJcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOnc&Rhp&>!lLB%5QY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&Rhp&>!lLB%5QY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&Rhp&>!lLAq;TJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOnc&Rhp&>!lLB%5QY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&Rhp&>!lLB%5QY5\J%N;rkW^Ae05JcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOnc&Rhp&>!lLAq;TJ:Og&!!%uX!W[b$^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW',$L]G0h!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW',$L]G0h!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$Y5a@Zs+%i`!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW'#!MZCKk!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW'#!MZCKk!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$X8e*.^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW'#!MZCKk!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW'#!MZCKk!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$X8e*.^Ae05Jc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcFa0!!%TMdf9:Ho`'F~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcFa0!!%TMdf0@KJ:R:lJ,~>
+f`(pOJcFs6rW%NLoD\jlrr@]O!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW%NLoD\kWs$25:!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$JcG?A!^QcNKDtoOJc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW%NLoD\jlrr@]O!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW%NLoD\kWs$25:!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$JcG?A!^QcNKDtoOJc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+f`(pOJcFs6rW%NLoD\jlrr@]O!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6rW%NLoD\kWs$25:!!%TMrW%NLir8uYJcF0urW)TjJ,~>
+f`(pOJcFs6!W[b$JcG?A!^QcNKDtoOJc>cOJ:N4Nir8uYJcF0u!W[b$o`'F~>
+g&HU'irFZ1o`"mkrr2ruK`;#PJcG]LJcFa0JH3sqo`'F~>
+g&HU'irFZ1o`"nVrr2s`K`;#PJcG]LJcFa0JH3sqo`'F~>
+g&HU'jT,=2JcGBB!'pP`!'l5;!!%TM!W[b$JcFa0JH4$ss+'bAJ,~>
+f`(pOJcFs6rW%NLo`"mkrr2ruK`;#PJcG]LJcFX-JH4'to`'F~>
+f`(pOJcFs6rW%NLo`"nVrr2s`K`;#PJcG]LJcFX-JH4'to`'F~>
+f`(pOJcFs6!W[b$JcGBB!'pP`!'l5;!!%TM!W[b$JcFX-JUl-uo`'F~>
+f`(pOJcFs6rW%NLo`"mkrr2ruK`;#PJcG]LJcFX-JH4'to`'F~>
+f`(pOJcFs6rW%NLo`"nVrr2s`K`;#PJcG]LJcFX-JH4'to`'F~>
+f`(pOJcFs6!W[b$JcGBB!'pP`!'l5;!!%TM!W[b$JcFX-JUl-uo`'F~>
+f`(pOJcFs6rW%NLp&>!lr;Q`sL&V,QJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLp&>"Wr;Qa^L&V,QJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcGEC!'pJ^!'l8<!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLp&>!lr;Q`sL&V,QJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLp&>"Wr;Qa^L&V,QJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcGEC!'pJ^!'l8<!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLp&>!lr;Q`sL&V,QJcG]LJcCW-rW&JgJ,~>
+f`(pOJcFs6rW%NLp&>"Wr;Qa^L&V,QJcG]LJcCW-rW&JgJ,~>
+f`(pOJcFs6!W[b$JcGEC!'pJ^!'l8<!!%TM!W[b$JcCW-rqN#`J,~>
+f`(pOJcFs6rW%NLpAY*mqYpNqLAq5RJcG]LJcDPGrrD]k!!)cnrW&JgJ,~>
+f`(pOJcFs6rW%NLpAY+XqYpO\LAq5RJcG]LJcDPGrrD]k!!)cnrW&JgJ,~>
+f`(pOJcFs6!W[b$JcGHD!'pD\!'l;=!!%TM!W[b$JcDPGs7l6d!;Q<grqN#`J,~>
+f`(pOJcFs6rW%NLpAY*mqYpNqLAq5RJcG]LJcDSH!s&B$!;HNk!;c]u!<3'!!1j.?~>
+f`(pOJcFs6rW%NLpAY+XqYpO\LAq5RJcG]LJcDSH!s&B$!;HNk!;c]u!<3'!!1j.?~>
+f`(pOJcFs6!W[b$JcGHD!'pD\!'l;=!!%TM!W[b$JcDSH"8Morq"Ogdq"k!nq#C-hpmqG8~>
+f`(pOJcFs6rW%NLpAY*mqYpNqLAq5RJcG]LJcDVI!!)ut!!)cnrrDio"9AH%rrAViJ,~>
+f`(pOJcFs6rW%NLpAY+XqYpO\LAq5RJcG]LJcDVI!!)ut!!)cnrrDio"9AH%rrAViJ,~>
+f`(pOJcFs6!W[b$JcGHD!'pD\!'l;=!!%TM!W[b$JcDVI!;QNm!;Q<gs7lBh"Si#ls7i/bJ,~>
+f`(pOJcFs6rW%NLp\t3nq#:<oL]7>SJcG]LJcDVI!!)ut!!)cn!W`6#qYpa"s8N*!rrAYjJ,~>
+f`(pOJcFs6rW%NLp\t4Yq#:=ZL]7>SJcG]LJcDVI!!)ut!!)cn!W`6#qYpa"s8N*!rrAYjJ,~>
+f`(pOJcFs6!W[b$JcGKE!'p>Z!'l>>!!%TM!W[b$JcDVI!;QNm!;Q<g!r2fjqYpcps8Vlos7i2c
+J,~>
+f`(pOJcFs6rW%NLp\t3nq#:<oL]7>SJcG]LJcDVI!!)ut!!)Ed"p"]'!<<'!T)X<~>
+f`(pOJcFs6rW%NLp\t4Yq#:=ZL]7>SJcG]LJcDVI!!)ut!!)Ed"p"]'!<<'!T)X<~>
+f`(pOJcFs6!W[b$JcGKE!'p>Z!'l>>!!%TM!W[b$JcDVI!;QNm!;Ps]#5J5uq#CBhT)X<~>
+f`(pOJcFs6rW%NLp\t3nq#:<oL]7>SJcG]LJcDVI!!)ut!!)Ed"p"]'!<<'!T)X<~>
+f`(pOJcFs6rW%NLp\t4Yq#:=ZL]7>SJcG]LJcDVI!!)ut!!)Ed"p"]'!<<'!T)X<~>
+f`(pOJcFs6!W[b$JcGKE!'p>Z!'l>>!!%TM!W[b$JcDVI!;QNm!;Ps]#5J5uq#CBhT)X<~>
+f`(pOJcFs6rW%NLq#:<opAY*mM#RGTJcG]LJcDVI!!)ut!!)He!!*#u!!*#u!!&YkJ,~>
+f`(pOJcFs6rW%NLq#:=ZpAY+XM#RGTJcG]LJcDVI!!)ut!!)He!!*#u!!*#u!!&YkJ,~>
+f`(pOJcFs6!W[b$JcGNF!'p8X!'lA?!!%TM!W[b$JcDVI!;QNm!;Q!^!;QQn!;QQn!;N2dJ,~>
+f`(pOJcFs6rW%NLq#BsdM#RGTJcG]LJcDSH!s&B$!:Bdd!<2uu!<2uu!2':A~>
+f`(pOJcFs6rW%NLq#BtOM#RGTJcG]LJcDSH!s&B$!:Bdd!<2uu!<2uu!2':A~>
+f`(pOJcFs6!W[b$JcGNFoK\64!!%TM!W[b$JcDSH"8Morq!J(]q#:9nq#:9npn.S:~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcDPGrrE#t!!*#u!!)`m!!)ut!!)ut!!&\lJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcDPGrrE#t!!*#u!!)`m!!)ut!!)ut!!&\lJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcDPGs7lQm!;QQn!;Q9f!;QNm!;QNm!;N5eJ,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCc1!!)ut!!)ut!!&\lJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCc1!!)ut!!)ut!!&\lJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCc1!;QNm!;QNm!;N5eJ,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW%NLo)A[iK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6rW%NLo)A\TK)YfNJcG]LJcCT,!!&MgJ,~>
+f`(pOJcFs6!W[b$JcG<@!'l/9!!%TM!W[b$JcCT,!;N&`J,~>
+f`(pOJcFs6rW'M/JH4'tlMlD8r;_EKM>mPUS,\!~>
+f`(pOJcFs6rW'M/JH4'tlMlD8r;_EKM>mPUS,\!~>
+f`(pOJcFs6!W[b$\c73\d/`J3JH5]Ms+#\#M>mSNS,\!~>
+f`(pOJcFs6rW'M/!!%TMe,KCJkPp)5!!%TMM>mPUS,\!~>
+f`(pOJcFs6rW'M/!!%TMe,KCJkPp)5!!%TMM>mPUS,\!~>
+f`(pOJcFs6!W[b$\c2X0JcF4!!!)3^JUd`NJcCT,!;N&`J,~>
+f`(pOJcFs6rW'M/!!%TMe,KCJkPp)5!!%TMM>mPUS,\!~>
+f`(pOJcFs6rW'M/!!%TMe,KCJkPp)5!!%TMM>mPUS,\!~>
+f`(pOJcFs6!W[b$\c2X0JcF4!!!)3^JUd`NJcCT,!;N&`J,~>
+f`(pOJcFs6rW'M/!!%TMe,TCIU]1;oJcC<$ci3tFS,\!~>
+f`(pOJcFs6rW'M/!!%TMe,TCIU]1<ZJcC<$ci3tFS,\!~>
+f`(pOJcFs6!W[b$\c2X0JcF4!!W[b$U]1<ZJcC<$ci4"?S,\!~>
+f`(pOJcFs6rW'M/!!(1Aq#KUXr;a)%rW&_n!!%TMJcF'r!!&MgJ,~>
+f`(pOJcFs6rW'M/!!(1Aq#KUXr;a)%rW&_n!'l,8JcF'r!!&MgJ,~>
+f`(pOJcFs6!W[b$\c2X0b5_8;kPtJ\Yl=b)J:OEp!'l,8JcF'r!;N&`J,~>
+f`(pOJcFs6rW'M/!!((>rrD0\rrE&u"9AK%!!)cnrrBn8rW&bo!W`6#JcC<$d/O(GS,\!~>
+f`(pOJcFs6rW'M/!!((>rrD0\rrE&u"9AK%!!)cnrrBn8rW&bo!^QcNJcC<$d/O(GS,\!~>
+f`(pOJcFs6!W[b$\c2X0a8c/>jo>>\rr3*$s8N'!p](6n_>aQ:J:OHq!^QcNJcC<$d/O+@S,\!~>
+f`(pOJcFs6rW'M/!!((>rrE#trr<-#!<;utrVufrs8W&us8W*!r;Z]qs8W#ts8W#trr;rtaT)5>
+V#LJrrr@WMJcF*s!!&MgJ,~>
+f`(pOJcFs6rW'M/!!((>rrE#trr<-#!<;utrVufrs8W&us8W*!r;Z]qs8W#ts8W#trr;rtaT)5>
+V#LK]s$2/8JcF*s!!&MgJ,~>
+f`(pOJcFs6!W[b$\c2X0a8c/>rVult!ri9#r;cfrr;cltrW)uurrDusr;cltr;cltr;cisrW(%>
+!W[b$V#LK]s$2/8JcF*s!;N&`J,~>
+f`(pOJcFs6rW'M/!!((>rrE#trW)lrrrE*!rrE#trr<0$!!*&u!;uls!;lfr!<<*!!<3#u!!<0#
+!6P9?!2TVr!<3%Ms+13srr<%gs*t~>
+f`(pOJcFs6rW'M/!!((>rrE#trW)lrrrE*!rrE#trr<0$!!*&u!;uls!;lfr!<<*!!<3#u!!<0#
+!6P9?!2TVr5lX*#s+13srr<%gs*t~>
+f`(pOJcFs6!W[b$\c2X0a8c/>rVuisr;Zcss8W*!rVult"9/?$s8E#rs8N)rs8N*!s8N)us8N'#
+rr<&@rrN1NJ>E2H5lX*#s+13srrDh`s*t~>
+f`(pOJcFs6rW'M/!!((>rrE#trrDrrrrE*!rrE#trr<3%!!*'!r;cisrrDrrrrE*!rrE&urr<-#
+!!(.@rW&ep!!*#u!!%TMJcF-t!!&MgJ,~>
+f`(pOJcFs6rW'M/!!((>rrE#trrDrrrrE*!rrE#trr<3%!!*'!r;cisrrDrrrrE*!rrE&urr<-#
+!!(.@rW&ep!'pP`!'l,8JcF-t!!&MgJ,~>
+f`(pOJcFs6!W[b$\c2X0a8c/>rVultqu?Zrs8W*!rVult"TJH%s8W#trr;uuqu?Zrs8W*!rr;uu
+!ri6#ao;DBJ:OKr!'pP`!'l,8JcF-t!;N&`J,~>
+f`(pOJcFs6rW'M/!!((>rrE#trrE#tr;cltrrE#tquH]qrW)uurrE#tr;cltrrE&uquFk=rW&ep
+!!*#u!!%TMJcF-t!!&MgJ,~>
+f`(pOJcFs6rW'M/!!((>rrE#trrE#tr;cltrrE#tquH]qrW)uurrE#tr;cltrrE&uquFk=rW&ep
+!'pP`!'l,8JcF-t!!&MgJ,~>
+f`(pOJcFs6!W[b$\c2X0a8c/>rVultrVufrs8W*!rVucqrVuiss8W*!rVufrs8W*!rr;lrao;DB
+J:OKr!'pP`!'l,8JcF-t!;N&`J,~>
+f`(pOJcFs6rW'M/!!((>rrE#trrE&urr<9'!!*'!!!)utrrDlprrE*!rrE&urr<9'!!*'!!!*#u
+rrC(=rW&ep!!*#u!!%TMJcF-t!!&MgJ,~>
+f`(pOJcFs6rW'M/!!((>rrE#trrE&urr<9'!!*'!!!)utrrDlprrE*!rrE&urr<9'!!*'!!!*#u
+rrC(=rW&ep!'pP`!'l,8JcF-t!!&MgJ,~>
+f`(pOJcFs6!W[b$\c2X0a8c/>rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!rr;uu#6+Z's8N'!
+rr;uu`r?)?J:OKr!'pP`!'l,8JcF-t!;N&`J,~>
+f`-L&j8caj!!((>rrE#trrE&urr<9'!!*'!!!)utrrE#t!!*#urrE*!rrE&urr<9'!!*'!!!*#u
+rrC(=rW&hq!!)rs!!%TMXT*hOblID9J,~>
+f`-L&j8caj!!((>rrE#trrE&urr<9'!!*'!!!)utrrE#t!!*#urrE*!rrE&urr<9'!!*'!!!*#u
+rrC(=rW&hq!'pJ^!'l,8XT*hOblID9J,~>
+f`-L&joGF3\c2X0a8c/>rVultrr;uu#6+Z's8N'!rVultrVlitrr;uus8W*!rr;uu#6+Z's8N'!
+rr;uu`r?)?J:ONs!'pJ^!'l,8XT*hOblID9J,~>
+ec11#k5`'m!!((>rrE#trrE#tquHcsr;cltr;cltr;cfrrW)uuquHcsrW)uur;at>rW&hq!!)rs
+!!%TMXT&8#JcF'r!!)ZkJ,~>
+ec11#k5`'m!!((>rrE#trrE#tquHcsr;cltr;cltr;cfrrW)uuquHcsrW)uur;at>rW&hq!'pJ^
+!'l,8XT&8#JcF'r!!)ZkJ,~>
+ec12NkCC,C!!((>rrE#trrE#tquHcsr;cltr;cltr;cfrrW)uuquHcsrW)uur;at>!W[b$VZ-W]
+r;Qa^JcDhO!!%TMci3tFo`'F~>
+ec11#k5`'m!!%TMe,TCIVZ-Vrr;Q`sJcDhO!!%TMci3tFo`'F~>
+ec11#k5`'m!!%TMe,TCIVZ-W]r;Qa^JcDhO!!%TMci3tFo`'F~>
+ec12NkCC,C!!%TMe,KILJ:ONs!'pJ^!'l,8XT&8#JcF'r!!)ZkJ,~>
+N;rnXJcG$8!!%TMe,TCIVuH_sqYpNqJcDkP!!%TMci<tEpA]X~>
+N;roCJcG$8!!%TMe,TCIVuH`^qYpO\JcDkP!!%TMci<tEpA]X~>
+N;roCJcG$8!!%TMe,KILJ:OQt!'pD\!'l,8XoAA$JcF'r!W[b$pA]X~>
+N;rnXJcG$8!!%TMe,TCIVuH_sqYpNqJcDkP!!(aQrrDBbquG@Kr;a\6rW)ZlJ,~>
+N;roCJcG$8!!%TMe,TCIVuH`^qYpO\JcDkP!!(aQrrDBbquG@Kr;a\6rW)ZlJ,~>
+N;roCJcG$8!!%TMe,KILJ:OQt!'pD\!'l,8XoAA$gAh0Qli6k_fDkdL_>aQ:J:R@nJ,~>
+N;iqZrr@WMli-qbJcF4!rW&kr!!)lq!!%TMXoAA$gAh0Qr;Zcsrr;uup](6ns8W*!g&M'Prr3*$
+s8N'!p](6ndf9:HpA]X~>
+N;irEs$2/8li-qbJcF4!rW&kr!'pD\!'l,8XoAA$gAh0Qr;Zcsrr;uup](6ns8W*!g&M'Prr3*$
+s8N'!p](6ndf9:HpA]X~>
+N;irEs$2/8li-qbJcF4!!W[b$VuH`^qYpO\JcDkP!!(aQrrDusrrE&urrDfnrrE*!rrCaPrrE&u
+"9AK%!!)cnrrCLI!W[b$pA]X~>
+N;iqZrr@WMli-qbJcF4!rW&ns!!)fo!!%TMY5\J%gAh0QrVufr!<;ut!ri6#rr3K/s8N'!s8N'!
+rr<'!!<<)t!<)rr!<<)u!<)rr!<3#s!!<0#!;ulq!<<)t!<<)t!<3#t!87DO!;?GC~>
+N;irEs$2/8li-qbJcF4!rW&ns!'p>Z!'l,8Y5\J%gAh0QrVufr!<;ut!ri6#rr3K/s8N'!s8N'!
+rr<'!!<<)t!<)rr!<<)u!<)rr!<3#s!!<0#!;ulq!<<)t!<<)t!<3#t!87DO!;?GC~>
+N;irEs$2/8li-qbJcF4!!W[b$W;ci_q#:=ZJcDnQ!!(aQrrE#tr;Zitr;Zp!!!*#u%flY0!!*'!
+!!*$!!<3'!s8;rrs8;rts8E#ss8;rss8;p!rr<&ss8;rts8;rts8;rss8E#OrrN1NJG0"n~>
+N;iqZrr@WMli-qbJcF4!rW&ns!!)fo!!%TMY5\J%gAh0Qr;Zcsrr;uus8W*!rr39)s8N'!s8N'!
+s8E#us8N*!s8N*!s8N)ts8N''rr<'!rr<&ss8N)ts8E#rs8N)rs8N*!s8N)us8N'#rr<&Qs8E#l
+s*t~>
+N;irEs$2/8li-qbJcF4!rW&ns!'p>Z!'l,8Y5\J%gAh0Qr;Zcsrr;uus8W*!rr39)s8N'!s8N'!
+s8E#us8N*!s8N*!s8N)ts8N''rr<'!rr<&ss8N)ts8E#rs8N)rs8N*!s8N)us8N'#rr<&Qs8E#l
+s*t~>
+N;irEs$2/8li-qbJcF4!!W[b$W;ci_q#:=ZJcDnQ!!(aQrrDusrrE&urrE*!rrE&u#lt#*!!*'!
+!!*&u!<<*!!<<*!!<<*!!<)rt!!`H'!<<'!!;uls!<)rs!;uls!;lfr!<<*!!<3#u!!<0#!8@GS
+!.]Uns*t~>
+NW/tYrr2ruJcG*:!!%TMe,TCIW;chtq#:<oJcDnQ!!(aQrrDusrrE&urrE&urr<*"!<3#r!<<*!
+!<3#u!<<*!!<<*!!<)rt!!N<%!<<)u!<)rs!<)rr!<3#u!;lfr!<<*!!<3#u!!<0#!8@JP!;?GC~>
+NW/uDrr2s`JcG*:!!%TMe,TCIW;ci_q#:=ZJcDnQ!!(aQrrDusrrE&urrE&urr<*"!<3#r!<<*!
+!<3#u!<<*!!<<*!!<)rt!!N<%!<<)u!<)rs!<)rr!<3#u!;lfr!<<*!!<3#u!!<0#!8@JP!;?GC~>
+NW/uDrr2s`JcG*:!!%TMe,KILJ:OTu!'p>Z!'l,8Y5\J%gAh0Qr;Zcsrr;uurr;uu!WN0!s82ls
+s8N)us8N*!s8N*!s8N)ts8N'%rr<'!s8E#ss8E#ss8;rss8N)rs8N*!s8N)us8N'#rr<&QrrN1N
+JG0"n~>
+NW/tYrr2ruJcG*:!!%TMe,TCIWW)qupAY*mJcDqR!!(aQrrDusrrE&urrE&urr<*"!<3#u!;uls
+!<3#u!<<*!!<<*!!<)rq!<3#t!<)rs!;ulr!<<*!!<)rr!<<*!!<3#r!8@JP!;?GC~>
+NW/uDrr2s`JcG*:!!%TMe,TCIWW)r`pAY+XJcDqR!!(aQrrDusrrE&urrE&urr<*"!<3#u!;uls
+!<3#u!<<*!!<<*!!<)rq!<3#t!<)rs!;ulr!<<*!!<)rr!<<*!!<3#r!8@JP!;?GC~>
+NW/uDrr2s`JcG*:!!%TMe,KILJ:OX!!'p8X!'l,8YQ"S&gAh0Qr;Zcsrr;uurr;uu!WN0!s8N)s
+s8N)us8N*!s8N*!s8N)ts82lrs8E#ss8E#rs8E#us8N)ts8;rts8N)us82lNrrN1NJG0"n~>
+NW/tYrr2ruJcG*:!!%TMe,TCIWW2SjJcDqR!!(aQrrDusrrE&urrE&urr<*"!<3#u!;uls!<3#u
+!<<*!!<<*!!<)rt!;c`p!<)rs!;uls!<<*!!<3#u!!`H'!<<'!!<3#u!8%8M!;?GC~>
+NW/uDrr2s`JcG*:!!%TMe,TCIWW2TUJcDqR!!(aQrrDusrrE&urrE&urr<*"!<3#u!;uls!<3#u
+!<<*!!<<*!!<)rt!;c`p!<)rs!;uls!<<*!!<3#u!!`H'!<<'!!<3#u!8%8M!;?GC~>
+NW/uDrr2s`JcG*:!!%TMe,KILJ:OX!oK\!-YQ"S&gAh0Qr;Zcsrr;uurr;uu!WN0!s8N)ss8N)u
+s8N*!s8N*!s8N)ts8N)qs8E#ss8E#rs8N*!s8N)us8N''rr<'!rr<&us8N)NrrN1NJG0"n~>
+NrK(Zr;Q`sJcG-;JH4!rU]1;oJcD_L!!(aQrrDusrrE&urrE#trrE#trrDusrrE&urrE*!rrE*!
+rrE#trrDlprrDusrr<*"!<3#u!<<*!!<3#u!!`H'!<<'!!<3#u!8%8M!;?GC~>
+NrK)Er;Qa^JcG-;JH4!rU]1<ZJcD_L!!(aQrrDusrrE&urrE#trrE#trrDusrrE&urrE*!rrE*!
+rrE#trrDlprrDusrr<*"!<3#u!<<*!!<3#u!!`H'!<<'!!<3#u!8%8M!;?GC~>
+NrK)Er;Qa^JcG-;JH4'ts+$mE!'l,8WW)qugAh0Qr;Zcsrr;uurVultrVultr;Zcsrr;uus8W*!
+s8W*!rVultq>^Hpr;Zcs!WN0!s8N*!s8N)us8N''rr<'!rr<&us8N)NrrN1NJG0"n~>
+NrK(Zr;Q`sJcG-;!!%TMe,TCIU]1;oJcD_L!!(aQqZ-ZrrW)uurW)uurrE#trrDusrrE#tr;cfr
+r;cltr;cltr;cisr;cisr;cfrrW)uuquHcsrW)uur;bROrW)ZlJ,~>
+NrK)Er;Qa^JcG-;!!%TMe,TCIU]1<ZJcD_L!!(aQqZ-ZrrW)uurW)uurrE#trrDusrrE#tr;cfr
+r;cltr;cltr;cisr;cisr;cfrrW)uuquHcsrW)uur;bROrW)ZlJ,~>
+NrK)Er;Qa^JcG-;!!%TMe,KILJ:OEp!'l,8WW)qugAh$Ms8W&us8W&us8W*!rVultr;ZcsrVufr
+rVufrs8W#ts8W#trr;osrr;osrVuiss8Vuss8W&us8W#tgA_3SJ:R@nJ,~>
+NrK(Zr;Q`sJcG-;!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+NrK)Er;Qa^JcG-;!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+NrK)Er;Qa^JcG-;!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+O8f1[qYpNqJcG0<!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+O8f2FqYpO\JcG0<!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+O8f2FqYpO\JcG0<!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+O8f1[qYpNqJcG0<!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+O8f2FqYpO\JcG0<!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+O8f2FqYpO\JcG0<!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+O8f1[qYpNqJcG0<!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+O8f2FqYpO\JcG0<!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+O8f2FqYpO\JcG0<!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+OT,:\q#:<oJcG3=!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+OT,;Gq#:=ZJcG3=!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+OT,;Gq#:=ZJcG3=!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+OT,:\q#:<oJcG3=!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+OT,;Gq#:=ZJcG3=!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+OT,;Gq#:=ZJcG3=!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+OT,:\q#:<oJcG3=!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+OT,;Gq#:=ZJcG3=!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+OT,;Gq#:=ZJcG3=!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+OoGC]pAY*mJcG6>!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+OoGDHpAY+XJcG6>!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+OoGDHpAY+XJcG6>!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+OoP%RJcG6>!!%TMe,TCIU]1;oJcD_L!!%TMci<tEpA]X~>
+OoP&=JcG6>!!%TMe,TCIU]1<ZJcD_L!!%TMci<tEpA]X~>
+OoP&=JcG6>!!%TMe,KILJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+N;ikXJcG!7!!%TMe,TCIU]1;oJcD_LJH3jnpA]X~>
+N;ilCJcG!7!!%TMe,TCIU]1<ZJcD_LJH3jnpA]X~>
+N;ilCJcG!7!!%TMe,KILJ:OEp!'l,8WW.MLblIcopA]X~>
+N;ikXJcG!7!!';(quHcs!!)rs!!)Ti!!)rsq>g<j!!)lq!!)cn!!)<arW&_n!!%TMWW)quJcF'r
+rW)ZlJ,~>
+N;ilCJcG!7!!';(quHcs!!)rs!!)Ti!!)rsq>g<j!!)lq!!)cn!!)<arW&_n!'l,8WW)quJcF'r
+rW)ZlJ,~>
+N;ilCJcG!7!!';(quHcs!!)rs!!)Ti!!)rsq>g<j!!)lq!!)cn!!)<a!W[b$U]1<ZJcD_L!!%TM
+ci4%HJ:R@nJ,~>
+N;ikXJcG!7!!'>)!!)lq!!)rs!!)Ti!!)ip!!)]l!!)lq!!)ipquH*`rW&_n!!%TMWW)quJcF'r
+rW)ZlJ,~>
+N;ilCJcG!7!!'>)!!)lq!!)rs!!)Ti!!)ip!!)]l!!)lq!!)ipquH*`rW&_n!'l,8WW)quJcF'r
+rW)ZlJ,~>
+N;ilCJcG!7!!'>)!!)lq!!)rs!!)Ti!!)ip!!)]l!!)lq!!)ipquH*`!W[b$U]1<ZJcD_L!!%TM
+ci4%HJ:R@nJ,~>
+N;ikXJcG!7!!)fo!!)or!<E0!!<3!%!<3$!s8W&urVuisrr;rtrVuisrr;rtrr;rtrVuiss8N'!
+rr2ruq>UEpr;Q`srr;rtrVuiss8N0$rr<&srr<&rs8E#trrE-"rW)rt!!*#urW)rtrrD?arW&_n
+!!%TMWW)quJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)fo!!)or!<E0!!<3!%!<3$!s8W&urVuisrr;rtrVuisrr;rtrr;rtrVuiss8N'!
+rr2ruq>UEpr;Q`srr;rtrVuiss8N0$rr<&srr<&rs8E#trrE-"rW)rt!!*#urW)rtrrD?arW&_n
+!'l,8WW)quJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)fo!!)or!<E0!!<3!%!<3$!s8W&urVuisrr;rtrVuisrr;rtrr;rtrVuiss8N'!
+rr2ruq>UEpr;Q`srr;rtrVuiss8N0$rr<&srr<&rs8E#trrE-"rW)rt!!*#urW)rtrrD?a!W[b$
+U]1<ZJcD_L!!%TMci4%HJ:R@nJ,~>
+N;ikXJcG!7!!)fo!!)orrrE&u"9AK%!!*#u!!*#u!s&B$!;uis!<3!#!<<'!r;Q`sr;Q`srr3'#
+s8N)orr<&prr<&srrW9$rrE&u!s&B$!;uls!<<'!!<)ot!;uis!<3!$!<<'!!<3!&!<<'!s8N)u
+rriE&rrE'!li6qaU]1;oJcD_L!!%TMci<tEpA]X~>
+N;ilCJcG!7!!)fo!!)orrrE&u"9AK%!!*#u!!*#u!s&B$!;uis!<3!#!<<'!r;Q`sr;Q`srr3'#
+s8N)orr<&prr<&srrW9$rrE&u!s&B$!;uls!<<'!!<)ot!;uis!<3!$!<<'!!<3!&!<<'!s8N)u
+rriE&rrE'!li6qaU]1<ZJcD_L!!%TMci<tEpA]X~>
+N;ilCJcG!7!!)fo!!)orrrE&u"9AK%!!*#u!!*#u!s&B$!;uis!<3!#!<<'!r;Q`sr;Q`srr3'#
+s8N)orr<&prr<&srrW9$rrE&u!s&B$!;uls!<<'!!<)ot!;uis!<3!$!<<'!!<3!&!<<'!s8N)u
+rriE&rrE'!li."dJ:OEp!'l,8WW)quJcF'r!W[b$pA]X~>
+N;ikXJcG!7!!)fo!!)or!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`srr3'#s8N)srr<&srr<&urrW9$
+rrDio!!)ipq>gEm!s&B$!;uis!<2uu!<)ot!;QQr!<<'!rVm'%s8N*!rrE&u!!)0]rW&_n!!%TM
+WW)quJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)fo!!)or!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`srr3'#s8N)srr<&srr<&urrW9$
+rrDio!!)ipq>gEm!s&B$!;uis!<2uu!<)ot!;QQr!<<'!rVm'%s8N*!rrE&u!!)0]rW&_n!'l,8
+WW)quJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)fo!!)or!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`srr3'#s8N)srr<&srr<&urrW9$
+rrDio!!)ipq>gEm!s&B$!;uis!<2uu!<)ot!;QQr!<<'!rVm'%s8N*!rrE&u!!)0]!W[b$U]1<Z
+JcD_L!!%TMci4%HJ:R@nJ,~>
+N;ikXJcG!7!!)orq>gNp!!)ut!s&B$!<)ot!<3!#!<<'!r;ZZprr;uurVultrr;lrrr;uuqYpNq
+r;Qj!s8N)srr<&us8;rss8N)urr<&urr<&trr<&rs8;rtrr<&trriE&rrE*!quGmZrW)<bJH1]1
+df0:IJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)orq>gNp!!)ut!s&B$!<)ot!<3!#!<<'!r;ZZprr;uurVultrr;lrrr;uuqYpNq
+r;Qj!s8N)srr<&us8;rss8N)urr<&urr<&trr<&rs8;rtrr<&trriE&rrE*!quGmZrW)<bJH1]1
+df0:IJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)orq>gNp!!)ut!s&B$!<)ot!<3!#!<<'!r;ZZprr;uurVultrr;lrrr;uuqYpNq
+r;Qj!s8N)srr<&us8;rss8N)urr<&urr<&trr<&rs8;rtrr<&trriE&rrE*!quGmZ!W[b$m/MV:
+NW@N-!!%TMci4%HJ:R@nJ,~>
+N;ikXJcG!7!!)fo!!)or!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Qj!s8N)orr<&rrr<&s
+rrW9$rrDus!s&B$!<2uu!;uj!!<<'!rr2rurVlitr;Q`srr3'#s8N)trrrK'rrE*!!94%X!:9^c
+!.k03rr<&Irr<%Ms3L`E!;?GC~>
+N;ilCJcG!7!!)fo!!)or!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Qj!s8N)orr<&rrr<&s
+rrW9$rrDus!s&B$!<2uu!;uj!!<<'!rr2rurVlitr;Q`srr3'#s8N)trrrK'rrE*!!94%X!:9^c
+!.k03rr<&Irr<%Ms3L`E!;?GC~>
+N;ilCJcG!7!!)fo!!)or!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Qj!s8N)orr<&rrr<&s
+rrW9$rrDus!s&B$!<2uu!;uj!!<<'!rr2rurVlitr;Q`srr3'#s8N)trrrK'rrE*!!94"[!.]Ud
+rr<%Ms,d6\!7LlI!.k0rrrN1NJG0"n~>
+N;ikXJcG!7!!)fo!!)orrrE&u!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Qj!s8N)orr<&qrr<&t
+rrW9$rrDus!s&B$!<2uu!;uj!!<<'!rr2rurVlitr;Q`srr3*$s8N'!rr30&s8N*!rrD'YrW)<b
+!!%TMOT,:\df0:IJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)fo!!)orrrE&u!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Qj!s8N)orr<&qrr<&t
+rrW9$rrDus!s&B$!<2uu!;uj!!<<'!rr2rurVlitr;Q`srr3*$s8N'!rr30&s8N*!rrD'YrW)<b
+!!%TMOT,:\df0:IJcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)fo!!)orrrE&u!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Qj!s8N)orr<&qrr<&t
+rrW9$rrDus!s&B$!<2uu!;uj!!<<'!rr2rurVlitr;Q`srr3*$s8N'!rr30&s8N*!rrD'Y!W[b$
+m/I%cJcCi3!!(II!!%TMci4%HJ:R@nJ,~>
+N;ikXJcG!7!!)fo!!)or!<E0!!<2uu!;ulr!<)rs!<3#s!<<)u!<3#t!<)rr!<<)u!<2uu!;ulp
+!<<'!!;uis!<3#r!!*&u!<2uu!<2uu!<)ot!;lfo!!<0#s8E#trr<&us8;r[s8E#brr<%Ms,d9[
+!7_#K!.k0rs8E#ls*t~>
+N;ilCJcG!7!!)fo!!)or!<E0!!<2uu!;ulr!<)rs!<3#s!<<)u!<3#t!<)rr!<<)u!<2uu!;ulp
+!<<'!!;uis!<3#r!!*&u!<2uu!<2uu!<)ot!;lfo!!<0#s8E#trr<&us8;r[s8E#brr<%Ms,d9[
+!7_#K!.k0rs8E#ls*t~>
+N;ilCJcG!7!!)fo!!)or!<E0!!<2uu!;ulr!<)rs!<3#s!<<)u!<3#t!<)rr!<<)u!<2uu!;ulp
+!<<'!!;uis!<3#r!!*&u!<2uu!<2uu!<)ot!;lfo!!<0#s8E#trr<&us8;r[rrN1NJF*:9!.k03
+rrN1NJCOT!!.k0rrrN1NJG0"n~>
+N;ikXJcG!7!!)Qh!!%TMjT#2Zm/I%cZiBh$k5YD\#6+Z's8N'!q#C9mR/d-ceGfLKJcF'rrW)Zl
+J,~>
+N;ilCJcG!7!!)Qh!!%TMjT#2Zm/I%cZiBh$k5YD\#6+Z's8N'!q#C9mR/d-ceGfLKJcF'rrW)Zl
+J,~>
+N;ilCJcG!7!!)Qh!!%TMjSo8]J:R"d!!'A*q#KRWrW!0&!!*'!!!)for;`5b!W[b$eGfLKJcF'r
+!W[b$pA]X~>
+N;ikXJcG!7!!)Qh!!%TMjT#2Zm/I%cYlF_'jT#5[qZ$Qqq>^Hprr3*$s8N'!p](6nWW2qteGfLK
+JcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)Qh!!%TMjT#2Zm/I%cYlF_'jT#5[qZ$Qqq>^Hprr3*$s8N'!p](6nWW2qteGfLK
+JcF'rrW)ZlJ,~>
+N;ilCJcG!7!!)Qh!!%TMjSo8]J:R"d!!'8'rrD-[rrDoqrrDlprrE&u"9AK%!!)cnrrB%u!W[b$
+eGfLKJcF'r!W[b$pA]X~>
+N;ikXJcG!7!!%TMe,TCIm/I%cYlF_'rVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)uu
+rrDusr;cltr;cltr;cisrW'2&rW(IJ!!)9`!!)lq!!)Ed!!%`QrW)ZlJ,~>
+N;ilCJcG!7!!%TMe,TCIm/I%cYlF_'rVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)uu
+rrDusr;cltr;cltr;cisrW'2&rW(IJ!!)9`!!)lq!!)Ed!!%`QrW)ZlJ,~>
+N;ilCJcG!7!!%TMe,KILJ:R"d!!'8'rrE#trr<-#!<;utrVufrs8W&us8Vus#6+Z's8N'!rr;rt
+s8W*!r;Z]qs8W#ts8W#trr;rtYl=b)J:Q/L!!)9`!!)lq!!)Ed!!%`Q!W[b$pA]X~>
+N;ikXJcG!7!!%TMe,TCIm/I%cYlF_'rVuisr;Zcss8W*!rVult#6+Z's8N'!rr;uus8W*!s8W*!
+"9/?$s8E#rs8N)rs8N*!s8N)us8N'#rr<&(s8E#Jrr<&Xrr<&Zrr<%[s8E#ls*t~>
+N;ilCJcG!7!!%TMe,TCIm/I%cYlF_'rVuisr;Zcss8W*!rVult#6+Z's8N'!rr;uus8W*!s8W*!
+"9/?$s8E#rs8N)rs8N*!s8N)us8N'#rr<&(s8E#Jrr<&Xrr<&Zrr<%[s8E#ls*t~>
+N;ilCJcG!7!!%TMe,KILJ:R"d!!'8'rrE#trW)lrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!
+rr<0$!!*&u!;uls!;lfr!<<*!!<3#u!!<0#!3uP*!.]ULrr<&Xrr<&Zrr<%[rrN1NJG0"n~>
+N;ikXJcG!7!!%TMe,TCIm/I%cYlF_'rVultqu?Zrs8W*!rVult#6+Z's8N'!rr;uus8W*!s8W*!
+"TJH%s8W#trr;uuqu?Zrs8W*!rr;uu!ri6#Z2ae'eGfLKq#:<oqu6Zss8E#trr<&us8E!$rrE*!
+!<)rr!<<'!!<3!+!<<'!s8N*!!!*'!rW&&[rW)ZlJ,~>
+N;ilCJcG!7!!%TMe,TCIm/I%cYlF_'rVultqu?Zrs8W*!rVult#6+Z's8N'!rr;uus8W*!s8W*!
+"TJH%s8W#trr;uuqu?Zrs8W*!rr;uu!ri6#Z2ae'eGfLKq#:<oqu6Zss8E#trr<&us8E!$rrE*!
+!<)rr!<<'!!<3!+!<<'!s8N*!!!*'!rW&&[rW)ZlJ,~>
+N;ilCJcG!7!!%TMe,KILJ:R"d!!'8'rrE#trrDrrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!
+rr<3%!!*'!r;cisrrDrrrrE*!rrE&urr<-#!!';(!W[b$eGfLKq#:<oqu6Zss8E#trr<&us8E!$
+rrE*!!<)rr!<<'!!<3!+!<<'!s8N*!!!*'!rW&&[!W[b$pA]X~>
+N;ikXJcG!7!!%TMe,TCIm/I%cYlF_'rVultrVufrs8W*!rVucqs8W*!rr;uus8W*!s8VusrVuis
+s8W*!rVufrs8W*!rr;lrZ2ae'eGfLKq#:<oqu?Zrrr30&s8N*!rrE&urrDrr!!*#u!s&B$!<3!-
+!<<'!s8N'!s8N*!rrA,[rW)ZlJ,~>
+N;ilCJcG!7!!%TMe,TCIm/I%cYlF_'rVultrVufrs8W*!rVucqs8W*!rr;uus8W*!s8VusrVuis
+s8W*!rVufrs8W*!rr;lrZ2ae'eGfLKq#:<oqu?Zrrr30&s8N*!rrE&urrDrr!!*#u!s&B$!<3!-
+!<<'!s8N'!s8N*!rrA,[rW)ZlJ,~>
+N;ilCJcG!7!!%TMe,KILJ:R"d!!'8'rrE#trrE#tr;cltrrE#tquHcsrrE&urrE*!rrE*!quH]q
+rW)uurrE#tr;cltrrE&uquF#%!W[b$eGfLKq#:<oqu?Zrrr30&s8N*!rrE&urrDrr!!*#u!s&B$
+!<3!-!<<'!s8N'!s8N*!rrA,[!W[b$pA]X~>
+N;ikXJcG!7!!)<a!!'q:!!'&!rW)<b!!'8'rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!
+rrE*!rrDlprrE*!rrE&urr<9'!!*'!!!*#urrB5%rW(IJ!!)fo!!)or!!)ut"p"]'!<<'!rVlit
+qu6Wrrr3'#s8N)urrrK'rrE*!!<3!#!<<'!O8o1ZpA]X~>
+N;ilCJcG!7!!)<a!!'q:!!'&!rW)<b!!'8'rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!
+rrE*!rrDlprrE*!rrE&urr<9'!!*'!!!*#urrB5%rW(IJ!!)fo!!)or!!)ut"p"]'!<<'!rVlit
+qu6Wrrr3'#s8N)urrrK'rrE*!!<3!#!<<'!O8o1ZpA]X~>
+N;ilCJcG!7!!)<a!!'q:!!'&!!W[b$m/I%cYlF_'rVultrr;uu#6+Z's8N'!rVultr;Zcsrr;uu
+s8W*!s8W*!q>^Hps8W*!rr;uu#6+Z's8N'!rr;uuY5\P'J:Q/L!!)fo!!)or!!)ut"p"]'!<<'!
+rVlitqu6Wrrr3'#s8N)urrrK'rrE*!!<3!#!<<'!O8f7]J:R@nJ,~>
+])ST,QN$pblMghag&D$Pir8uY[/^+*m/I%cYlF_'rVultrr;uu#6+Z's8N'!rVultr;Zcsrr;uu
+s8W*!s8W*!rVlitrr;uus8W*!rr;uu#6+Z's8N'!rr;uuY5eJ$eGfLKqu?Kmrr2rurVm'%s8N*!
+rrE#t!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrA,[rW)ZlJ,~>
+])ST,QN$pblMghag&D$Pir8uY[/^+*m/I%cYlF_'rVultrr;uu#6+Z's8N'!rVultr;Zcsrr;uu
+s8W*!s8W*!rVlitrr;uus8W*!rr;uu#6+Z's8N'!rr;uuY5eJ$eGfLKqu?Kmrr2rurVm'%s8N*!
+rrE#t!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrA,[rW)ZlJ,~>
+])ST,QN$pblMghag&D$Pir8uY[/U1-J:R"d!!'8'rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&u
+rrE*!rrE*!rrE#t!!*#urrE*!rrE&urr<9'!!*'!!!*#urrB5%!W[b$eGfLKqu?Kmrr2rurVm'%
+s8N*!rrE#t!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrA,[!W[b$pA]X~>
+])Ma1VuH_sQN$pbq#:<oqu6`urr<&urrE-"rW)]mrW)uu!!)rs!<E0!!<3!%!<3$!s8W&us8N'!
+rVufrs8N'!rr3?+s8N*!rrE'!!<<)u!4Dk+!:9^c!3lM'!<)rt!<)rq!<<)t!<<)t!<<*!!<3#u
+!<<*!!<3#s!<<)t!<)rs!<<)s!<<)u!<<)t!3uS'!7_#K!;QQo!;lcr!<)p%!<<'!s8N)trr<&r
+rr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N([s8E#ls*t~>
+])Ma1VuH_sQN$pbq#:<oqu6`urr<&urrE-"rW)]mrW)uu!!)rs!<E0!!<3!%!<3$!s8W&us8N'!
+rVufrs8N'!rr3?+s8N*!rrE'!!<<)u!4Dk+!:9^c!3lM'!<)rt!<)rq!<<)t!<<)t!<<*!!<3#u
+!<<*!!<3#s!<<)t!<)rs!<<)s!<<)u!<<)t!3uS'!7_#K!;QQo!;lcr!<)p%!<<'!s8N)trr<&r
+rr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N([s8E#ls*t~>
+])Ma1VuH_sQN$pbq#:<oqu6`urr<&urrE-"rW)]mrW)uu!!)rs!<E0!!<3!%!<3$!s8W&us8N'!
+rVufrs8N'!rr3?+s8N*!rrE'!!<<)u!4Dh.!.]Udrr<&'s8N)ts8N)ts82lss8;rts8;rts8N)u
+s8N*!s8N)us8;rts8;rrs8E#us82lss8E#us8;r&rrN1NJCOT!!;QQo!;lcr!<)p%!<<'!s8N)t
+rr<&rrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N([rrN1NJG0"n~>
+])Ma1VuH_sQN$pbq#:<oqu?Zrs8N3%s8N'!rr2ruq>UEprr3'#s8N)urrN3#!<3!*!<<'!!<<'!
+s8N)qrr<&urrW9$rrE&u%06G.!<<'!!<<'!s8N)+s8E#brr<%Ms,d9[!7_#K!;QQo!;lfr!<3!&
+!<<'!s8N)us8N)rrt,82rr<'!rrE*!!!*'!!<<'!rr3'#s8N([s8E#ls*t~>
+])Ma1VuH_sQN$pbq#:<oqu?Zrs8N3%s8N'!rr2ruq>UEprr3'#s8N)urrN3#!<3!*!<<'!!<<'!
+s8N)qrr<&urrW9$rrE&u%06G.!<<'!!<<'!s8N)+s8E#brr<%Ms,d9[!7_#K!;QQo!;lfr!<3!&
+!<<'!s8N)us8N)rrt,82rr<'!rrE*!!!*'!!<<'!rr3'#s8N([s8E#ls*t~>
+])Ma1VuH_sQN$pbq#:<oqu?Zrs8N3%s8N'!rr2ruq>UEprr3'#s8N)urrN3#!<3!*!<<'!!<<'!
+s8N)qrr<&urrW9$rrE&u%06G.!<<'!!<<'!s8N)+rrN1NJF*:9!.k03rrN1NJCOT!!;QQo!;lfr
+!<3!&!<<'!s8N)us8N)rrt,82rr<'!rrE*!!!*'!!<<'!rr3'#s8N([rrN1NJG0"n~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr3'#s8N)trr<&prr<&urrW9$rrE&u!W`6#rr3'#s8N)urrW9$
+rrDoq!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrBG+rW)<b!!%TMOT5:[eGfLKq#:<oqu6Zss8E#t
+rr<&us8E!$rrE*!!<)rt!!3*"rr;uu#QFf(rrE*!!<2uu!<2uu!0I6[!;?GC~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr3'#s8N)trr<&prr<&urrW9$rrE&u!W`6#rr3'#s8N)urrW9$
+rrDoq!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrBG+rW)<b!!%TMOT5:[eGfLKq#:<oqu6Zss8E#t
+rr<&us8E!$rrE*!!<)rt!!3*"rr;uu#QFf(rrE*!!<2uu!<2uu!0I6[!;?GC~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#u!s&B$!<)ot!;ZWp!<3!#!<<'!rr3$"rrE&u!s&B$!<3!#
+!<<'!qYpNqrr3'#s8N)urrrK'rrE*!!<3!#!<<'![/U1-J:R"d!!%TMOT,@^J:Q/L!!)fo!!)or
+!<E0!!<2uu!<3#t!!N<%s8N)ts8N'"rrE&urr<<(!<<'!s8N)urr<&urr<%\rrN1NJG0"n~>
+])Ma1rVuZneGoIIjT#2ZR/[-dqu?Kmrr2rurr3'#s8N)trr<&ps82lrrr`?%!<<)s!<<'!!<3!#
+!<<'!qYpNqrr3'#s8N)urrrK'rrE*!!<3!#!<<'![/^+*m/I%cJcCi3rW(IJ!!)Qh!!)3^!!%TM
+qu?WqpA]X~>
+])Ma1rVuZneGoIIjT#2ZR/[-dqu?Kmrr2rurr3'#s8N)trr<&ps82lrrr`?%!<<)s!<<'!!<3!#
+!<<'!qYpNqrr3'#s8N)urrrK'rrE*!!<3!#!<<'![/^+*m/I%cJcCi3rW(IJ!!)Qh!!)3^!!%TM
+qu?WqpA]X~>
+])Ma1rVuZneGoIIjSo8]J:O$e!!)orq>gNp!!*#u!s&B$!<)ot!;ZZm!<3!$!<3'!s82lsrr<&u
+rrW9$rrDoq!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrBG+!W[b$m/I%cJcCi3!W[b$eGfLKnc&Rh
+kPkM^JcGWI!W[b$pA]X~>
+])Ma1qZ$Qqf)PaMs8W*!rr3*$s8N'!p](6np&G!kR/[-dq#:<oqu6Wrrr3'#s8N)trr<&prr<&q
+rriE&!<<'!qu6Wrrr3'#s8N)qrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N)+s8E#brr<%Ms,d9[
+!7_#K!:g'h!:0[`!.k1Hs8E#ls*t~>
+])Ma1qZ$Qqf)PaMs8W*!rr3*$s8N'!p](6np&G!kR/[-dq#:<oqu6Wrrr3'#s8N)trr<&prr<&q
+rriE&!<<'!qu6Wrrr3'#s8N)qrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N)+s8E#brr<%Ms,d9[
+!7_#K!:g'h!:0[`!.k1Hs8E#ls*t~>
+])Ma1qZ$Qqf)PaMs8W*!rr3*$s8N'!p](6np&>'nJ:O$e!!)fo!!)or!!*#u!s&B$!<)ot!;ZWp
+!;c^!!<3'!rrDrr!!*#u!s&B$!;c]q!<3!#!<<'!rr30&s8N*!rrE&u!s&B$!4;b-!.]Udrr<%M
+s,d6^!.]ULrr<&hrr<&bs8;qKs8)`s!.]Uns*t~>
+])Ma1qZ$QqrVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;Zp!!!)rsr;cltr;cltr;cisrW)lr
+rW&>c!!)fo!!)or!!*#u"9AK%!!*#u!!)ip!!)lq"T\Q&s8N)rrr<&urrW9$rrDoq&HMk2!!*'!
+!<<'!!<<'!s8N)urrW9$rrBG+rW)<b!!%TMOT5:[eGfLKJcF'rrW)ZlJ,~>
+])Ma1qZ$QqrVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;Zp!!!)rsr;cltr;cltr;cisrW)lr
+rW&>c!!)fo!!)or!!*#u"9AK%!!*#u!!)ip!!)lq"T\Q&s8N)rrr<&urrW9$rrDoq&HMk2!!*'!
+!<<'!!<<'!s8N)urrW9$rrBG+rW)<b!!%TMOT5:[eGfLKJcF'rrW)ZlJ,~>
+])Ma1qZ$QqrVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;Zp!!!)rsr;cltr;cltr;cisrW)lr
+!W[b$R/[-dq#:<oqu6Wrrr3*$s8N'!rr2ruq>UEpqYp^!rrE*!!;lcr!<3!#!<<'!qYq--s8N'!
+s8N*!rr<'!rrE*!!<3!#!<<'![/U1-J:R"d!!%TMOT,@^J:Q/L!!%TMci4%HJ:R@nJ,~>
+])Ma1qZ$QqrVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#lal)s8N'!s8W&ur;Zcsqu?Zrs8W*!
+rr;uu!ri6#rVuisR/[-dq#:<oqu6Wrrr3*$s8N*!rW)]mr;cfr!!)utr;clt!!*#u!!*#u!s&B$
+!<)rt!!3*"rr;uu#QFf(rrE*!!<2uu!<2uu!4Dk+!:9^c!.k03s8E#Jrr<%Ms3L`E!;?GC~>
+])Ma1qZ$QqrVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#lal)s8N'!s8W&ur;Zcsqu?Zrs8W*!
+rr;uu!ri6#rVuisR/[-dq#:<oqu6Wrrr3*$s8N*!rW)]mr;cfr!!)utr;clt!!*#u!!*#u!s&B$
+!<)rt!!3*"rr;uu#QFf(rrE*!!<2uu!<2uu!4Dk+!:9^c!.k03s8E#Jrr<%Ms3L`E!;?GC~>
+])Ma1qZ$QqrVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#lal)s8N'!s8W&ur;Zcsqu?Zrs8W*!
+rr;uu!ri6#rVlp!J:O$e!!)fo!!)or!!*#u"9AK%!<<#up](0lrVlitrVufrs8N'!rr2rurr3'#
+s8N)ts8N'"rrE&urr<<(!<<'!s8N)urr<&urr<&,rrN1NJF*:9!.k03rrN1NJCOT!!.k0rrrN1N
+JG0"n~>
+])Ma1qZ$QqrVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;osrr;uuqu?Zrs8W*!
+rr;uu!ri6#rVuisR/[-dirArWf`(pOT`=ukm/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1qZ$QqrVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;osrr;uuqu?Zrs8W*!
+rr;uu!ri6#rVuisR/[-dirArWf`(pOT`=ukm/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1qZ$QqrVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;osrr;uuqu?Zrs8W*!
+rr;uu!ri6#rVlp!J:O$e!!)$Yr;bLM!!&\l!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1qZ$QqrVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!r;Z`rs8W*!rVufrs8W*!rr;lrrVuis
+R/[-d\c;U.TE"ljm/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1qZ$QqrVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!r;Z`rs8W*!rVufrs8W*!rr;lrrVuis
+R/[-d\c;U.TE"ljm/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1qZ$QqrVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!r;Z`rs8W*!rVufrs8W*!rr;lrrVlp!
+J:O$e!!'S0r;`Ji!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1qZ$QqrVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsqu?Zrs8W*!rr;uu#6+Z's8N'!
+rr;uuqZ$NpR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKiVrlXqYpNqmJd.dNW8tXpA]X~>
+])Ma1qZ$QqrVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsqu?Zrs8W*!rr;uu#6+Z's8N'!
+rr;uuqZ$NpR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKiVrlXqYpNqmJd.dNW8tXpA]X~>
+])Ma1qZ$QqrVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsqu?Zrs8W*!rr;uu#6+Z's8N'!
+rr;uuqYpTsJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)!X!!)lq!!)Ed!!&#Y!W[b$pA]X~>
+])Ma1qZ$QqrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;Zcss8N'!rr;uus8W*!rr;uu#6+Z'
+s8N'!rr;uuqZ$NpR/[-dJcF4!rW)<bJH1W/eGfLKg&D$Pj8T)ZQiI$bpA]X~>
+])Ma1qZ$QqrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;Zcss8N'!rr;uus8W*!rr;uu#6+Z'
+s8N'!rr;uuqZ$NpR/[-dJcF4!rW)<bJH1W/eGfLKg&D$Pj8T)ZQiI$bpA]X~>
+])Ma1qZ$QqrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;Zcss8N'!rr;uus8W*!rr;uu#6+Z'
+s8N'!rr;uuqYpTsJ:O$e!!%TMe,KILJ:R"dJH1]1s+&W!!!(^P!!)'Z!!&Ac!W[b$pA]X~>
+])Ma1qZ$QqrVultrVucqs8W#ts8W#ts8W#trVufrrr;rt!<;utrVuiss8Vuss8W&us8W#trVuis
+R/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu6Zss8E#trrE-"rW)rt!!*#urW!*$!<<'!rVufr
+s8N'!rr3?+s8N*!rrE'!!<<)u!1<fc!;?GC~>
+])Ma1qZ$QqrVultrVucqs8W#ts8W#ts8W#trVufrrr;rt!<;utrVuiss8Vuss8W&us8W#trVuis
+R/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu6Zss8E#trrE-"rW)rt!!*#urW!*$!<<'!rVufr
+s8N'!rr3?+s8N*!rrE'!!<<)u!1<fc!;?GC~>
+])Ma1qZ$QqrVultrVucqs8W#ts8W#ts8W#trVufrrr;rt!<;utrVuiss8Vuss8W&us8W#trVlp!
+J:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)or!<E0!!<3!!!<<#urr2rurr;rt"TJK%
+rrE#tr;clt!!*#u$NU5,!<<'!rr<'!s8E"crrN1NJG0"n~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu?Zrrr3*$s8N'!rr30&s8N*!rrE&u
+rrDrr!!*#u!s&B$!<3!-!<<'!s8N'!s8N*!rrADcrW)ZlJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu?Zrrr3*$s8N'!rr30&s8N*!rrE&u
+rrDrr!!*#u!s&B$!<3!-!<<'!s8N'!s8N*!rrADcrW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)orrrE&u"9AK%!!*#u"p"]'
+!<<'!rr;uuqu6Wrrr3'#s8N)urs\u.rrE*!!!*'!!<<'!Qi@*eJ:R@nJ,~>
+])Ma1VuQ_rR/[-ddJj1Hg]%6RmJd.d_#OB6m/I%cJcCi3rW(IJ!!)fo!!)or!!)ut!s&B$!<)p%
+!<<'!s8N)trr<&rrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N(cs8E#ls*t~>
+])Ma1VuQ_rR/[-ddJj1Hg]%6RmJd.d_#OB6m/I%cJcCi3rW(IJ!!)fo!!)or!!)ut!s&B$!<)p%
+!<<'!s8N)trr<&rrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N(cs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!(FH!!(dR!!)Ed!!'h7!W[b$m/I%cJcCi3!W[b$eGfLKq#:<oqu6WrrVls"
+s8N)trrrK'rrE*!!<)ot!;lcr!<3!#!<<'!rr30&s8N*!rrE&u!s&B$!13]e!.]Uns*t~>
+])Ma1VuQ_rR/[-da8Z,>jo5;\j8T)Zb5_G@m/I%cJcCi3rW(IJ!!)orq>gNp!!)ut!s&B$!<)p%
+!<<'!s8N)trr<&rrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N(cs8E#ls*t~>
+])Ma1VuQ_rR/[-da8Z,>jo5;\j8T)Zb5_G@m/I%cJcCi3rW(IJ!!)orq>gNp!!)ut!s&B$!<)p%
+!<<'!s8N)trr<&rrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N(cs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!((>!!)-\!!)'Z!!(1A!W[b$m/I%cJcCi3!W[b$eGfLKqu?Kmrr2rurVls"
+s8N)trrrK'rrE*!!<)ot!;lcr!<3!#!<<'!rr30&s8N*!rrE&u!s&B$!13]e!.]Uns*t~>
+])Ma1VuQ_rR/[-dq#:<oqZ$Nprr;rts8N'!r;Qcts8E#nrs/W)rrE'!!<<)u!<3#t!<3!!!<<#u
+r;Qcts8E#trrW9$rrE#tr;clt!!*#u$NU5,!<<'!rr<'!s8E#As8E#brr<%Ms,d9[!7_#K!;QQo
+!;lcr!<)p"!<<'!rVm'%s8N*!rrE#t!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrADcrW)Zl
+J,~>
+])Ma1VuQ_rR/[-dq#:<oqZ$Nprr;rts8N'!r;Qcts8E#nrs/W)rrE'!!<<)u!<3#t!<3!!!<<#u
+r;Qcts8E#trrW9$rrE#tr;clt!!*#u$NU5,!<<'!rr<'!s8E#As8E#brr<%Ms,d9[!7_#K!;QQo
+!;lcr!<)p"!<<'!rVm'%s8N*!rrE#t!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrADcrW)Zl
+J,~>
+])Ma1VuHeuJ:O$e!!)fo!!)lqrW)rtrW)uu!!)rs!<E0!!;QR"!<<'!rr<'!s8E#ts8E#trrE-"
+rW)lr!<E0!!<3!#!<<'!rVufrs8N'!rr3?+s8N*!rrE'!!<<)u!6bBD!.]Udrr<%Ms,d6^!.]UL
+rr<&orr<&rrr<&trrW9$rrE#t"p"]'!<<'!rVlitqu6Wrrr3'#s8N)urrrK'rrE*!!<3!#!<<'!
+Qi@*eJ:R@nJ,~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrr;Q`srr3'#s8N)urrN3#!<2uu!;ZX%!<<'!!<<'!s8N)urr<&u
+rr`?%rr<&urr<&urrN3#!<3!#!<<'!qu6Wrrr3'#s8N)urs\u.rrE*!!!*'!!<<'!b5_G@m/I%c
+JcCi3rW)KgrrDZjrrDcm!!)fo!!)orrrE&u"9AK%!!*#u"p"]'!<<'!rr;uuqu76.s8N'!s8N*!
+rr<'!rrE*!!<3!#!<<'!QiI$bpA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrr;Q`srr3'#s8N)urrN3#!<2uu!;ZX%!<<'!!<<'!s8N)urr<&u
+rr`?%rr<&urr<&urrN3#!<3!#!<<'!qu6Wrrr3'#s8N)urs\u.rrE*!!!*'!!<<'!b5_G@m/I%c
+JcCi3rW)KgrrDZjrrDcm!!)fo!!)orrrE&u"9AK%!!*#u"p"]'!<<'!rr;uuqu76.s8N'!s8N*!
+rr<'!rrE*!!<3!#!<<'!QiI$bpA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!)rs!!*#u!s&B$!<3!"!<3&urr<&prsAc+rr<'!rrE*!!<2uu
+!<3!$!<<'!!<2uu!<3!"!<3&urrW9$rrDrr!!*#u!s&B$!<3!-!<<'!s8N'!s8N*!rrC4A!W[b$
+m/I%cJcCi3!W[b$nc/XaoDejcpAY*mq#:<oqu?Zrrr3*$s8N'!rr30&s8N*!rrE&urrDrr&HMk2
+!!*'!!<<'!!<<'!s8N)urrW9$rrADc!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrq#:Ers8N)urrN3#!<2uu!;ZWs!<<'!rr3'#s8N)urr<&urrW9$
+rrE#t!!*#u!!)rs!s&B$!;lcr!<3!#!<<'!rr30&s8N*!rrE&u!s&B$!6Y?@!:9^c!.k03s8E#h
+rrW9$rrD`l!W`6#pAY*mq#:<oqu6Zss8E#trrE-"rW)rt!!*#urW!*$!<<'!rVult!WN0!s8N'(
+rrE*!!<<'!rr2rurr2ruR/d-cpA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrq#:Ers8N)urrN3#!<2uu!;ZWs!<<'!rr3'#s8N)urr<&urrW9$
+rrE#t!!*#u!!)rs!s&B$!;lcr!<3!#!<<'!rr30&s8N*!rrE&u!s&B$!6Y?@!:9^c!.k03s8E#h
+rrW9$rrD`l!W`6#pAY*mq#:<oqu6Zss8E#trrE-"rW)rt!!*#urW!*$!<<'!rVult!WN0!s8N'(
+rrE*!!<<'!rr2rurr2ruR/d-cpA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!)fo!s&B$!<3!"!<3&urr<&prrW9$rrE&u!s&B$!<2uu!<3!#
+!<<'!rVlitrr2rur;Qj!s8N)rrr<&urrW9$rrE&u"p"]'!<<'!rr3'#s8N)ArrN1NJF*:9!.k03
+rrN1NJF`^Bq#CBhp&>*gs7l<f!!)fo!!)or!<E0!!<3!!!<<#urr2rurr;rt"TJK%rrE#trr<*"
+!<3#u!!iN(s8N*!rrE&u!!*#u!!&Dd!W[b$pA]X~>
+])Ma1VuQ_rR/[-dqu?KmrVultrVufrrr3*$rrE*!quHQm!s&B$!<3!#!<<'!rr;lrs8N'!r;Qfu
+rrE&ur;clt!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrC4ArW)<b!!%TMOT5:[oD\djrVlit
+o`"mkpAY*mnc&RhqYpNqkPkM^KE(oNpA]X~>
+])Ma1VuQ_rR/[-dqu?KmrVultrVufrrr3*$rrE*!quHQm!s&B$!<3!#!<<'!rr;lrs8N'!r;Qfu
+rrE&ur;clt!!)or!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrC4ArW)<b!!%TMOT5:[oD\djrVlit
+o`"mkpAY*mnc&RhqYpNqkPkM^KE(oNpA]X~>
+])Ma1VuHeuJ:O$e!!)orq>gKorrE#tr;cis"9AH%s8Vusq>UNss8N)urrW9$rrE&uquHcs!!)rs
+!W`6#rr;oss8N'!qu6Wrrr3'#s8N)urrrK'rrE*!!<3!#!<<'!b5VMCJ:R"d!!%TMOT,@^J:R7k
+!;QNm!;Q3d!;Q9f!!)Qh!!)lq!!)3^!!%ZO!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oq#:Ers8N)urr<&urriE&!<<'!p&>*os8N)urrW9$rrE&u!!)or!!)rs
+"T\Q&s8N)urrW9$rrDrr!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrC4ArW)<b!!%TMOT5:[oD\dj
+rVlito`"mkpAY*mnc&RhqYpNqli6n`K)bfMpA]X~>
+])Ma1VuQ_rR/[-dq#:<oq#:Ers8N)urr<&urriE&!<<'!p&>*os8N)urrW9$rrE&u!!)or!!)rs
+"T\Q&s8N)urrW9$rrDrr!!*#u!s&B$!<3!&!<<'!s8N)urrW9$rrC4ArW)<b!!%TMOT5:[oD\dj
+rVlito`"mkpAY*mnc&RhqYpNqli6n`K)bfMpA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)fo!s&B$!<2uu!<3!%!<3'!rrD`l!s&B$!<3!#!<<'!rr2ruqu6Wr
+r;Qp#rrE*!!<3!#!<<'!qu6Wrrr3'#s8N)urrrK'rrE*!!<3!#!<<'!b5VMCJ:R"d!!%TMOT,@^
+J:R7k!;QNm!;Q3d!;Q9f!!)Qh!!)lq!!)?br;_HL!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oq#:Ers8N)urr<&urriE&!<<'!p&>*os8N)urrW9$rrE&u!!)or!!)rs
+"T\Q&s8N)urrW9$rrDrr&HMk2!!*'!!<<'!!<<'!s8N)urrW9$rrC4ArW)<b!!%TMOT5:[oD\dj
+rVlito`"mkpAY*mJcF'rrW)ZlJ,~>
+])Ma1VuQ_rR/[-dq#:<oq#:Ers8N)urr<&urriE&!<<'!p&>*os8N)urrW9$rrE&u!!)or!!)rs
+"T\Q&s8N)urrW9$rrDrr&HMk2!!*'!!<<'!!<<'!s8N)urrW9$rrC4ArW)<b!!%TMOT5:[oD\dj
+rVlito`"mkpAY*mJcF'rrW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)fo!!)fo!s&B$!<2uu!<3!%!<3'!rrD`l!s&B$!<3!#!<<'!rr2ruqu6Wr
+r;Qp#rrE*!!<3!#!<<'!qu76.s8N'!s8N*!rr<'!rrE*!!<3!#!<<'!b5VMCJ:R"d!!%TMOT,@^
+J:R7k!;QNm!;Q3d!;Q9f!!%TMci4%HJ:R@nJ,~>
+]DnT*R/[-dq#:<oqu?WqrVucqrr2rurVufrq>UNss8N)urr<&urr<&us8;rtrr<&rrr<&ts82j"
+rrE*!!<)rt!!3*"rr;uu#QFf(rrE*!!<2uu!<2uu!6bEA!:9^c!.k03s8E#irr<&trr<&krr<&m
+rr<%Ms3L`E!;?GC~>
+]DnT*R/[-dq#:<oqu?WqrVucqrr2rurVufrq>UNss8N)urr<&urr<&us8;rtrr<&rrr<&ts82j"
+rrE*!!<)rt!!3*"rr;uu#QFf(rrE*!!<2uu!<2uu!6bEA!:9^c!.k03s8E#irr<&trr<&krr<&m
+rr<%Ms3L`E!;?GC~>
+]DnZ,s+$L:!!)fo!!)orrW)osquH`r!!)utr;cZn!s&B$!<2uu!<2uu!<3#s!<<'!!;lcr!<)rq
+!!N<%s8N)ts8N'"rrE&urr<<(!<<'!s8N)urr<&urr<&BrrN1NJF*:9!.k03rrN1NJFid@q#13m
+q"4Rdq"F^f!.k0rrrN1NJG0"n~>
+])Ma1VuQ_rR/[-dfDkdLc2RbD[f?=,m/I%cJcG3=!!)Her;bONquH!]!<E0!!;$3j!<)ot!;-9k
+!;?Em!.k0rs8E#ls*t~>
+])Ma1VuQ_rR/[-dfDkdLc2RbD[f?=,m/I%cJcG3=!!)Her;bONquH!]!<E0!!;$3j!<)ot!;-9k
+!;?Em!.k0rs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!(XNr;b+B!!'J-!W[b$m/I%cJcG3=!!)Her;bONquH!]"9AH%J:R7k!;QNm
+!;Q3d!;Q9f!!%TMci4%HJ:R@nJ,~>
+])Ma1VuQ_rR/[-dU]:8m[K$4+m/I%cbl7YC^]+96p\t3noD\djr;Q`srr2ruq#:<orr2rug]%6R
+qu6Wrp\t3nq#C0jo)Adls8N)jrr<&mrr<%Ms3L`E!;?GC~>
+])Ma1VuQ_rR/[-dU]:8m[K$4+m/I%cbl7YC^]+96p\t3noD\djr;Q`srr2ruq#:<orr2rug]%6R
+qu6Wrp\t3nq#C0jo)Adls8N)jrr<&mrr<%Ms3L`E!;?GC~>
+])Ma1VuHeuJ:O$e!!&eor;a8*!W[b$m/I%cbl7YC^]+96p\t3noD\djr;Q`srr2ruq#:<orr2ru
+g]%6Rqu6Wrp\t3nq#C6ls+'\?"8Morq"+Lcq"F^f!.k0rrrN1NJG0"n~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)fo!!)lqrW)uu!!*#u%06G.!<3$!rrE'!!<<)u!<3!%!<3$!
+s8W&uq>UHqs8E#trriE&!!*'!rW)osrW)rtrW)osrW)rtrW)`nrVururW)rtrW)uurW)rtrW)rt
+!!*#u!!)utrVururW!!!!;uls!<3!(!<<'!rr<'!s8E#ss8E#ts8E#ss8E#ts8E!!rrDusrW)rt
+rW)uurW)rtrW)rtrr<'!rW)KgrrE#t!!*#u!!)utquHNl!!(OK!!)3^!!)9`!!)]lq>gQq!!((>
+rW)ZlJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)fo!!)lqrW)uu!!*#u%06G.!<3$!rrE'!!<<)u!<3!%!<3$!
+s8W&uq>UHqs8E#trriE&!!*'!rW)osrW)rtrW)osrW)rtrW)`nrVururW)rtrW)uurW)rtrW)rt
+!!*#u!!)utrVururW!!!!;uls!<3!(!<<'!rr<'!s8E#ss8E#ts8E#ss8E#ts8E!!rrDusrW)rt
+rW)uurW)rtrW)rtrr<'!rW)KgrrE#t!!*#u!!)utquHNl!!(OK!!)3^!!)9`!!)]lq>gQq!!((>
+rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!)fo!!)lqrW)uu!!*#u%06G.!<3$!rrE'!!<<)u!<3!%
+!<3$!s8W&uq>UHqs8E#trriE&!!*'!rW)osrW)rtrW)osrW)rtrW)`nrVururW)rtrW)uurW)rt
+rW)rt!!*#u!!)utrVururW!!!!;uls!<3!(!<<'!rr<'!s8E#ss8E#ts8E#ss8E#ts8E!!rrDus
+rW)rtrW)uurW)rtrW)rtrr<0$!.]Uis8VlmrrDinrrDims8;Zerr<&Krr<&^rr<&`rr<&ls7u`q
+rr<&>rrN1NJG0"n~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)fo!!)or!!)rs!!*#u"9AK%!!*#urrE&u!!*#u$3:,+!!*'!
+!<<'!q#C?orr3*$s8N'!rr2rurr3'#s8N)srr<&urrW9$rrDus!!)`m!!)rs!!*#u!!*#u!s&B$
+!<2uu!<2uu!;lcr!;uis!<2uu!<2uu!<3!"!<3&urr`?%rr<&urr<&urrW9$rrDus!!*#u!s&B$
+!;uis!;uis!;uis!<2uu!<3!#!<<'!rr2rurr3*$s8N*!r;b@I!!([O!!)3^!!)-\!!)rs!!*#u
+!!)rs!!'k8rW)ZlJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)fo!!)or!!)rs!!*#u"9AK%!!*#urrE&u!!*#u$3:,+!!*'!
+!<<'!q#C?orr3*$s8N'!rr2rurr3'#s8N)srr<&urrW9$rrDus!!)`m!!)rs!!*#u!!*#u!s&B$
+!<2uu!<2uu!;lcr!;uis!<2uu!<2uu!<3!"!<3&urr`?%rr<&urr<&urrW9$rrDus!!*#u!s&B$
+!;uis!;uis!;uis!<2uu!<3!#!<<'!rr2rurr3*$s8N*!r;b@I!!([O!!)3^!!)-\!!)rs!!*#u
+!!)rs!!'k8rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!)fo!!)or!!)rs!!*#u"9AK%!!*#urrE&u!!*#u$3:,+
+!!*'!!<<'!q#C?orr3*$s8N'!rr2rurr3'#s8N)srr<&urrW9$rrDus!!)`m!!)rs!!*#u!!*#u
+!s&B$!<2uu!<2uu!;lcr!;uis!<2uu!<2uu!<3!"!<3&urr`?%rr<&urr<&urrW9$rrDus!!*#u
+!s&B$!;uis!;uis!;uis!<2uu!<3!#!<<'!rr2rurr36(s8N*!!!%P"eGfLKf`(pOkPkM^jo5;\
+r;Q`srr2rur;Q`s_>aQ:J:R@nJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!<3!#!<<'!rr3'#
+s8N)orr<&trrW9$rrE#t!!*#u!s&B$!;uis!<3!#!<<'!r;Q`spAY*mr;Q`sqYpWts8N)urr<&u
+rr<&rrr<&srr<&urr<&urr<&urrE-"r;cis!!)ut!!*#u!s&B$!;uis!<3!#!<<'!r;Q`squ?Zr
+rr2ruqYpWts8N)urr<&urr<&ss8E#Jrr<&orr<&qs8E#urriE&!!*'!rW)osrW)uurW)uu!!*#u
+rW)rt!s&?$!;ZZo!<<'+!<<'!rr<'!rr<&ts8E#trr<&urr<&ts8Duus8E#srr<&srsAc+rrE'!
+!<<'!!<)rs!8.>N!;?GC~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!<3!#!<<'!rr3'#
+s8N)orr<&trrW9$rrE#t!!*#u!s&B$!;uis!<3!#!<<'!r;Q`spAY*mr;Q`sqYpWts8N)urr<&u
+rr<&rrr<&srr<&urr<&urr<&urrE-"r;cis!!)ut!!*#u!s&B$!;uis!<3!#!<<'!r;Q`squ?Zr
+rr2ruqYpWts8N)urr<&urr<&ss8E#Jrr<&orr<&qs8E#urriE&!!*'!rW)osrW)uurW)uu!!*#u
+rW)rt!s&?$!;ZZo!<<'+!<<'!rr<'!rr<&ts8E#trr<&urr<&ts8Duus8E#srr<&srsAc+rrE'!
+!<<'!!<)rs!8.>N!;?GC~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!<3!#!<<'!
+rr3'#s8N)orr<&trrW9$rrE#t!!*#u!s&B$!;uis!<3!#!<<'!r;Q`spAY*mr;Q`sqYpWts8N)u
+rr<&urr<&rrr<&srr<&urr<&urr<&urrE-"r;cis!!)ut!!*#u!s&B$!;uis!<3!#!<<'!r;Q`s
+qu?Zrrr2ruqYpWts8N)urr<&urr<&srrN1NJCOT!!;QQo!;c`p!<<'&!<3$!s8W&urVuiss8W&u
+s8N'!rr;rtrr3'#rr<&ps8E#ursAc+rrE'!!<<'!!<)rs!<2uu!<2uu!<)rs!!*&u!<)ot!;uj(
+!<<'!rr<'!rr<&ts8E#NrrN1NJG0"n~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)orq>gNp!!)rs!!*#u!s&B$!<)ot!<)rq!<<'!!<3!#!<<'!
+q#:<orVls"s8N)trr<&urrW9$rrDusquH`rrrE#trrDfnrrE&u!!)utr;clt!!*#uquHWo!!)rs
+!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDusquH`rrrE#trrDrr!s&B$!<)rr!<<'!!<3#r
+!;ulr!9!nW!;HKn!;QQo!;lcr!;uls!<2uu!<3!#!<<'!rr3'#s8N)urrW9$rrE&u#6=f(!!*'!
+!;ZWp!<3!.!<<'!!<<'!!<<'!s8N)urr<&rrr<&srr<&urr<&srr<&srsf&/rr<'!rr<'!rrE*!
+!<2uu!87DO!;?GC~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!)orq>gNp!!)rs!!*#u!s&B$!<)ot!<)rq!<<'!!<3!#!<<'!
+q#:<orVls"s8N)trr<&urrW9$rrDusquH`rrrE#trrDfnrrE&u!!)utr;clt!!*#uquHWo!!)rs
+!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDusquH`rrrE#trrDrr!s&B$!<)rr!<<'!!<3#r
+!;ulr!9!nW!;HKn!;QQo!;lcr!;uls!<2uu!<3!#!<<'!rr3'#s8N)urrW9$rrE&u#6=f(!!*'!
+!;ZWp!<3!.!<<'!!<<'!!<<'!s8N)urr<&rrr<&srr<&urr<&srr<&srsf&/rr<'!rr<'!rrE*!
+!<2uu!87DO!;?GC~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!)orq>gNp!!)rs!!*#u!s&B$!<)ot!<)rq!<<'!!<3!#
+!<<'!q#:<orVls"s8N)trr<&urrW9$rrDusquH`rrrE#trrDfnrrE&u!!)utr;clt!!*#uquHWo
+!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDusquH`rrrE#trrDrr!s&B$!<)rr!<<'!
+!<3#r!;uiu!.]UXs8Vlgrr<&orr<&rrr<&ss8N)urr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr33'
+s8N'!s8N)prr<&ursf&/rr<'!rr<'!rrE*!!<2uu!;lcr!;uis!<2uu!;uis!;uj,!<<'!!<<'!
+!<<'!s8N)urr<&PrrN1NJG0"n~>
+])Ma1VuQ_rR/[-dL]@8PrVuislMghaqYpNqq>^Eom/I%cq#:<oqu6Wrr;Q`srr3'#s8N)trr<&t
+rr<&rrr<&urrW9$rrDio!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`spAY3ps8N)urr<&u
+rrW9$rrE&u!!)cn!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus!!)fo!!)rs!!)rs
+!s&B$!<2uu!<3!#!<<'!rr2ruq#C<nhZ*TUq>UEpq#:<oqu6Wrr;Q`srVlitrr2ruqu6`us8N)u
+rrW9$rrE&u!s&B$!<2uu!;ZWp!<3!#!<<'!rr2rurr3'#s8N)urr<&rrr<&srr<&urr<&srr<&s
+rrW9$rrE&u!!*#u!s&B$!<2uu!87DO!;?GC~>
+])Ma1VuQ_rR/[-dL]@8PrVuislMghaqYpNqq>^Eom/I%cq#:<oqu6Wrr;Q`srr3'#s8N)trr<&t
+rr<&rrr<&urrW9$rrDio!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`spAY3ps8N)urr<&u
+rrW9$rrE&u!!)cn!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus!!)fo!!)rs!!)rs
+!s&B$!<2uu!<3!#!<<'!rr2ruq#C<nhZ*TUq>UEpq#:<oqu6Wrr;Q`srVlitrr2ruqu6`us8N)u
+rrW9$rrE&u!s&B$!<2uu!;ZWp!<3!#!<<'!rr2rurr3'#s8N)urr<&rrr<&srr<&urr<&srr<&s
+rrW9$rrE&u!!*#u!s&B$!<2uu!87DO!;?GC~>
+])Ma1VuHeuJ:O$e!!%fSquH]qrW)6`!!)lq!!)ip!W[b$m/I%cq#:<oqu6Wrr;Q`srr3'#s8N)t
+rr<&trr<&rrr<&urrW9$rrDio!!)ut!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`spAY3ps8N)u
+rr<&urrW9$rrE&u!!)cn!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus!!)fo!!)rs
+!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruq#:BqJ:QMVs7lEi!!)fo!!)or!!)rs!!)ut!!*#u!!)or
+!s&B$!<3!#!<<'!rr3'#s8N)urr<&prr<&urrW9$rrE&u!!*#u!s&B$!<2uu!;lcr!;uis!<2uu
+!;uis!;uj!!<<'!rr2rurr3'#s8N)urr<&PrrN1NJG0"n~>
+])Ma1VuQ_rR/[-df)G^Mrr2ru\GlO/q>UEprr2ruli-qbr;ZZpqu?Wqm/I%cq#:<oqu6Wrr;R!%
+s8N'!s8N)trr<&trr<&rrr<&urrW9$rrDiorrE&u!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`s
+pAY3ps8N)urr<&urrW9$rrE&u!!)cn!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus
+!!)fo!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruq#C<nh#I?Rr;Q`squ?Kmrr2rur;Q`srVucq
+rr;oss8N'!rr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$!<2uu!<3!"!<<)s!;lcr!;uis!<2uu
+!;uis!;uj!!<<'!rr2rurr3$"s8Vusg&M$OpA]X~>
+])Ma1VuQ_rR/[-df)G^Mrr2ru\GlO/q>UEprr2ruli-qbr;ZZpqu?Wqm/I%cq#:<oqu6Wrr;R!%
+s8N'!s8N)trr<&trr<&rrr<&urrW9$rrDiorrE&u!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<or;Q`s
+pAY3ps8N)urr<&urrW9$rrE&u!!)cn!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$rrDus
+!!)fo!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruq#C<nh#I?Rr;Q`squ?Kmrr2rur;Q`srVucq
+rr;oss8N'!rr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$!<2uu!<3!"!<<)s!;lcr!;uis!<2uu
+!;uis!;uj!!<<'!rr2rurr3$"s8Vusg&M$OpA]X~>
+])Ma1VuHeuJ:O$e!!(UM!!*#u!!'P/!!)ip!!*#u!!)?b!!)rsquHWo!W[b$m/I%cq#:<oqu6Wr
+r;R!%s8N'!s8N)trr<&trr<&rrr<&urrW9$rrDiorrE&u!s&B$!<)ot!<3!#!<<'!r;Q`sq#:<o
+r;Q`spAY3ps8N)urr<&urrW9$rrE&u!!)cn!!)rs!!*#u!!)ut"T\Q&s8N)rrr<&trr<&urrW9$
+rrDus!!)fo!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruq#:BqJ:QGTrqQEk!!)orq>gNp!!)rs
+!!)utquH`rr;clt!!*#u!s&B$!<3!#!<<'!rr2ruq>UEprr3'#s8N)urr<&urrN3#s82lorr<&s
+rr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quGFM!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqZ$Nps8N'!r;Qcts8E#trriE&!!*'!rVururW!!!!;uls!!*&u!<)rs
+!;QQr!<3$!rVuisrr33'rr<'!rr<&ts8E#ss8E#urr<&urr<&prr<&srrW9$rrE&u!!*#urW)rt
+"T\Q&!<3&urr`?%rr<&ps8E#brr<&orr<&qs8E#ts8N'%rrE*!!<)ot!;ulq!<<'!!<2uu!<2uu
+!;ZWq!<<#urr2rur;Z`rrVuisrr;oss8W&urr;rtq#C<nrVlitrr;lrs8N'!rr;oss8N'!rr;lr
+s8N'!rr2rurVlitrr2ruqu6Wrr;Z`rrVuisrr;oss8W&urr;rts8W#trVlitrr;lrs8N'!rr;os
+r;Z`rg&M'Prr2ruq#:<oqu6Wrr;Q`srVlitqu6Wrrr3'#s8N)urrW9$rrE&u!s&B$!<2uu!;ZWp
+!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!s&B$!7h,K!;?GC~>
+])Ma1VuQ_rR/[-dq#:<oqZ$Nps8N'!r;Qcts8E#trriE&!!*'!rVururW!!!!;uls!!*&u!<)rs
+!;QQr!<3$!rVuisrr33'rr<'!rr<&ts8E#ss8E#urr<&urr<&prr<&srrW9$rrE&u!!*#urW)rt
+"T\Q&!<3&urr`?%rr<&ps8E#brr<&orr<&qs8E#ts8N'%rrE*!!<)ot!;ulq!<<'!!<2uu!<2uu
+!;ZWq!<<#urr2rur;Z`rrVuisrr;oss8W&urr;rtq#C<nrVlitrr;lrs8N'!rr;oss8N'!rr;lr
+s8N'!rr2rurVlitrr2ruqu6Wrr;Z`rrVuisrr;oss8W&urr;rts8W#trVlitrr;lrs8N'!rr;os
+r;Z`rg&M'Prr2ruq#:<oqu6Wrr;Q`srVlitqu6Wrrr3'#s8N)urrW9$rrE&u!s&B$!<2uu!;ZWp
+!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!s&B$!7h,K!;?GC~>
+])Ma1VuHeuJ:O$e!!)fo!!)lqrW)uu!!)rs!<E0!!<3!%!<3$!s8W&u!<<#u!WN/ts8N'!s8E#s
+s8E#nrrW9$!!)utrW)rt#6=c(!<<'!!<)rs!<)rs!<<'!!<2uu!;ZWp!;uj!!<<'!rr2rurr;rt
+rr3-%rr<'!!<3!$!<<'!!;ZWr!.]Udrr<&orr<&qs8E#ts8N'%rrE*!!<)ot!;ulq!<<'!!<2uu
+!<2uu!;ZWq!<<#urr2rur;Z`rrVuisrr;oss8W&urr;rtq#C<nrVlitrr;lrs8N'!rr;oss8N'!
+rr;lrs8N'!rr2rurVlitrr2ruqu6Wrr;Z`rrVuisrr;oss8W&urr;rts8W#trVlitrr;lrs8N'!
+rr;osr;QfuJ:Q>Qs7lTn!!)fo!!)or!!)rs!!)ut!!)or!!*#u!s&B$!<3!#!<<'!rr3'#s8N)u
+rr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)L
+rrN1NJG0"n~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr3'#s8N)urrN3#!<3!*!<<'!!<<'!s8N)urrW9$rrDusrW)rt
+!s&B$!<2uu!;ZZp!<<'$!<<'!rr3H.s8N'!s8N'!s8N*!rrE&u!s&B$!;QQo!;ZWp!;uj!!<<'!
+rr3'#s8N)urr`?%rr<&urrW9$rrE&u!W`6#qZ$Npm/I%caT)2=s8N'!ec5RJJc>`MrW(RMrr<*"
+!;QQo!;lcr!;uis!<)ot!;lcr!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$!<2uu
+!<3!#!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrCULrW)ZlJ,~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr3'#s8N)urrN3#!<3!*!<<'!!<<'!s8N)urrW9$rrDusrW)rt
+!s&B$!<2uu!;ZZp!<<'$!<<'!rr3H.s8N'!s8N'!s8N*!rrE&u!s&B$!;QQo!;ZWp!;uj!!<<'!
+rr3'#s8N)urr`?%rr<&urrW9$rrE&u!W`6#qZ$Npm/I%caT)2=s8N'!ec5RJJc>`MrW(RMrr<*"
+!;QQo!;lcr!;uis!<)ot!;lcr!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$!<2uu
+!<3!#!<<'!p\t3nr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrCULrW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!<3!#!<<'!r;Z`r
+rr3'#s8N)urr<&ps8N*!rrW9$rrE&u%KQP/!!*'!!!*'!!<<'!rr3'#s8N)orr<&prr<&srrW9$
+rrE&u!s&B$!<3!$!<<'!!<3!#!<<'!rr3$"rrDoq!W[b$m/I%caT)2=s8N'!ec5RJJc>iP!.]UO
+s8ViprrDio!!)or!!)rs!!)ut!!)or!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&prr<&urrW9$
+rrE&u!!*#u!s&B$!;HKn!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3'#s8N)LrrN1NJG0"n~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr3'#s8N)urrN3#!<3!#!<<'!rr3'#s8N)urr<&urr<&urrN3#
+!<)p"!<<'!rr2ruq>UEprr2ruqu6`us8N)urr<&urrW9$rrE&u!s&B$!;QQo!;ZWp!;uj!!<<'!
+rr2ruqu6`us8N)trrN3#!;$6i!:9^c!5ea9!.k0ss3Lc@rr<&qs8E#urr<&ss8;rss82lsrrW9$
+rrE&urW)rt!!*#u!!)fo"p"]'!<<'!rr2rurr2rurr;oss8N'!rr;lrs8N'!rr2rurVlitr;Qj!
+s8N)urr<&urr<&us8;rNs8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr3'#s8N)urrN3#!<3!#!<<'!rr3'#s8N)urr<&urr<&urrN3#
+!<)p"!<<'!rr2ruq>UEprr2ruqu6`us8N)urr<&urrW9$rrE&u!s&B$!;QQo!;ZWp!;uj!!<<'!
+rr2ruqu6`us8N)trrN3#!;$6i!:9^c!5ea9!.k0ss3Lc@rr<&qs8E#urr<&ss8;rss82lsrrW9$
+rrE&urW)rt!!*#u!!)fo"p"]'!<<'!rr2rurr2rurr;oss8N'!rr;lrs8N'!rr2rurVlitr;Qj!
+s8N)urr<&urr<&us8;rNs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#u!s&B$!<3!"!<3&urrW9$rrE&u!s&B$!<2uu!<2uu!<3!"
+!<3&trrW9$rrE&u!!)ip!!*#u!!)or!s&B$!<2uu!<3!#!<<'!rr3'#s8N)orr<&prr<&srrW9$
+rrE&u!!)or!s&B$!<)p!!<3&jrrN1NJF*:9!5ea9!.k0srrN1NJCO>o!;QQo!;c`p!<<'!!;ulq
+!<3#r!<<'$!<<'!rr;rtrr2rurr2ruq#:Nus8N*!rrE&u!!*#u!!*#ur;clt!!*#uquHcs!!*#u
+!!)ut!!)rs!s&B$!<2uu!<2uu!<3#s!87AR!.]Uns*t~>
+])Ma1VuQ_rR/[-dqu?Kmrr;lrrr3*$rrE*!quHcs!!*#u!s&B$!<2uu!<2uu!<3!"!<3&trrN3#
+s82lmrr<&urr<&us8;rtrr<&urr<&urrN3#s82lrs8N)qrr<&srrW9$rrDus!s&B$!<2uu!<3#s
+!<<'!!<)rs!;$6i!:9^c!.k03s8E#Ms8N'"rrBt:r;_u[rW)ZlJ,~>
+])Ma1VuQ_rR/[-dqu?Kmrr;lrrr3*$rrE*!quHcs!!*#u!s&B$!<2uu!<2uu!<3!"!<3&trrN3#
+s82lmrr<&urr<&us8;rtrr<&urr<&urrN3#s82lrs8N)qrr<&srrW9$rrDus!s&B$!<2uu!<3#s
+!<<'!!<)rs!;$6i!:9^c!.k03s8E#Ms8N'"rrBt:r;_u[rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)orq>gNpquH`r"9AH%s8Vuss8N'!rr3'#s8N)urr<&urr<&urrN3#!<)p!
+!<<)s!;ZWp!<2uu!<3#s!<<'!!<2uu!<3!"!<<)s!<3#u!;c]q!;uj!!<<'!r;Qj!s8N)urr<&u
+s8;rtrr<&ts8E#irrN1NJF*:9!.k03rrN1NJCji$p]:Bp_uKZ8OoGI_J:R@nJ,~>
+])Ma1VuQ_rR/[-dq#:<oqu6WrqYp^!rrE*!!;lcr!<3!#!<<'!rr2rurVm$$rrE*!!<)p"!<<'!
+p&>!lrr3'#s8N)urrW9$rrE&u!!*#u!s&B$!;QQo!;lcr!;uj!!<<'!r;Qj!s8N)urrW9$rrE&u
+!s&B$!<)p"!<<'!o`+mjm/I%cJcCi3rW(XOrrE&u!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6WrqYp^!rrE*!!;lcr!<3!#!<<'!rr2rurVm$$rrE*!!<)p"!<<'!
+p&>!lrr3'#s8N)urrW9$rrE&u!!*#u!s&B$!;QQo!;lcr!;uj!!<<'!r;Qj!s8N)urrW9$rrE&u
+!s&B$!<)p"!<<'!o`+mjm/I%cJcCi3rW(XOrrE&u!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!)lq"T\Q&s8N)rrr<&urrW9$rrE&u!!)ut"T\Q&s8N)trrW9$
+rrD`l!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)orr<&rrr<&srrW9$rrDus!s&B$!<3!#!<<'!
+rr3'#s8N)trrW9$rrD]k!W[b$m/I%cJcCi3!W[b$g&M*Irr2ruJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6WrqYp^!rrE*!!;lcr!<3!#!<<'!rr2rurVm'%rrE*!!!*#u!s&B$
+!;6?l!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDio!!)lq!!)ut!!*#u!!*#u!!*#u#6=f(!!*'!
+!<3!#!<<'!rVlitrr2rup&G!km/I%cJcCi3rW(aRrW)lr!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6WrqYp^!rrE*!!;lcr!<3!#!<<'!rr2rurVm'%rrE*!!!*#u!s&B$
+!;6?l!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDio!!)lq!!)ut!!*#u!!*#u!!*#u#6=f(!!*'!
+!<3!#!<<'!rVlitrr2rup&G!km/I%cJcCi3rW(aRrW)lr!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!)lq"T\Q&s8N)rrr<&urrW9$rrE&u!!)ut"p"Z's8N'!rr3'#
+s8N)lrr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!q#:<oqYpNqrVlitrr2rurr2rurr33's8N'!
+s8N)urrW9$rrE#t!!*#u!!)]l!W[b$m/I%cJcCi3!W[b$h#IBKr;Q`sJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqZ$KorVlitrVufrs8N'!rr2rurr2rurr2rurVlitrr3!!s8E#ss8;rn
+rr<&urr<&us82itrrE&u!!*#u!!*#ur;cltrW)rt!!)rsquH]qrW)lrrr<*"!<3#r!!3*"rVlit
+rVlitpAb*lm/I%cJcCi3rW(gTrrDlp!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dq#:<oqZ$KorVlitrVufrs8N'!rr2rurr2rurr2rurVlitrr3!!s8E#ss8;rn
+rr<&urr<&us82itrrE&u!!*#u!!*#ur;cltrW)rt!!)rsquH]qrW)lrrr<*"!<3#r!!3*"rVlit
+rVlitpAb*lm/I%cJcCi3rW(gTrrDlp!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)lqr;cfr!!)utr;clt!!*#u!!*#u!!*#u!!)ut!!*#u!<E0!!<)rr
+!;ZWp!<2uu!<3#r!!3*"rr2rurr2rurr;oss8W&urr2rur;ZZprVuisr;Zcs!WN0!s82itrrE#t
+!!)ut!!)`m!W[b$m/I%cJcCi3!W[b$hZ*WNq>UEpJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dbl7YCrr2ruoDeaha8Z,>gAh-Pm/I%cJcCi3rW(mVrrDfn!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dbl7YCrr2ruoDeaha8Z,>gAh-Pm/I%cJcCi3rW(mVrrDfn!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!(7C!!*#u!!)Wjr;an<!!(aQ!W[b$m/I%cJcCi3!W[b$i;`iPp\t3nJcF'r
+!W[b$pA]X~>
+])Ma1VuQ_rR/[-dc2RbDrVlit[/^.+h#I?Rm/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dc2RbDrVlit[/^.+h#I?Rm/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!(:D!!)ut!!'D+rrCjS!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKnc&Rhir8uYkPkM^l2L_`p&Fjgs8N'!b5_G@
+pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKnc&Rhir8uYkPkM^l2L_`p&Fjgs8N'!b5_G@
+pA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)Qh!!)$Y!!)3^!!)9`!!)]lq>gQq
+!!(1A!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKec,ULkPkM^jo5;\r;Q`srr2rur;Q`s`;ff:
+pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKec,ULkPkM^jo5;\r;Q`srr2rur;Q`s`;ff:
+pA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!(RL!!)3^!!)-\!!)rs!!*#u!!)rs
+!!'t;!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<bJH1W/eGfLKq#:<oqu6j#s8N*!!!)utrW)rtrW)rt!<E/t!<<'!
+!<3#t!<3!#!<3$!q>^Eos8NE+s8N*!!!*'!!!)utrW)rt!!*#u!!)utrVururW)os!!)rs$3:,+
+!<3$!s8N'!rVuisg].6QpA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<bJH1W/eGfLKq#:<oqu6j#s8N*!!!)utrW)rtrW)rt!<E/t!<<'!
+!<3#t!<3!#!<3$!q>^Eos8NE+s8N*!!!*'!!!)utrW)rt!!*#u!!)utrVururW)os!!)rs$3:,+
+!<3$!s8N'!rVuisg].6QpA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"dJH1]1s+&W!!!)fo!!)or"p"]'!<3$!rVuisrr;rtrr3!!
+s82lsrr<&us8E#trrW9$!!)iprW)uu$3:,+!<3$!s8N'!rVuisrr2rurr2rurVuis!<<#urVlit
+r;R*(s8N*!!!*'!!!)utrW(^Q!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu7!'s8N'!s8N*!rrDus!!*#u"9AK%
+!!*#u!!*#u!s&B$!<3!'!<<'!!<<'!q>UEprr3H.s8N'!s8N'!s8N*!rrE&u!!)or!!)rs!!*#u
+!!)rs!!)rs%KQP/!!*'!!!*'!!<<'!rr2ruh#I?RpA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu7!'s8N'!s8N*!rrDus!!*#u"9AK%
+!!*#u!!*#u!s&B$!<3!'!<<'!!<<'!q>UEprr3H.s8N'!s8N'!s8N*!rrE&u!!)or!!)rs!!*#u
+!!)rs!!)rs%KQP/!!*'!!!*'!!<<'!rr2ruh#I?RpA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)or$3:,+!!*'!!<<'!r;Q`s
+rr3*$s8N'!rr2rurr3'#s8N)urs&Q(rr<'!rrDlp!!*#u%KQP/!!*'!!!*'!!<<'!rr2ruqu6Wr
+r;Q`srr2rur;Q`sr;R6,s8N'!s8N'!s8N*!rrE&u!!(gS!W[b$pA]X~>
+])Ma1VuQ_rR/[-ddf0CLs8N)Ds82lqs8E#`rr<&qrr<&]s8E#brr<%Ms,d9[!7_#K!;QQo!;lcu
+!<<'!rr3'#s8N)srr<&urrW9$rrE#t!!*#u!s&B$!<3!#!<<'!rr2ruq>UEprr3'#s8N)urr<&u
+rrW9$rrE&u!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruh#I?RpA]X~>
+])Ma1VuQ_rR/[-ddf0CLs8N)Ds82lqs8E#`rr<&qrr<&]s8E#brr<%Ms,d9[!7_#K!;QQo!;lcu
+!<<'!rr3'#s8N)srr<&urrW9$rrE#t!!*#u!s&B$!<3!#!<<'!rr2ruq>UEprr3'#s8N)urr<&u
+rrW9$rrE&u!!)or!!)rs!!*#u!!)rs!!)rs!s&B$!<2uu!<3!#!<<'!rr2ruh#I?RpA]X~>
+])Ma1VuHeuJ:O$e!!(II!s&B$!6tQA!<)rs!:'Ra!;c]q!9X:_!.]Udrr<%Ms,d6^!.]ULrr<&o
+rr<&rrrW9$rrE&u!s&B$!;uis!<3!#!<<'!rVlitrr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$
+!<2uu!<3!#!<<'!rr2ruqu6Wrr;Q`srr2rur;Q`sr;Qj!s8N)urr<&urrW9$rrE&u!!(gS!W[b$
+pA]X~>
+]DnT*R/[-ddf0CLs8N)Err<&prr<&urr<&brr<&ss82l\s8E#brr<%Ms,d9[!7_#K!;lfm!<3!#
+!<<'!rr2rurr;uurr;lrs8N'!rVlitrr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$!<2uu!<3!"
+!<<)s!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3$"s8Vush#I?RpA]X~>
+]DnT*R/[-ddf0CLs8N)Err<&prr<&urr<&brr<&ss82l\s8E#brr<%Ms,d9[!7_#K!;lfm!<3!#
+!<<'!rr2rurr;uurr;lrs8N'!rVlitrr3'#s8N)urrW9$rrE&u!!)ip!!*#u!s&B$!<2uu!<3!"
+!<<)s!;lcr!;uis!<2uu!;uis!;uj!!<<'!rr2rurr3$"s8Vush#I?RpA]X~>
+]DnZ,s+$L:!!(II!s&B$!7(TE!;ZWp!<2uu!:0Xb!;ulp!9jFa!.]Udrr<%Ms,d6^!.]ULrr<&r
+s7u`prrW9$rrE&u!!*#urrE&uquHcs!!)ut!!*#u!s&B$!<3!#!<<'!rr2ruq>UEprr3'#s8N)u
+rr<&urrN3#s82lorr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!W`9#quGOP!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqZ$Np!WN/trrE-"rW)rtrW)rtrW)rt!s&B$!;ZWs!<3$!rVuisrr33'
+rr<'!rr<&ts8E#ss8E#urr<&urr<&prr<&srrW9$rrE&u!!*#urW)rt"T\Q&!<3&urr`?%rr<&]
+s8E#brr<%Ms,d9[!7_#K!;QQo!;lcu!<<'!rr2rur;Qj!s8N)rrr<&trr<&urrW9$rrE&u!s&B$
+!<2uu!;ZWp!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!s&B$
+!8.>N!;?GC~>
+])Ma1VuQ_rR/[-dq#:<oqZ$Np!WN/trrE-"rW)rtrW)rtrW)rt!s&B$!;ZWs!<3$!rVuisrr33'
+rr<'!rr<&ts8E#ss8E#urr<&urr<&prr<&srrW9$rrE&u!!*#urW)rt"T\Q&!<3&urr`?%rr<&]
+s8E#brr<%Ms,d9[!7_#K!;QQo!;lcu!<<'!rr2rur;Qj!s8N)rrr<&trr<&urrW9$rrE&u!s&B$
+!<2uu!;ZWp!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urr<&srr<&srrW9$rrE&u!!*#u!s&B$
+!8.>N!;?GC~>
+])Ma1VuHeuJ:O$e!!)fo!!)lqrW!!!!;uit!<<#urr;rtrr;rtrr3'#s8N)prrW9$!!)utrW)rt
+#6=c(!<<'!!<)rs!<)rs!<<'!!<2uu!;ZWp!;uj!!<<'!rr2rurr;rtrr3-%rr<'!!<3!$!<<'!
+!9X:_!.]Udrr<%Ms,d6^!.]ULrr<&orr<&rrrW9$rrE&u!!)rs!s&B$!;lcr!<)ot!<3!#!<<'!
+rr3'#s8N)urr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uis!<2uu!;uis!;uj!!<<'!rr2ru
+rr3'#s8N)OrrN1NJG0"n~>
+])Ma1VuQ_rR/[-dq#:<oqu6WrrVlitr;Zcsr;Q`sr;Q`srr30&s8N*!rrDlprrE*!!s&B$!<3!.
+!<<'!!<<'!!<<'!s8N)urrW9$rrDio!!)ip!!)rs!s&B$!<3!#!<<'!rr3*$s8N'!rr3'#s8N)u
+rrN3#!9aC]!:9^c!.k03s8E#Jrr<&orr<&rrrW9$rrE&u!!)rs!s&B$!;lcr!<)ot!<3!#!<<'!
+rr3'#s8N)urr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uis!<2uu!;uis!;uj!!<<'!rr2ru
+rr3'#s8N)Os8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oqu6WrrVlitr;Zcsr;Q`sr;Q`srr30&s8N*!rrDlprrE*!!s&B$!<3!.
+!<<'!!<<'!!<<'!s8N)urrW9$rrDio!!)ip!!)rs!s&B$!<3!#!<<'!rr3*$s8N'!rr3'#s8N)u
+rrN3#!9aC]!:9^c!.k03s8E#Jrr<&orr<&rrrW9$rrE&u!!)rs!s&B$!;lcr!<)ot!<3!#!<<'!
+rr3'#s8N)urr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uis!<2uu!;uis!;uj!!<<'!rr2ru
+rr3'#s8N)Os8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!)ut!!)rsrrDus!!)rs!!*#u"p"]'!<<'!q>^Hps8N0$s8N)u
+rsf&/rr<'!rr<'!rrE*!!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$
+!<3!"!<3&^rrN1NJF*:9!.k03rrN1NJCOT!!;QQo!;lcu!<<'!rr2rur;Qj!s8N)rrr<&trr<&u
+rrW9$rrE&u!s&B$!<2uu!;ZWp!<3!#!<<'!rr2rurr3'#s8N)nrr<&srr<&urr<&srr<&srrW9$
+rrE&u!!*#u!s&B$!8.;Q!.]Uns*t~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrr;Q`srr3$"rrDus!!)fo"p"]'!<<'!q>UEprr2ruqu6`us8N)u
+rr<&urrW9$rrE&u!s&B$!;QQo!;ZWp!;uj!!<<'!rr2ruqu6`us8N)trrN3#!9!nV!:9^c!.k03
+s8E#Jrr<&orr<&rrrW9$rrE&u!W`9#rW)osr;clt!!)rs!s&B$!<3#t!<2uu!<2uu!;QQu!<<'!
+s8N)urr<&urr<&us8;rtrr<&us82lsrr<&urr<&trr<&srrW9$rrE&u!!*#u!!*#ur;bXQrW)Zl
+J,~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrr;Q`srr3$"rrDus!!)fo"p"]'!<<'!q>UEprr2ruqu6`us8N)u
+rr<&urrW9$rrE&u!s&B$!;QQo!;ZWp!;uj!!<<'!rr2ruqu6`us8N)trrN3#!9!nV!:9^c!.k03
+s8E#Jrr<&orr<&rrrW9$rrE&u!W`9#rW)osr;clt!!)rs!s&B$!<3#t!<2uu!<2uu!;QQu!<<'!
+s8N)urr<&urr<&us8;rtrr<&us82lsrr<&urr<&trr<&srrW9$rrE&u!!*#u!!*#ur;bXQrW)Zl
+J,~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!)rs!!*#u!W`6#r;Q`sq#:Nus8N*!rrDlp!!*#u!!)or!s&B$
+!<2uu!<3!#!<<'!rr3'#s8N)orr<&prr<&srrW9$rrE&u!!)or!s&B$!<)p!!<3&WrrN1NJF*:9
+!.k03rrN1NJCOT!!;QQo!;lcu!<<'!rr3$"s8W&urVufrs8N'!r;Qj!s8N)us8E#trr<&urr<&o
+rrrK'rrE*!!<2uu!<2uu!<3#s!<<'!!<3#r!<<'!!<2uu!<)ot!;uj!!<<'!rr2rurr2rurr;os
+h#@EUJ:R@nJ,~>
+])Ma1VuQ_rR/[-dqu?KmrVultrr2rurr3*$s8N'!rr2ruqu?Tps8N0$s8N)prr<&urr<&us8;rt
+rr<&urr<&urrN3#s82lrs8N)qrr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!!<)rs!9!nV!:9^c
+!.k03s8E#Jrr<&7s8;q^s8E#ls*t~>
+])Ma1VuQ_rR/[-dqu?KmrVultrr2rurr3*$s8N'!rr2ruqu?Tps8N0$s8N)prr<&urr<&us8;rt
+rr<&urr<&urrN3#s82lrs8N)qrr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!!<)rs!9!nV!:9^c
+!.k03s8E#Jrr<&7s8;q^s8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)orq>gKorrE&u!!*#u"9AK%!!*#u!!)orr;clt!s&B$!;ZWp!<2uu!<3#s
+!<<'!!<2uu!<3!"!<<)s!<3#u!;c]q!;uj!!<<'!r;Qj!s8N)urr<&us8;rtrr<&ts8E#VrrN1N
+JF*:9!.k03rrN1NJCOT!!5SX5!0mKb!.]Uns*t~>
+])Ma1VuQ_rR/[-dq#:<oq#:<orr3$"rrDus!s&B$!;uis!<3!&!<<'!s8N)prr<&urrW9$rrE&u
+!s&B$!<2uu!<3!#!<<'!q#:<oqu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)X
+s8E#brr<%Ms,d9[!7_#K!.k0rs8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oq#:<orr3$"rrDus!s&B$!;uis!<3!&!<<'!s8N)prr<&urrW9$rrE&u
+!s&B$!<2uu!<3!#!<<'!q#:<oqu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)X
+s8E#brr<%Ms,d9[!7_#K!.k0rs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)fo!!*#u!W`6#r;Qj!s8N)srr<&urrrK'rrE*!!;ZWp!<3!#!<<'!
+rr3'#s8N)urr<&urrW9$rrDio!!)or!!)rs!s&B$!;uj!!<<'!rr3'#s8N)urrW9$rrE#t!s&B$
+!9*qZ!.]Udrr<%Ms,d6^!.]ULrr<%Ms3L]H!.]Uns*t~>
+])Ma1VuQ_rR/[-dq#:<oq#:<orr3$"rrDus!s&B$!;uis!<3!&!<<'!s8N)prr<&urrW9$rrE&u
+!s&B$!<2uu!<3!#!<<'!q#:<oqYpNqrVlitrr2rurr2rurr33's8N'!s8N)urrW9$rrE#t!!*#u
+!!)$YrW)<b!!%TMOT5:[eGfLKJcF'rrW)ZlJ,~>
+])Ma1VuQ_rR/[-dq#:<oq#:<orr3$"rrDus!s&B$!;uis!<3!&!<<'!s8N)prr<&urrW9$rrE&u
+!s&B$!<2uu!<3!#!<<'!q#:<oqYpNqrVlitrr2rurr2rurr33's8N'!s8N)urrW9$rrE#t!!*#u
+!!)$YrW)<b!!%TMOT5:[eGfLKJcF'rrW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)fo!!)fo!!*#u!W`6#r;Qj!s8N)srr<&urrrK'rrE*!!;ZWp!<3!#!<<'!
+rr3'#s8N)urr<&urrW9$rrDio!!)lq!!)ut!!*#u!!*#u!!*#u#6=f(!!*'!!<3!#!<<'!rVlit
+rr2ruir9&[J:R"d!!%TMOT,@^J:Q/L!!%TMci4%HJ:R@nJ,~>
+])Ma1VuQ_rR/[-dq#:<oqu?Wqr;Q`srr;rtrVuisrr;lr"TJK%rrDlp!!*#u!!*#uqu?ct!<2uu
+!<2uu!<3#s!<<)u!<2uu!;ulp!<)rs!;uls!!3*"rr;lr!WN/urr<&trr<&Zs8E#brr<%Ms,d9[
+!7_#K!.k0rs8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oqu?Wqr;Q`srr;rtrVuisrr;lr"TJK%rrDlp!!*#u!!*#uqu?ct!<2uu
+!<2uu!<3#s!<<)u!<2uu!;ulp!<)rs!;uls!!3*"rr;lr!WN/urr<&trr<&Zs8E#brr<%Ms,d9[
+!7_#K!.k0rs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)orrW)lr!!*#urW)osrW)rtqu?m"!<<'!q>UEprr2rurr;lr!WN0!
+rr<&urr<&us8;rts8E#trr<&ss82lqs8E#rs8N'"rrE&uqu?ct!<)ot!<)ot!9=(\!.]Udrr<%M
+s,d6^!.]ULrr<%Ms3L]H!.]Uns*t~>
+])Ma1VuQ_rR/[-dl2L_`jo>8Za8Z,>a8c,=m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dl2L_`jo>8Za8Z,>a8c,=m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)9`!!)-\r;an<!!((>!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dlMghaV>pPqaoD>?m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-dlMghaV>pPqaoD>?m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)<a!!&kqrrC1@!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKbQ%J?rVuislMghaWW2qtpA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKbQ%J?rVuislMghaWW2qtpA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!(4BquH]qrW)6`!!'"u!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKbl7YCq>UEprr2ruli-qbWW2qtpA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKbl7YCq>UEprr2ruli-qbWW2qtpA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!(7C!!)ip!!*#u!!)?b!!'"u!W[b$
+pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu6`urr<&ts8E#trs&Q(!!*'!!!)ut
+rW)rt!!*#u!!)ip!!)rs!s&B$!<2uu!<3#t!<3!%!<3$!rrE&u!!'/$rW)ZlJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu6`urr<&ts8E#trs&Q(!!*'!!!)ut
+rW)rt!!*#u!!)ip!!)rs!s&B$!<2uu!<3#t!<3!%!<3$!rrE&u!!'/$rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)or!s&?$!<)rs!<3!'!<3$!
+s8N'!rVuisrr2rurr2ruq>UEpr;Qj!s8N)urr<&us8E#trriE&!!*$!rr2ruXoAG&J:R@nJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu?Zrs8N0$s8N)ursf&/rr<'!rr<'!
+rrE*!!<2uu!;lcr!;ZWp!;uj!!<<'!rr3'#s8N)urr`?%rr<&urrW9$rrB/#rW)ZlJ,~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu?Zrs8N0$s8N)ursf&/rr<'!rr<'!
+rrE*!!<2uu!;lcr!;ZWp!;uj!!<<'!rr3'#s8N)urr`?%rr<&urrW9$rrB/#rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)orrrE*!!s&B$!<3!.!<<'!
+!<<'!!<<'!s8N)urr<&rrr<&prr<&srrW9$rrE&u!s&B$!<3!$!<<'!!<3!#!<<'!XT&>%J:R@n
+J,~>
+])Ma1VuQ_rR/[-dVuQYprVuislMghaqYpNqg&M$Om/I%cJcCi3rW(IJ!!)fo!!)or!!*#u!!)or
+!s&B$!<2uu!<3!#!<<'!rr2ruqu6Wrq>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#X8i/!pA]X~>
+])Ma1VuQ_rR/[-dVuQYprVuislMghaqYpNqg&M$Om/I%cJcCi3rW(IJ!!)fo!!)or!!*#u!!)or
+!s&B$!<2uu!<3!#!<<'!rr2ruqu6Wrq>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#X8i/!pA]X~>
+])Ma1VuHeuJ:O$e!!&qsquH]qrW)6`!!)lq!!(^P!W[b$m/I%cJcCi3!W[b$eGfLKq#:<oqu6Wr
+rr2ruqu6`us8N)urr<&urrW9$rrE&u!!)or!!)ip!!)rs!s&B$!<2uu!;lcu!<<'!rVlp!rrB,"
+!W[b$pA]X~>
+])Ma1VuQ_rR/[-dnc&Rh\c2X0q>UEprr2ruli-qbr;ZZpg].6Qm/I%cJcCi3rW(IJ!!)orq>gNp
+!!*#u!!*#ur;clt!!*#u!!*#u!W`9#quHWo!!)rs!s&B$!;uj!!<<'!rr2rurr;oss8N'!rVuis
+X8i/!pA]X~>
+])Ma1VuQ_rR/[-dnc&Rh\c2X0q>UEprr2ruli-qbr;ZZpg].6Qm/I%cJcCi3rW(IJ!!)orq>gNp
+!!*#u!!*#ur;clt!!*#u!!*#u!W`9#quHWo!!)rs!s&B$!;uj!!<<'!rr2rurr;oss8N'!rVuis
+X8i/!pA]X~>
+])Ma1VuHeuJ:O$e!!)Qh!!'S0!!)ip!!*#u!!)?b!!)rsquGLO!W[b$m/I%cJcCi3!W[b$eGfLK
+qu?Kmrr2rurr2rurr;oss8N'!rr2rurr3$"s8Vusqu6Wrr;Qj!s8N)srrW9$rrE&u!!*#ur;clt
+!!)utrW'#!!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<or;Z`rs8N6&rr<'!s8E#trrE-"rW)`n!s&?$!<)rs!<3!'!<3$!s8N'!
+rVuisrVuiss8N'!rr2ruq>UEpr;Qj!s8N)urr<&us8E#trriE&!!*$!rr3*$s8N'!g&M$Om/I%c
+JcCi3rW(IJ!!)fo!!)or!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)nrr<&srrW9$rrDus!s&B$
+!<3!#!<<'!rr3'#s8N)trrW9$rrB/#rW)ZlJ,~>
+])Ma1VuQ_rR/[-dq#:<or;Z`rs8N6&rr<'!s8E#trrE-"rW)`n!s&?$!<)rs!<3!'!<3$!s8N'!
+rVuisrVuiss8N'!rr2ruq>UEpr;Qj!s8N)urr<&us8E#trriE&!!*$!rr3*$s8N'!g&M$Om/I%c
+JcCi3rW(IJ!!)fo!!)or!!*#u!s&B$!<3!#!<<'!rr2rurr3'#s8N)nrr<&srrW9$rrDus!s&B$
+!<3!#!<<'!rr3'#s8N)trrW9$rrB/#rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)fo!!)rsrW)uu"T\Q&!<<)u!<3!!!<<#uq#:Errr<&ts8E#trs&Q(!!*'!
+!!)utrW)osrW)uu!!*#u!!)ip!!)rs!s&B$!<2uu!<3#t!<3!%!<3$!rrE&u"9AK%!!(^P!W[b$
+m/I%cJcCi3!W[b$eGfLKq#:<oqu6Wrrr3'#s8N)urrW9$rrE&u!!*#u!s&B$!;HKn!;uj!!<<'!
+r;Qj!s8N)urrW9$rrE&u!s&B$!<)p"!<<'!XT&>%J:R@nJ,~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr;uurr2rurr3*$s8N'!rr2ruq>^Hps8N0$s8N)ursf&/rr<'!
+rr<'!rrE*!!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$!<3!"!<3&Q
+s8E#brr<%Ms,d9[!7_#K!;QQo!;lcr!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDcm!!)ut!!*#u
+!!*#u!!*#u#6=f(!!*'!!<3!#!<<'!rVlitrr2ruXoJA#pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr;uurr2rurr3*$s8N'!rr2ruq>^Hps8N0$s8N)ursf&/rr<'!
+rr<'!rrE*!!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$!<3!"!<3&Q
+s8E#brr<%Ms,d9[!7_#K!;QQo!;lcr!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDcm!!)ut!!*#u
+!!*#u!!*#u#6=f(!!*'!!<3!#!<<'!rVlitrr2ruXoJA#pA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#urrE&u!!*#u"9AK%!!*#u!!)iprrE*!!s&B$!<3!.!<<'!
+!<<'!!<<'!s8N)urrW9$rrDio!!)ip!!)rs!s&B$!<3!#!<<'!rr3*$s8N'!rr3'#s8N)urrN3#
+!8@GS!.]Udrr<%Ms,d6^!.]ULrr<&orr<&rrr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!pAY*m
+rVlitrr2rurr2rurr33's8N'!s8N)urrW9$rrE#t!!*#u!!'/$!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr2ruq>UNss8N)trr<&prr<&urr<&rrrW9$rrE&u!!*#u!s&B$
+!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#e,TCIm/I%cJcCi3rW(IJ!!)fo
+!!)or!!*#u!!*#uqu?ct!<2uu!<2uu!<3#s!<<'!!;ulp!<)rs!;uls!!3*"rr;lr!WN/urr<&t
+rr<&%s8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr2ruq>UNss8N)trr<&prr<&urr<&rrrW9$rrE&u!!*#u!s&B$
+!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#e,TCIm/I%cJcCi3rW(IJ!!)fo
+!!)or!!*#u!!*#uqu?ct!<2uu!<2uu!<3#s!<<'!!;ulp!<)rs!;uls!!3*"rr;lr!WN/urr<&t
+rr<&%s8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#u!!)ip!s&B$!<)ot!;ZWp!<2uu!;lcu!<<'!rr2rurr3'#
+s8N)urrW9$rrDio!!)ip!!)rs!s&B$!<2uu!;lcu!<<'!rVlp!rrCOJ!W[b$m/I%cJcCi3!W[b$
+eGfLKq#:<oqu6Wrrr2rurr;lr!WN0!rr<&urr<&us8;rtrr<&ss82lqs8E#rs8N'"rrE&uqu?ct
+!<)ot!<)ot!3Z>'!.]Uns*t~>
+])Ma1VuQ_rR/[-dqu?Kmrr2rurr2rur;Z]qs8N'!rVlitq>UEprr2rurr;oss8N'!rr2rurr3$"
+s8Vusrr;uuqYpNqr;Qj!s8N)srrW9$rrE&u!!*#ur;clt!!)utrW(FIrW)<b!!%TMOT5:[eGfLK
+^]+96P5kL]pA]X~>
+])Ma1VuQ_rR/[-dqu?Kmrr2rurr2rur;Z]qs8N'!rVlitq>UEprr2rurr;oss8N'!rr2rurr3$"
+s8Vusrr;uuqYpNqr;Qj!s8N)srrW9$rrE&u!!*#ur;clt!!)utrW(FIrW)<b!!%TMOT5:[eGfLK
+^]+96P5kL]pA]X~>
+])Ma1VuHeuJ:O$e!!)orq>gNp!!*#u!!)rsr;clt!!)ut!!)ip!!*#u!!*#ur;clt!!*#u!!*#u
+!W`9#quH`rrrDoq!!)rs!s&B$!;uj!!<<'!rr2rurr;oss8N'!rVuise,KILJ:R"d!!%TMOT,@^
+J:Q/L!!'e6!!&2^!W[b$pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr2rurVlitrr3'#s8N)trr<&prr<&urrW9$rrE&u!s&B$!<2uu
+!<3!#!<<'!q#:<oqu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)Ks8E#brr<%M
+s,d9[!7_#K!5AL5!0mN_!;?GC~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr2rurVlitrr3'#s8N)trr<&prr<&urrW9$rrE&u!s&B$!<2uu
+!<3!#!<<'!q#:<oqu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)Ks8E#brr<%M
+s,d9[!7_#K!5AL5!0mN_!;?GC~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#u!!)ut!!*#u!s&B$!<)ot!;ZWp!<3!#!<<'!rr3'#s8N)u
+rr<&urrW9$rrDio!!)or!!)rs!s&B$!;uj!!<<'!rr3'#s8N)urrW9$rrE#t!s&B$!7_#M!.]Ud
+rr<%Ms,d6^!.]ULrr<&5s8N(`rrN1NJG0"n~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr2rurVlitrr3*$s8N'!rr2ruq>UEprr3'#s8N)urrW9$rrE&u
+!!*#u!s&B$!;QQo!;c]q!<)ot!<2uu!<2uu!<3!'!<<'!!<<'!rr3'#s8N)trr<&urr<&Ls8E#b
+rr<%Ms,d9[!7_#K!.k0rs8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oqu6Wrrr2rurVlitrr3*$s8N'!rr2ruq>UEprr3'#s8N)urrW9$rrE&u
+!!*#u!s&B$!;QQo!;c]q!<)ot!<2uu!<2uu!<3!'!<<'!!<<'!rr3'#s8N)trr<&urr<&Ls8E#b
+rr<%Ms,d9[!7_#K!.k0rs8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)or!!*#u!!)ut!!*#u"9AK%!!*#u!!)ip!!*#u!s&B$!<3!#!<<'!
+rr2rurr3'#s8N)orr<&qrr<&trr<&urr<&urr<&urs&Q(rr<'!rrE&u!s&B$!<)ot!<2uu!7h)N
+!.]Udrr<%Ms,d6^!.]ULrr<%Ms3L]H!.]Uns*t~>
+])Ma1VuQ_rR/[-dq#:<oqYpWts8N)ss82iurrE)u!;QQo!<2uu!<3#r!!3*"rr2rurr2rurr;os
+s8W&urr2rur;ZZprVuisr;Zcs!WN0!s82itrrE#t!!)ut!!(UMrW)<b!!%TMOT5:[eGfLKJcF'r
+rW)ZlJ,~>
+])Ma1VuQ_rR/[-dq#:<oqYpWts8N)ss82iurrE)u!;QQo!<2uu!<3#r!!3*"rr2rurr2rurr;os
+s8W&urr2rur;ZZprVuisr;Zcs!WN0!s82itrrE#t!!)ut!!(UMrW)<b!!%TMOT5:[eGfLKJcF'r
+rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)fo!!)lq!s&B$!;ulp!!<0#s8E#nrr<&urr<&us82itrrE&u!!*#u!!*#u
+r;cltrW)rt!!)rsquH]qrW)lrrr<*"!<3#r!!3*"rVlitrVlitf)GdOJ:R"d!!%TMOT,@^J:Q/L
+!!%TMci4%HJ:R@nJ,~>
+])Ma1VuQ_rR/[-diVrlXqZ$Koa8Z,>])Va0m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-diVrlXqZ$Koa8Z,>])Va0m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)!X!!)lqr;an<!!'V1!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-diVrlX]Dqm2]`7s2m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuQ_rR/[-diVrlX]Dqm2]`7s2m/I%cJcCi3rW(IJ!!%TMci<tEpA]X~>
+])Ma1VuHeuJ:O$e!!)!X!!'Y2rrB_3!W[b$m/I%cJcCi3!W[b$eGfLKJcF'r!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKl2L_`qYpNqp&>!lkPtG[rVuislMgha]Dqj1
+pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKl2L_`qYpNqp&>!lkPtG[rVuislMgha]Dqj1
+pA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)9`!!)lq!!)]l!!)3^quH]qrW)6`
+!!'Y2!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKiVrlXq>UEpjSo2[q>UEprr2ruli-qb]Dqj1
+pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKiVrlXq>UEpjSo2[q>UEprr2ruli-qb]Dqj1
+pA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)!X!!)ip!!)*[!!)ip!!*#u!!)?b
+!!'Y2!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu6Zss8E#trr<&us8E!!rrDoqrW)uu
+$3:,+!<3$!s8N'!rVuisrr2rurr2ruq>UEpr;Qj!s8N)urr<&us8E#trriE&!!*$!rr2ru^]495
+pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu6Zss8E#trr<&us8E!!rrDoqrW)uu
+$3:,+!<3$!s8N'!rVuisrr2rurr2ruq>UEpr;Qj!s8N)urr<&us8E#trriE&!!*$!rr2ru^]495
+pA]X~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)or!<E0!!<2uu!<3#t!!3*"
+qZ$Nps8NE+s8N*!!!*'!!!)utrW)rt!!*#u!!)ip!!)rs!s&B$!<2uu!<3#t!<3!%!<3$!rrE&u
+!!'e6!W[b$pA]X~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu?Zrrr30&s8N*!rrE&urrDlp!!*#u%
+KQP/!!*'!!!*'!!<<'!rr2ruqu6Wrq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$!5AL4!
+;?GC~>
+])Ma1VuQ_rR/[-dJcF4!rW)<b!!%TMOT5:[eGfLKq#:<oqu?Zrrr30&s8N*!rrE&urrDlp!!*#u%
+KQP/!!*'!!!*'!!<<'!rr2ruqu6Wrq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$!5AL4!
+;?GC~>
+])Ma1VuHeuJ:O$e!!%TMe,KILJ:R"d!!%TMOT,@^J:Q/L!!)fo!!)orrrE&u"p"]'!<<'!rr;uu
+q>UEprr3H.s8N'!s8N'!s8N*!rrE&u!!)or!!)ip!!)rs!s&B$!<3!#!<<'!rr3*$s8N'!rr3'#
+s8N)5rrN1NJG0"n~>
+])Ma1VuQ_rR/[-dnc&Rh_#O<4rVuislMghaqYpNqdJs1Gm/I%cJcCi3rW(IJ!!)fo!!)or!!)ut
+"p"]'!<<'!rVlitq>UEprr3'#s8N)urr<&urrW9$rrE&u!!)or!!)ip!!)rs!s&B$!<2uu!;lcu
+!<<'!rVlp!rrBb4rW)ZlJ,~>
+])Ma1VuQ_rR/[-dnc&Rh_#O<4rVuislMghaqYpNqdJs1Gm/I%cJcCi3rW(IJ!!)fo!!)or!!)ut
+"p"]'!<<'!rVlitq>UEprr3'#s8N)urr<&urrW9$rrE&u!!)or!!)ip!!)rs!s&B$!<2uu!;lcu
+!<<'!rVlp!rrBb4rW)ZlJ,~>
+])Ma1VuHeuJ:O$e!!)Qh!!'h7quH]qrW)6`!!)lq!!(FH!W[b$m/I%cJcCi3!W[b$eGfLKq#:<o
+qu6WrrVm'%s8N*!rrE#t!!)ip!!*#u!s&B$!<2uu!<3!#!<<'!rr2ruqu6Wrq>UEpr;Qj!s8N)u
+rr<&rrrW9$rrE#t!W`6#^&J-6J:R@nJ,~>
+])Ma1VuQ_rR/[-dYl=\'q>UEprr2ruli-qbr;ZZpe,TCIm/MV:Mu_B-!!)orq>gNp!!)ut"p"]'
+!<<'!rVlitq>UEprr3'#s8N)urr<&urrN3#s82lorr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!
+!<)rs!58F3!;?GC~>
+])Ma1VuQ_rR/[-dYl=\'q>UEprr2ruli-qbr;ZZpe,TCIm/MV:Mu_B-!!)orq>gNp!!)ut"p"]'
+!<<'!rVlitq>UEprr3'#s8N)urr<&urrN3#s82lorr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!
+!<)rs!58F3!;?GC~>
+])Ma1VuHeuJ:O$e!!'8'!!)ip!!*#u!!)?b!!)rsquG4G!W[b$m/MV:NWB*0eGfLKqu?Kmrr2ru
+rVm'%s8N*!rrE#t!!)ip!!*#u!s&B$!<2uu!<3!"!<<)s!;lcr!;uj!!<<'!r;Qj!s8N)urr<&u
+s8;rtrr<&ts8E#3rrN1NJG0"n~>
+])Ma1VuQ_rR/[-dq#:<oqu6p%s8N*!!!*'!rW!!!!;ZWs!<3$!rVuisrr33'rr<'!rr<&ts8E#s
+s8E#urr<&urr<&prr<&srrW9$rrE&u!!*#urW)rt"T\Q&!<3&urr`?%rr<&Hs8E#_s+(02!7_#K
+!;QQo!;lcr!<)p%!<<'!s8N)trr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uj!!<<'!r;Qj!
+s8N)urrW9$rrE&u!s&B$!<)p"!<<'!^An04pA]X~>
+])Ma1VuQ_rR/[-dq#:<oqu6p%s8N*!!!*'!rW!!!!;ZWs!<3$!rVuisrr33'rr<'!rr<&ts8E#s
+s8E#urr<&urr<&prr<&srrW9$rrE&u!!*#urW)rt"T\Q&!<3&urr`?%rr<&Hs8E#_s+(02!7_#K
+!;QQo!;lcr!<)p%!<<'!s8N)trr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uj!!<<'!r;Qj!
+s8N)urrW9$rrE&u!s&B$!<)p"!<<'!^An04pA]X~>
+])Ma1VuHeuJ:O$e!!)fo!!)or#QXo)!<3$!s8W&u!WN/qrrW9$!!)utrW)rt#6=c(!<<'!!<)rs
+!<)rs!<<'!!<2uu!;ZWp!;uj!!<<'!rr2rurr;rtrr3-%rr<'!!<3!$!<<'!!7CfJ!.]Uas+,]]
+JCOT!!;QQo!;lcr!<)p%!<<'!s8N)trr<&prr<&urrW9$rrE&u!!*#u!s&B$!;HKn!;uj!!<<'!
+r;Qj!s8N)urrW9$rrE&u!s&B$!<)p"!<<'!^Ae67J:R@nJ,~>
+])Ma1VuQ_rR/[-dq#:<oqu6d!s8N'!rr2rurr;uuq>^Hps8N0$s8N)ursf&/rr<'!rr<'!rrE*!
+!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$!<3!"!<3&Is8E#_s+(02
+!7_#K!;QQo!;lfr!<3!&!<<'!s8N)us8N)prr<&urrW9$rrE&u!!*#u!s&B$!;?Em!<)ot!<2uu
+!<2uu!<3!'!<<'!!<<'!rr3'#s8N)trr<&urr<&6s8E#ls*t~>
+])Ma1VuQ_rR/[-dq#:<oqu6d!s8N'!rr2rurr;uuq>^Hps8N0$s8N)ursf&/rr<'!rr<'!rrE*!
+!<3!#!<<'!q#:<oq>UEpr;Qj!s8N)urrW9$rrE&u"9AK%!!*#u!s&B$!<3!"!<3&Is8E#_s+(02
+!7_#K!;QQo!;lfr!<3!&!<<'!s8N)us8N)prr<&urrW9$rrE&u!!*#u!s&B$!;?Em!<)ot!<2uu
+!<2uu!<3!'!<<'!!<<'!rr3'#s8N)trr<&urr<&6s8E#ls*t~>
+])Ma1VuHeuJ:O$e!!)fo!!)or"9AK%!!*#u!!*#urrDlprrE*!!s&B$!<3!.!<<'!!<<'!!<<'!
+s8N)urrW9$rrDio!!)ip!!)rs!s&B$!<3!#!<<'!rr3*$s8N'!rr3'#s8N)urrN3#!7LlK!.]Ua
+s+,]]JCOT!!;QQo!;lfr!<3!&!<<'!s8N)us8N)prr<&urrW9$rrE&u!!*#u!s&B$!;?Em!<)ot
+!<2uu!<2uu!<3!'!<<'!!<<'!rr3'#s8N)trr<&urr<&6rrN1NJG0"n~>
+])SN*R/[-dq#:<oqu6`us8N)trr<&trr<&prr<&urr<&rrrW9$rrE&u!!*#u!s&B$!<3!#!<<'!
+q#:<oq>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#bQ%PAJcG$8!!%TMir8uYq#:<oqu6Zss8E#t
+rr<&us8E!!rrDio"p"]'!<<'!rr2rurr2rurr;oss8N'!r;ZZprVuisr;Zcs!WN0!s82itrrE#t
+!!)ut!!'h7rW)ZlJ,~>
+])SN*R/[-dq#:<oqu6`us8N)trr<&trr<&prr<&urr<&rrrW9$rrE&u!!*#u!s&B$!<3!#!<<'!
+q#:<oq>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#bQ%PAJcG$8!'l,8ir8uYq#:<oqu6Zss8E#t
+rr<&us8E!!rrDio"p"]'!<<'!rr2rurr2rurr;oss8N'!r;ZZprVuisr;Zcs!WN0!s82itrrE#t
+!!)ut!!'h7rW)ZlJ,~>
+])ST,s+$L:!!)fo!!)or!s&B$!<)ot!<)ot!;ZWp!<2uu!;lcu!<<'!rr2rurr3'#s8N)urrW9$
+rrDio!!)ip!!)rs!s&B$!<2uu!;lcu!<<'!rVlp!rrC7B!W[b$JcG$8!'l,8ir8uYq#:<oqu6Zs
+s8E#trr<&us8E!!rrDio"p"]'!<<'!rr2rurr2rurr;oss8N'!r;ZZprVuisr;Zcs!WN0!s82it
+rrE#t!!)ut!!'h7!W[b$pA]X~>
+\,W<*R/[-dqu?Kmrr3'#s8N)trr<&trr<&prr<&urr<&us8;rtrr<&urr<&urrN3#s82lrs8N)q
+rr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!!<)rs!6bEA!.k18rr<%Ms5O%Y!:g'h!:Tsd!7_#K
+!2TYo!;?GC~>
+\,W<*R/[-dqu?Kmrr3'#s8N)trr<&trr<&prr<&urr<&us8;rtrr<&urr<&urrN3#s82lrs8N)q
+rr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!!<)rs!6bEA!.k18rr><8s5O%Y!:g'h!:Tsd!7_#K
+!2TYo!;?GC~>
+\,W=UR/[-dqu?Kmrr3'#s8N)trr<&trr<&prr<&urr<&us8;rtrr<&urr<&urrN3#s82lrs8N)q
+rr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!!<)rs!6bBD!.]TNs6BUa5_8sprr<&hrr<&fs8;rI
+rr<%prrN1NJG0"n~>
+\,W<*R/[-dq#:<oqu6`us8N)trr<&trr<&prr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!q#:<o
+qu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)Cs8E"Ls6K[d!<3%Ms5X+Z!:g'h
+!58F4!2feq!;?GC~>
+\,W<*R/[-dq#:<oqu6`us8N)trr<&trr<&prr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!q#:<o
+qu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)Cs8E"Ls6K[d5lX*#s5X+Z!:g'h
+!58F4!2feq!;?GC~>
+\,W=UR/[-dq#:<oqu6`us8N)trr<&trr<&prr<&urrW9$rrE&u!s&B$!<2uu!<3!#!<<'!q#:<o
+qu6Wrr;Qj!s8N)srrW9$rrE&u!s&B$!<3!#!<<'!rVls"s8N)CrrN1NJ:[adrrPIc5_8sqrr<&h
+rr<&4s8N(rrrN1NJG0"n~>
+MuWeWJcG'9!!)fo!!)or!s&B$!<)ot!<3#u!;ZWp!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDio
+!!)lq!!)ut!!*#u!!*#u!!*#u#6=f(!!*'!!<3!#!<<'!rVlitrr2ruc2[bCJcG'9!W`6#JcFd1
+!!%TMci<tEpA]X~>
+MuWfBJcG'9!!)fo!!)or!s&B$!<)ot!<3#u!;ZWp!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDio
+!!)lq!!)ut!!*#u!!*#u!!*#u#6=f(!!*'!!<3!#!<<'!rVlitrr2ruc2[bCJcG'9!^QcNJcFd1
+!!%TMci<tEpA]X~>
+MuWfBJcG'9!!)fo!!)or!s&B$!<)ot!<3#u!;ZWp!<3!#!<<'!rr3'#s8N)urr<&urrW9$rrDio
+!!)lq!!)ut!!*#u!!*#u!!*#u#6=f(!!*'!!<3!#!<<'!rVlitrr2ruc2RhFJ:N4Nli.#Os$2/8
+j8T)ZJcF'r!W[b$pA]X~>
+MuWeWJcG'9!!)fo!!)or!s&B$!;ulr!!3*"q>UEprr2rurr;lr!WN0!rr<&urr<&us8;rts8E#t
+rr<&ss82lqs8E#rs8N'"rrE&uqu?ct!<)ot!<)ot!7(WD!.k19rrN3#!.k11rr<%Ms3L`E!;?GC~>
+MuWfBJcG'9!!)fo!!)or!s&B$!;ulr!!3*"q>UEprr2rurr;lr!WN0!rr<&urr<&us8;rts8E#t
+rr<&ss82lqs8E#rs8N'"rrE&uqu?ct!<)ot!<)ot!7(WD!.k19rrPIc5_8sqrr<%Ms3L`E!;?GC~>
+MuWfBJcG'9!!)fo!!)or!s&B$!;ulr!!3*"q>UEprr2rurr;lr!WN0!rr<&urr<&us8;rts8E#t
+rr<&ss82lqs8E#rs8N'"rrE&uqu?ct!<)ot!<)ot!7(TG!.]TNs6K[d5lX*#s5X+Z!.k0rrrN1N
+JG0"n~>
+MuNhYrr@WMm/I%cjSo8]s8W#ta8Z,>ZN'n(JcG*:!!*#u!!%TMjSo2[JcF'rrW)ZlJ,~>
+MuNiDs$2/8m/I%cjSo8]s8W#ta8Z,>ZN'n(JcG*:!'pP`!'l,8jSo2[JcF'rrW)ZlJ,~>
+MuNiDs$2/8m/I%cjSo8]s8W#ta8Z,>ZMst+J:N4Nm/I&Nrr2s`JcFg2!!%TMci4%HJ:R@nJ,~>
+MuNhYrr@WMm/I%cjSo2[_#OE7[/^+*JcG*:!!*#u!!%TMjSo2[JcF'rrW)ZlJ,~>
+MuNiDs$2/8m/I%cjSo2[_#OE7[/^+*JcG*:!'pP`!'l,8jSo2[JcF'rrW)ZlJ,~>
+MuNiDs$2/8m/I%cjSo2[_#OE7[/U1-J:N4Nm/I&Nrr2s`JcFg2!!%TMci4%HJ:R@nJ,~>
+MuNhYrr@WMm/I%cJcF4!rW%NLm/I%crr2ruJcFg2!!(4B!!(OK!!)]lquHZp!!)-\!!)6_rW)Zl
+J,~>
+MuNiDs$2/8m/I%cJcF4!rW%NLm/I&Nrr2s`JcFg2!!(4B!!(OK!!)]lquHZp!!)-\!!)6_rW)Zl
+J,~>
+MuNiDs$2/8m/I%cJcF4!!W[b$JcG*:!'pP`!'l,8jSo2[bPqPBeGfLKp&Fpir;Q`sjo5;\kl1\a
+J:R@nJ,~>
+N;ikXrr2ruJcG-;!!%TMe,TCIJcG-;!!)rs!!%TMjo5;\ci3tFiVrlXnc&RhpAY*mp\t3nkPtG[
+lMph`pA]X~>
+N;ilCrr2s`JcG-;!!%TMe,TCIJcG-;!'pJ^!'l,8jo5;\ci3tFiVrlXnc&RhpAY*mp\t3nkPtG[
+lMph`pA]X~>
+N;ilCrr2s`JcG-;!!%TMe,KILJ:N4NmJd/Or;Qa^JcFj3!!(@F!!)!X!!)Qh!!)`m!!)cn!!)3^
+quH$^!W[b$pA]X~>
+N;ikXrr2ruJcG-;!!%TMe,TCIJcG-;!!)rs!!%TMjo5;\q#:<oqZ$Nprr2rurr2rurr;rtrVuis
+s8N'!rr3!!s8E#urr<&us8E#trrW9$!!)cnrVururW)rtrW)osrW)uu!!*#u!s&B$!<2uu!;HKp
+!<3&ursAc+!!*$!rr<'!s8E#urr<&ss8E#^s8E#ls*t~>
+N;ilCrr2s`JcG-;!!%TMe,TCIJcG-;!'pJ^!'l,8jo5;\q#:<oqZ$Nprr2rurr2rurr;rtrVuis
+s8N'!rr3!!s8E#urr<&us8E#trrW9$!!)cnrVururW)rtrW)osrW)uu!!*#u!s&B$!<2uu!;HKp
+!<3&ursAc+!!*$!rr<'!s8E#urr<&ss8E#^s8E#ls*t~>
+N;ilCrr2s`JcG-;!!%TMe,KILJ:N4NmJd/Or;Qa^JcFj3!!)fo!!)lqrW)rt!!*#u!!*#urW)os
+rW)uu!!*#u!<E0!!<<'!!<3#t!<3!#!<3$!p](3m!<<#urr;rtrVuiss8N'!rr3'#s8N)urr<&n
+rrN3#!<3!*!<3$!rrE'!!<<)u!<<'!!;ulr!9jFa!.]Uns*t~>
+N;ikXrr2ruJcG-;!!%TMe,TCIJcG-;!!)rs!!%TMjo5;\q#:<oqu6Wrrr2rurr3$"rrE&u!!*#u
+!s&B$!;uis!<3!#!<<'!rr3'#s8N)urs&Q(rr<'!rrDlp!!)rs!!*#u!!*#u!s&B$!;uj!!<<'!
+qYpNqp\t9prrE&urrE&urrE&u!!*#u!W`6#r;Zcs!WN/as8E#ls*t~>
+N;ilCrr2s`JcG-;!!%TMe,TCIJcG-;!'pJ^!'l,8jo5;\q#:<oqu6Wrrr2rurr3$"rrE&u!!*#u
+!s&B$!;uis!<3!#!<<'!rr3'#s8N)urs&Q(rr<'!rrDlp!!)rs!!*#u!!*#u!s&B$!;uj!!<<'!
+qYpNqp\t9prrE&urrE&urrE&u!!*#u!W`6#r;Zcs!WN/as8E#ls*t~>
+N;ilCrr2s`JcG-;!!%TMe,KILJ:N4NmJd/Or;Qa^JcFj3!!)fo!!)or!!*#u!!*#u!W`6#rr2ru
+rr3'#s8N)srr<&urrW9$rrE&u!s&B$!<3!'!<<'!!<<'!q>UEpr;Q`srr2rurr3'#s8N)srrW9$
+rrDoq!!)cn!W`6#rr;uurr;uurr2rurr3$"rrDusrr<*"!9sLb!.]Uns*t~>
+NW/tYr;Q`sJcG0<!!%TMe,TCIJcG0<!!)lq!!%TMk5PD]q#:<oqu6Wrrr2rurr3$"rrE&u!!*#u
+!s&B$!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)ip!!)rs!!)lq!s&B$!;uiu!<3&prr<&o
+rr<&urrW9$rrE#t!!)ip!s&B$!<2uu!9O7[!;?GC~>
+NW/uDr;Qa^JcG0<!!%TMe,TCIJcG0<!'pD\!'l,8k5PD]q#:<oqu6Wrrr2rurr3$"rrE&u!!*#u
+!s&B$!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)ip!!)rs!!)lq!s&B$!;uiu!<3&prr<&o
+rr<&urrW9$rrE#t!!)ip!s&B$!<2uu!9O7[!;?GC~>
+NW/uDr;Qa^JcG0<!!%TMe,KILJ:N4Nmf*8PqYpO\JcFm4!!)fo!!)or!!*#u!!*#u!W`6#rr2ru
+rr3'#s8N)srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2ruq>UEpr;Q`sqYpWts8N)srrN3#!;ZWp
+!;QQo!<3!#!<<'!rVlitq>UNss8N)urr<&\rrN1NJG0"n~>
+NW/tYr;Q`sJcG0<!!%TMe,TCIJcG0<!!)lq!!%TMk5PD]qu?Kmrr;lrrVlitrVucqs8N'!r;Q`s
+rr3'#s8N)urrW9$rrE&u!s&B$!<2uu!;QTo!<2uu!<)rr!<<'!!;ulr!;ZWp!;uis!<2uu!<3!#
+!<<'!rVlitr;Z]qs8N'!rr2rujo>;[pA]X~>
+NW/uDr;Qa^JcG0<!!%TMe,TCIJcG0<!'pD\!'l,8k5PD]qu?Kmrr;lrrVlitrVucqs8N'!r;Q`s
+rr3'#s8N)urrW9$rrE&u!s&B$!<2uu!;QTo!<2uu!<)rr!<<'!!;ulr!;ZWp!;uis!<2uu!<3!#
+!<<'!rVlitr;Z]qs8N'!rr2rujo>;[pA]X~>
+NW/uDr;Qa^JcG0<!!%TMe,KILJ:N4Nmf*8PqYpO\JcFm4!!)orq>gNpquH]q!!)utquHcs!!)rs
+!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&os8N)urr<&ts8;rtrr<&ss8E#orr<&srr<&urr<&u
+rrW9$rrE#t!!)rsr;clt!!*#u!!)-\!W[b$pA]X~>
+NW/tYr;Q`sJcG0<!!%TMe,TCIJcG0<!!)lq!!%TMk5PD]q#:<oqu6WrqYpTsrrE&u!!)or!!)rs
+!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&mrrW9$rrE&u!!*#u!s&B$!;uj!!<<'!qYpNqr;Qfu
+s8Voq!WN/urr<&trr<&urr<&urrN3#!9F1Z!;?GC~>
+NW/uDr;Qa^JcG0<!!%TMe,TCIJcG0<!'pD\!'l,8k5PD]q#:<oqu6WrqYpTsrrE&u!!)or!!)rs
+!!*#u!s&B$!<3!#!<<'!rr3'#s8N)urr<&mrrW9$rrE&u!!*#u!s&B$!;uj!!<<'!qYpNqr;Qfu
+s8Voq!WN/urr<&trr<&urr<&urrN3#!9F1Z!;?GC~>
+NW/uDr;Qa^JcG0<!!%TMe,KILJ:N4Nmf*8PqYpO\JcFm4!!)fo!!)or!!)lq!W`6#rr2ruqu6Wr
+r;Q`srr3'#s8N)urrW9$rrE&u!s&B$!<2uu!;?Ep!<<'!rr2rurr3'#s8N)srrW9$rrDoq!!)rs
+!W`9#q>^Qr!<)ot!<)ot!<2uu!<3!"!<3&[rrN1NJG0"n~>
+NrK(ZqYpNqJcG3=!!%TMe,TCIJcG3=!!)fo!!%TMkPkM^q#:<oqu6WrqYpTsrrE&u!!)or!!)rs
+#6=f(!!*'!!<3!#!<<'!rr3'#s8N)urr<&mrrW9$rrE&u!!*#u!s&B$!;uis!<2uu!;c]q!<)p"
+!<<'!r;QfurrE#t!!)ut!!*#u!!*#u!W`6#jT#2ZpA]X~>
+NrK)EqYpO\JcG3=!!%TMe,TCIJcG3=!'p>Z!'l,8kPkM^q#:<oqu6WrqYpTsrrE&u!!)or!!)rs
+#6=f(!!*'!!<3!#!<<'!rr3'#s8N)urr<&mrrW9$rrE&u!!*#u!s&B$!;uis!<2uu!;c]q!<)p"
+!<<'!r;QfurrE#t!!)ut!!*#u!!*#u!W`6#jT#2ZpA]X~>
+NrK)EqYpO\JcG3=!!%TMe,KILJ:N4Nn,EAQq#:=ZJcFp5!!)fo!!)or!!)lq!W`6#rr2ruqu6Wr
+r;R!%s8N'!s8N)urrW9$rrE&u!s&B$!<2uu!;?Ep!<<'!rr2rurr3'#s8N)srr<&urr<&qrr<&t
+rrW9$rrDus!W`6#rVlitrVlitrr2rurr3$"rrD-[!W[b$pA]X~>
+NrK(ZqYpNqJcG3=JH4!rJcG3=!!)fo!!%TMkPkM^q#:<oqZ$Kos8N'!rr2rurr;osrr;rtrr;uu
+!WN0!rrW9$rrE&urW)rt!!*#u!!)iprW)os!!*#uquHcsrW)uu!!)ut!W`6#r;ZZp!WN/rs8N)t
+rr<&ss82lrrr<&Zs8E#ls*t~>
+NrK)EqYpO\JcG3=JH4!rJcG3=!'p>Z!'l,8kPkM^q#:<oqZ$Kos8N'!rr2rurr;osrr;rtrr;uu
+!WN0!rrW9$rrE&urW)rt!!*#u!!)iprW)os!!*#uquHcsrW)uu!!)ut!W`6#r;ZZp!WN/rs8N)t
+rr<&ss82lrrr<&Zs8E#ls*t~>
+NrK)EqYpO\JcG3=JH4'ts+#\#n,EAQq#:=ZJcFp5!!)fo!!)lqr;clt!!*#u!!*#ur;cisrW)rt
+rr<*"!<3!#!<<'!rr;rtrr2rurr2ruq>^EorVlitrr;lrs8W&us8N'!rVlp!rrDusqu?ct!;c`q
+!<)ot!;ulp!<2uu!9=(\!.]Uns*t~>
+NrK(ZqYpNqJcG3=!!%TMe,TCIJcG3=!!)fo!!%TMkPkM^])V^/\c2X0j8])YpA]X~>
+NrK)EqYpO\JcG3=!!%TMe,TCIJcG3=!'p>Z!'l,8kPkM^])V^/\c2X0j8])YpA]X~>
+NrK)EqYpO\JcG3=!!%TMe,KILJ:N4Nn,EAQq#:=ZJcFp5!!'V1r;aD.!!)'Z!W[b$pA]X~>
+O8f1[q#:<oJcG6>!!%TMe,TCIJcG6>!!)`m!!%TMkl1V_JcG3=!!)$YrW)ZlJ,~>
+O8f2Fq#:=ZJcG6>!!%TMe,TCIJcG6>!'p8X!'l,8kl1V_JcG3=!!)$YrW)ZlJ,~>
+O8f2Fq#:=ZJcG6>!!%TMe,KILJ:N4NnG`JRpAY+XJcFs6!!%TMn,E@fir9&[J:R@nJ,~>
+O8f1[q#:<oJcG6>!!%TMe,TCIJcG6>oDjIBkl1V_JcF'rrW)ZlJ,~>
+O8f2Fq#:=ZJcG6>!!%TMe,TCIJcG6>oK\!-kl1V_JcF'rrW)ZlJ,~>
+O8f2Fq#:=ZJcG6>!!%TMe,KILJ:N4NnGi,GJcFs6!!%TMci4%HJ:R@nJ,~>
+O8f1[q#:<oJcG6>!!%TMe,TCIJcG$8!!%TMir8uYJcF'rrW)ZlJ,~>
+O8f2Fq#:=ZJcG6>!!%TMe,TCIJcG$8!'l,8ir8uYJcF'rrW)ZlJ,~>
+O8f2Fq#:=ZJcG6>!!%TMe,KILJ:N4NlMgiLJcFa0!!%TMci4%HJ:R@nJ,~>
+OT,:\pAY*mJcG9?!!%TMe,TCIJcG$8!!%TMir8uYJcF'rrW)ZlJ,~>
+OT,;GpAY+XJcG9?!!%TMe,TCIJcG$8!'l,8ir8uYJcF'rrW)ZlJ,~>
+OT,;GpAY+XJcG9?!!%TMe,KILJ:N4NlMgiLJcFa0!!%TMci4%HJ:R@nJ,~>
+OT4qQJcG9?!!%TMe,TCIJcG$8!!%TMir8uYJcF'rrW)ZlJ,~>
+OT4r<JcG9?!!%TMe,TCIJcG$8!'l,8ir8uYJcF'rrW)ZlJ,~>
+OT4r<JcG9?!!%TMe,KILJ:N4NlMgiLJcFa0!!%TMci4%HJ:R@nJ,~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYdJj1Hmf3.aiVrlXnc/Lel2L_`kl:V^pA]X~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYdJj1Hmf3.aiVrlXnc/Lel2L_`kl:V^pA]X~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!(FH!!)HeqZ,UT!!)QhquH!]!!)6_!W[b$pA]X~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYli-qbp\t3noD\djr;Q`srr2ruq#:<oi;WcWmf*7e
+qu6Wrp\t3nq#C6llMph`pA]X~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYli-qbp\t3noD\djr;Q`srr2ruq#:<oi;WcWmf*7e
+qu6Wrp\t3nq#C6llMph`pA]X~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)?b!!)cn!!)Wj!!)rs!!*#u!!)fo!!(sW!!)He
+!!)or!!)cn!!)foquH$^!W[b$pA]X~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYq#:<oqZ$Np!<<#urr;rts8W&urr;rtrr2rurr2ru
+rVuis!<<#u!WN/ts8N)rrr<&urr<&us8E#ss8E#urr<&urrE-"rW)uu!!*#urW)rt"p"Z'!<<'!
+r;Z`rrr;rts8W&urr;rtrr;uukl:V^pA]X~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYq#:<oqZ$Np!<<#urr;rts8W&urr;rtrr2rurr2ru
+rVuis!<<#u!WN/ts8N)rrr<&urr<&us8E#ss8E#urr<&urrE-"rW)uu!!*#urW)rt"p"Z'!<<'!
+r;Z`rrr;rts8W&urr;rtrr;uukl:V^pA]X~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)fo!!)lqrVururW)rtrW)uurW)rtrW)rt!!*#u
+!!)utrVururW!!!!;uls!;lcr!<2uu!<3#t!<)rs!<<'!!<3!!!<<#us8N'!rr;rtrr30&rr<'!
+rrDusrW)rtrW)uurW)rtrW)rtrrD9_!W[b$pA]X~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYq#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&urr<&r
+rr<&srr<&urr<&urr<&urrN3#!;c]s!<3&urr<&urrW9$rrDus!!*#u!s&B$!<3!#!<<'!rr3<*
+s8N'!s8N*!rrDus!!*#u!!*#u!s&B$!<2uu!<3!%!<<'!rrD<`rW)ZlJ,~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYq#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&urr<&r
+rr<&srr<&urr<&urr<&urrN3#!;c]s!<3&urr<&urrW9$rrDus!!*#u!s&B$!<3!#!<<'!rr3<*
+s8N'!s8N*!rrDus!!*#u!!*#u!s&B$!<2uu!<3!%!<<'!rrD<`rW)ZlJ,~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)fo!!)or!!)rs!!*#u!!*#u!s&B$!<2uu!<2uu
+!;lcr!;uis!<2uu!<2uu!<3!"!<3&qrrN3#!<2uu!<3!#!<<'!r;Q`srr3'#s8N)urrW9$rrE&u
+$3:,+!!*'!!<<'!r;Q`srr2rurr3'#s8N)urr<&urriE&rrE'!l2LebJ:R@nJ,~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYq#:<oqu6Wrr;Q`sqYpWts8N)urr<&urr<&rrr<&s
+rr<&urr<&urr<&urrE-"quH`r!W`6#rr2rurr3'#s8N)srr<&urrW9$rrE&u!s&B$!<3!#!<<'!
+rr2rurr;uurr2ruqYpWts8N)urr<&urr<&[s8E#ls*t~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYq#:<oqu6Wrr;Q`sqYpWts8N)urr<&urr<&rrr<&s
+rr<&urr<&urr<&urrE-"quH`r!W`6#rr2rurr3'#s8N)srr<&urrW9$rrE&u!s&B$!<3!#!<<'!
+rr2rurr;uurr2ruqYpWts8N)urr<&urr<&[s8E#ls*t~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)fo!!)or!!)rs!!)lq!s&B$!<2uu!<2uu!;lcr
+!;uis!<2uu!<2uu!<3!!!<;rsrr3$"rrE&u!!*#u!s&B$!;uis!<3!#!<<'!rr3'#s8N)urrW9$
+rrE&u!!*#urrE&u!!)lq!s&B$!<2uu!<2uu!9F.]!.]Uns*t~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYqu?KmrVultrr2rurVufrs8N'!rr;lrqu6Wrr;Q`s
+rr2rurVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs!s&B$
+!<)rr!<<'!!<3#r!9F1Z!;?GC~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYqu?KmrVultrr2rurVufrs8N'!rr;lrqu6Wrr;Q`s
+rr2rurVm$$rrE*!!;ZWp!<)rq!<<'!!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs!s&B$
+!<)rr!<<'!!<3#r!9F1Z!;?GC~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)orq>gKorrE&u!!)utr;clt!!*#uquHWo!!)rs
+!!*#u!!)ut"T\Q&s8N)prr<&ts82lsrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2rur;Qj!
+s8N)ts8;rtrr<&us82lXrrN1NJG0"n~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYq#:<oq#:Ers8N)urr<&urrW9$rrE&u!!)cn!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs
+!s&B$!<2uu!<3!#!<<'!rr2rui;`cVpA]X~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYq#:<oq#:Ers8N)urr<&urrW9$rrE&u!!)cn!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uis!<3!#!<<'!rr3'#s8N)urrW9$rrE&u!!)rs
+!s&B$!<2uu!<3!#!<<'!rr2rui;`cVpA]X~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)fo!!)fo!s&B$!<2uu!<3!#!<<'!rr2rup\t3n
+r;Q`srr2rurVm$$rrE*!!;c]s!<3&urr<&rrr<&srr<&urrW9$rrE&u!s&B$!<3!#!<<'!rr2ru
+r;Qj!s8N)urr<&urrW9$rrE&u!!(sW!W[b$pA]X~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYq#:<oq#:Ers8N)urr<&urrW9$rrE&u!!)cn!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uj%!<<'!!<<'!rr3'#s8N)urrW9$rrE&u!!)rs
+!s&B$!<2uu!<3!#!<<'!rr2rui;`cVpA]X~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYq#:<oq#:Ers8N)urr<&urrW9$rrE&u!!)cn!!)rs
+!!*#u!!)ut"T\Q&s8N)qrrN3#!<2uu!;lcr!;uj%!<<'!!<<'!rr3'#s8N)urrW9$rrE&u!!)rs
+!s&B$!<2uu!<3!#!<<'!rr2rui;`cVpA]X~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)fo!!)fo!s&B$!<2uu!<3!#!<<'!rr2rup\t3n
+r;Q`srr2rurVm$$rrE*!!;c]s!<3&urr<&rrr<&srs&Q(rr<'!rrE&u!s&B$!<3!#!<<'!rr2ru
+r;Qj!s8N)urr<&urrW9$rrE&u!!(sW!W[b$pA]X~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYq#:<oqu?WqrVlitrr;lrs8N'!rr;oss8N'!rr;lr
+s8N'!rr2rurVlitrr;iq!WN0!rr<&us8;rss8E#ts8N'"rrE&u!s&B$!<3#t!<2uu!<3!!!<;ut
+rVlitrr;lrs8N'!rr;osjT#2ZpA]X~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYq#:<oqu?WqrVlitrr;lrs8N'!rr;oss8N'!rr;lr
+s8N'!rr2rurVlitrr;iq!WN0!rr<&us8;rss8E#ts8N'"rrE&u!s&B$!<3#t!<2uu!<3!!!<;ut
+rVlitrr;lrs8N'!rr;osjT#2ZpA]X~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!)fo!!)orrW)os!!*#uquHcs!!*#ur;clt!!*#u
+quHcs!!*#u!!)ut!!*#uqZ$Zs!<2uu!<3#s!<3#t!<3#u!!3*"rr3'#s8N)us8E#trr<&urrE-"
+r;cfr!!*#uquHcs!!*#ur;bpY!W[b$pA]X~>
+MuNbWJcG$8!!%TMe,TCIJcG$8!!%TMir8uYJcF'rrW)ZlJ,~>
+MuNcBJcG$8!!%TMe,TCIJcG$8!'l,8ir8uYJcF'rrW)ZlJ,~>
+MuNcBJcG$8!!%TMe,KILJ:N4NlMgiLJcFa0!!%TMci4%HJ:R@nJ,~>
+cMrFqVZ-VrJcF4!rW(7DJH3:^_uB]:JcF'rrW)ZlJ,~>
+cMrFqVZ-VrJcF4!rW(7DJH3:^_uB]:JcF'rrW)ZlJ,~>
+cMrFqVZ-VrJcF4!!W[b$cMrFq])]bK!!%TMci4%HJ:R@nJ,~>
+cMmkEKDtoOVZ-VrJcF4!rW(7D!!%TM^&J'4_uB]:JcF'rrW)ZlJ,~>
+cMmkEKDtoOVZ-VrJcF4!rW(7D!!%TM^&J'4_uB]:JcF'rrW)ZlJ,~>
+cMmkEKDtoOVZ-VrJcF4!!W[b$cMmkEJcEF`!!'q:!!%TMci4%HJ:R@nJ,~>
+cMmkEKDtoOVZ-VrJcF4!rW(7D!!%TM^&J'4_uB]:JcF'rrW)ZlJ,~>
+cMmkEKDtoOVZ-VrJcF4!rW(7D!!%TM^&J'4_uB]:JcF'rrW)ZlJ,~>
+cMmkEKDtoOVZ-VrJcF4!!W[b$cMmkEJcEF`!!'q:!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:OTu!!%TMe,KILJ:PrF!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEli6b\eGoIIdf9:HW;chtJcF4!rW(7D!!(.@q#KRWrW!0&!!*'!!!)for;a&$rW'q;!!%TM
+ci<tEpA]X~>
+cMmkEli6b\eGoIIdf9:HW;chtJcF4!rW(7D!!(.@q#KRWrW!0&!!*'!!!)for;a&$rW'q;!!%TM
+ci<tEpA]X~>
+cMmkEli6b\eGoIIdf0@KJ:OTu!!%TMe,KILJ:PrF!!(.@q#KRWrW!0&!!*'!!!)for;a&$!W[b$
+`W#o<JcF'r!W[b$pA]X~>
+cMmkEkl:Y_f)PaMs8W*!rr3*$s8N'!p](6nj8])YW;chtJcF4!rW(7D!!(%=rrD-[rrDoqrrDlp
+rrE&u"9AK%!!)cnrrBk7rW'q;!!)Qh!!(:DquH]qrW)6`!!'P/rW)ZlJ,~>
+cMmkEkl:Y_f)PaMs8W*!rr3*$s8N'!p](6nj8])YW;chtJcF4!rW(7D!!(%=rrD-[rrDoqrrDlp
+rrE&u"9AK%!!)cnrrBk7rW'q;!!)Qh!!(:DquH]qrW)6`!!'P/rW)ZlJ,~>
+cMmkEkl:Y_f)PaMs8W*!rr3*$s8N'!p](6nj8T/\J:OTu!!%TMe,KILJ:PrF!!(%=rrD-[rrDoq
+rrDlprrE&u"9AK%!!)cnrrBk7!W[b$`W#o<nc&Rhc2[\ArVuislMgha\GlU1J:R@nJ,~>
+cMmkEkl:Y_rVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;Zp!!!)rsr;cltr;cltr;cisr;c0`
+rW&ns!!%TMe,TCIcMmkE`rH&=rVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)uurrDus
+r;cltr;cltr;cisr;aq=rW'q;!!)Qh!!)Ti!!(mU!!)ip!!*#u!!)?b!!'P/rW)ZlJ,~>
+cMmkEkl:Y_rVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;Zp!!!)rsr;cltr;cltr;cisr;c0`
+rW&ns!!%TMe,TCIcMmkE`rH&=rVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)uurrDus
+r;cltr;cltr;cisr;aq=rW'q;!!)Qh!!)Ti!!(mU!!)ip!!*#u!!)?b!!'P/rW)ZlJ,~>
+cMmkEkl:Y_rVult!ri9#r;cfrr;cltrW)osr;cisrW)uur;Zp!!!)rsr;cltr;cltr;cisr;c0`
+!W[b$W;chtJcF4!!W[b$cMmkE`rH&=rVult!ri9#r;cfrr;cltrW)uuqu?s$!!*'!!!*#urW)uu
+rrDusr;cltr;cltr;cisr;aq=!W[b$`W#o<nc&Rho)A[ihZ!QUq>UEprr2ruli-qb\GlU1J:R@n
+J,~>
+cMmkEkl:Y_rVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#lal)s8N'!s8W&ur;Zcsqu?Zrs8W*!
+rr;uukl:V^W;chtJcF4!rW(7D!!(%=rrE#trW)lrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!
+rr<0$!!*&u!;uls!;lfr!<<*!!<3#u!6,!;!6+s<!;QQo!;lcr!<3#t!<)rs!!*&u!;QTn!<<'"
+!<<#urr2rurr3'#s8N)urr<&prr<&srrW9$rrE&u!!*#urW)rt"T\Q&!<3&urr<&3s8E#ls*t~>
+cMmkEkl:Y_rVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#lal)s8N'!s8W&ur;Zcsqu?Zrs8W*!
+rr;uukl:V^W;chtJcF4!rW(7D!!(%=rrE#trW)lrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!
+rr<0$!!*&u!;uls!;lfr!<<*!!<3#u!6,!;!6+s<!;QQo!;lcr!<3#t!<)rs!!*&u!;QTn!<<'"
+!<<#urr2rurr3'#s8N)urr<&prr<&srrW9$rrE&u!!*#urW)rt"T\Q&!<3&urr<&3s8E#ls*t~>
+cMmkEkl:Y_rVuisr;Zcss8W*!rVult#6+Z's8N'!r;Zcs#lal)s8N'!s8W&ur;Zcsqu?Zrs8W*!
+rr;uukl1\aJ:OTu!!%TMe,KILJ:PrF!!(%=rrE#trW)lrrrE*!rrE#trr<9'!!*'!!!*#urrE*!
+rrE*!rr<0$!!*&u!;uls!;lfr!<<*!!<3#u!6+s>!.]U=rr<&orr<&rrr<&us8E#ss8Duus8E#n
+s8E#urrE-"rW)rt!!*#u!s&B$!<2uu!;ZWp!;uj!!<<'!rr2rurr;rtrr3-%rr<'!!<2uu!5/=5
+!.]Uns*t~>
+cMmkEkl:Y_rVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;osrr;uuqu?Zrs8W*!
+rr;rtl2U__W;chtJcF4!rW(7D!!(%=rrE#trrDrrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!
+rr<3%!!*'!r;cisrrDrrrrE*!rrE&urW't<rW'q;!!)fo!!)or!s&B$!<3!#!<<'!r;Q`sq#:<o
+r;Zcsrr3'#s8N)urr<&rrr<&prr<&srrW9$rrE&u!s&B$!<3!$!<<'!!<3!#!<<'!]Dqj1pA]X~>
+cMmkEkl:Y_rVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;osrr;uuqu?Zrs8W*!
+rr;rtl2U__W;chtJcF4!rW(7D!!(%=rrE#trrDrrrrE*!rrE#trr<9'!!*'!!!*#urrE*!rrE*!
+rr<3%!!*'!r;cisrrDrrrrE*!rrE&urW't<rW'q;!!)fo!!)or!s&B$!<3!#!<<'!r;Q`sq#:<o
+r;Zcsrr3'#s8N)urr<&rrr<&prr<&srrW9$rrE&u!s&B$!<3!$!<<'!!<3!#!<<'!]Dqj1pA]X~>
+cMmkEkl:Y_rVultqu?Zrs8W*!rVult"TJH%s8W&urVult#6+Z's8N'!rr;osrr;uuqu?Zrs8W*!
+rr;rtl2LebJ:OTu!!%TMe,KILJ:PrF!!(%=rrE#trrDrrrrE*!rrE#trr<9'!!*'!!!*#urrE*!
+rrE*!rr<3%!!*'!r;cisrrDrrrrE*!rrE&urW't<!W[b$`W#o<q#:<oqu6`us8N)urrW9$rrDus
+!!)fo!!)rsrrE&u!s&B$!<2uu!;lcr!;ZWp!;uj!!<<'!rr3'#s8N)urr`?%rr<&urrW9$rrB\2
+!W[b$pA]X~>
+cMmkEkl:Y_rVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!r;Z`rs8W*!rVufrs8W*!rVuislMph`
+W;chtJcF4!rW(7D!!(%=rrE#trrE#tr;cltrrE#tquHcsrrE&urrE*!rrE*!quH]qrW)uurrE#t
+r;cltrrE#trW("=rW'q;!!)fo!!)or!!)or!s&B$!;uis!;QQo!;uis!<)p"!<<'!rr2ruqu6Wr
+q>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#])Va0pA]X~>
+cMmkEkl:Y_rVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!r;Z`rs8W*!rVufrs8W*!rVuislMph`
+W;chtJcF4!rW(7D!!(%=rrE#trrE#tr;cltrrE#tquHcsrrE&urrE*!rrE*!quH]qrW)uurrE#t
+r;cltrrE#trW("=rW'q;!!)fo!!)or!!)or!s&B$!;uis!;QQo!;uis!<)p"!<<'!rr2ruqu6Wr
+q>UEpr;Qj!s8N)urr<&rrrW9$rrE#t!W`6#])Va0pA]X~>
+cMmkEkl:Y_rVultrVufrs8W*!rVucqrr;rtrr;lrs8W*!r;Z`rs8W*!rVufrs8W*!rVuislMgnc
+J:OTu!!%TMe,KILJ:PrF!!(%=rrE#trrE#tr;cltrrE#tquHcsrrE&urrE*!rrE*!quH]qrW)uu
+rrE#tr;cltrrE#trW("=!W[b$`W#o<q#:<oqu6Wrqu6`us8N)srr<&orr<&srr<&trrW9$rrE&u
+!!)or!!)ip!!)rs!s&B$!<2uu!;lcu!<<'!rVlp!rrBY1!W[b$pA]X~>
+cMmkEkl:Y_rVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsqu?Zrs8W*!rr;uu#6+Z's8N'!
+r;Z`rli6qaW;chtJcF4!rW(7D!!(%=rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!rrE*!
+rrDlprrE*!rrE&urr<9'!!*'!!!)rsrW(%>rW'q;!!)orq>gNp!!*#ur;cisrrE&u!!)fo!!)rs
+!!)ut!s&B$!<2uu!;lcr!;uj!!<<'!r;Qj!s8N)urr<&us8;rtrr<&ts8E#0s8E#ls*t~>
+cMmkEkl:Y_rVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsqu?Zrs8W*!rr;uu#6+Z's8N'!
+r;Z`rli6qaW;chtJcF4!rW(7D!!(%=rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!rrE*!
+rrDlprrE*!rrE&urr<9'!!*'!!!)rsrW(%>rW'q;!!)orq>gNp!!*#ur;cisrrE&u!!)fo!!)rs
+!!)ut!s&B$!<2uu!;lcr!;uj!!<<'!r;Qj!s8N)urr<&us8;rtrr<&ts8E#0s8E#ls*t~>
+cMmkEkl:Y_rVultrr;uu#6+Z's8N'!rVultqZ$Nps8W*!r;Zcsqu?Zrs8W*!rr;uu#6+Z's8N'!
+r;Z`rli."dJ:OTu!!%TMe,KILJ:PrF!!(%=rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!
+rrE*!rrDlprrE*!rrE&urr<9'!!*'!!!)rsrW(%>!W[b$`W#o<qu?Kmrr2rurr;osrr;uurr2ru
+q#:<or;Q`srVls"s8N)urr<&rrr<&srrW9$rrDus!s&B$!<2uu!<3#s!<<'!!<)rs!4r13!.]Un
+s*t~>
+cMmkEkl:Y_rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;Zcss8N'!rr;uus8W*!rr;uu#6+Z'
+s8N'!qu?Zrli6qaW;chtJcF4!rW(7D!!(%=rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!
+rrE*!rrE#t!!*#urrE*!rrE&urr<9'!!*'!!!)orrrC.?rW'q;!!)fo!!)or!s&B$!<2uu!;uj!
+!<<'!q#:<or;Q`srVls"s8N)urr<&rrr<&srrW9$rrDus!s&B$!<3!#!<<'!rr3'#s8N)trrW9$
+rrB\2rW)ZlJ,~>
+cMmkEkl:Y_rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;Zcss8N'!rr;uus8W*!rr;uu#6+Z'
+s8N'!qu?Zrli6qaW;chtJcF4!rW(7D!!(%=rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&urrE*!
+rrE*!rrE#t!!*#urrE*!rrE&urr<9'!!*'!!!)orrrC.?rW'q;!!)fo!!)or!s&B$!<2uu!;uj!
+!<<'!q#:<or;Q`srVls"s8N)urr<&rrr<&srrW9$rrDus!s&B$!<3!#!<<'!rr3'#s8N)trrW9$
+rrB\2rW)ZlJ,~>
+cMmkEkl:Y_rVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!r;Zcss8N'!rr;uus8W*!rr;uu#6+Z'
+s8N'!qu?Zrli."dJ:OTu!!%TMe,KILJ:PrF!!(%=rrE#trrE&urr<9'!!*'!!!)utrrDusrrE&u
+rrE*!rrE*!rrE#t!!*#urrE*!rrE&urr<9'!!*'!!!)orrrC.?!W[b$`W#o<q#:<oqu6`us8N)u
+rr<&srrW9$rrDio!!)rs!!)ut!s&B$!<2uu!;lcr!;uj!!<<'!r;Qj!s8N)urrW9$rrE&u!s&B$
+!<)p"!<<'!]Dhp4J:R@nJ,~>
+cMmkEkl:Y_rVultrVucqs8W#ts8W#ts8W#trVufrrr;rt!<;utrVuiss8Vuss8W&u!<;utlMph`
+W;chtJcF4!rW(7D!!(%=rrE#trrE#tquHcsr;cltr;cltrrE&urrE*!rrE&ur;cltr;cfrrW)uu
+quHcsrVurur;an<rW'q;!!)fo!!)or!s&B$!<2uu!;uj!!<<'!q#:<or;Zcsrr33's8N*!rr<&q
+rr<&trr<&urr<&urr<&urs&Q(rr<'!rrE&u!s&B$!<)ot!<2uu!5/@2!;?GC~>
+cMmkEkl:Y_rVultrVucqs8W#ts8W#ts8W#trVufrrr;rt!<;utrVuiss8Vuss8W&u!<;utlMph`
+W;chtJcF4!rW(7D!!(%=rrE#trrE#tquHcsr;cltr;cltrrE&urrE*!rrE&ur;cltr;cfrrW)uu
+quHcsrVurur;an<rW'q;!!)fo!!)or!s&B$!<2uu!;uj!!<<'!q#:<or;Zcsrr33's8N*!rr<&q
+rr<&trr<&urr<&urr<&urs&Q(rr<'!rrE&u!s&B$!<)ot!<2uu!5/@2!;?GC~>
+cMmkEkl:Y_rVultrVucqs8W#ts8W#ts8W#trVufrrr;rt!<;utrVuiss8Vuss8W&u!<;utlMgnc
+J:OTu!!%TMe,KILJ:PrF!!(%=rrE#trrE#tquHcsr;cltr;cltrrE&urrE*!rrE&ur;cltr;cfr
+rW)uuquHcsrVurur;an<!W[b$`W#o<q#:<oqu6`us8N)urr<&srrW9$rrDio!!)rsrrE&u#6=f(
+!<<'!!;c]q!<)ot!<2uu!<2uu!<3!'!<<'!!<<'!rr3'#s8N)trr<&urr<&3rrN1NJG0"n~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<q#:<oqu6Wrrr;lr!<<#urVlitq#C<ns8N*"
+s8E#ss8N'%rrE*!!;ulp!<)rs!;uls!!3*"rr;lr!WN/urr<&trr<&4s8E#ls*t~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<q#:<oqu6Wrrr;lr!<<#urVlitq#C<ns8N*"
+s8E#ss8N'%rrE*!!;ulp!<)rs!;uls!!3*"rr;lr!WN/urr<&trr<&4s8E#ls*t~>
+cMmkEKDtuQJ:OTu!!%TMe,KILJ:PrF!!%TM^&J-6J:PW=!!)fo!!)or!!*#uqu?`srW)os!!)fo
+rW)uu!<E0!!<)rt!!N<%s8N)ss82lqs8E#rs8N'"rrE&uqu?ct!<)ot!<)ot!58C6!.]Uns*t~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<h>dERq>UEpiVrlXU&Y)lpA]X~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<h>dERq>UEpiVrlXU&Y)lpA]X~>
+cMmkEKDtuQJ:OTu!!%TMe,KILJ:PrF!!%TM^&J-6J:PW=!!(jTr;cZn!!)!X!!&_m!W[b$pA]X~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<dJj1Hi;`fWU]:;npA]X~>
+cMmkEKE(oNW;chtJcF4!rW(7D!!%TM^&S'3`W#o<dJj1Hi;`fWU]:;npA]X~>
+cMmkEKDtuQJ:OTu!!%TMe,KILJ:PrF!!%TM^&J-6J:PW=!!(FH!!(sWrrAho!W[b$pA]X~>
+cMmkEKE(oNW;hDKcN)8j!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNW;hDKcN)8j!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:OTuJH4'ts+&Dp!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNV>l)HdK%Sm!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNV>l)HdK%Sm!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:OKrJUl1!cMmkEJcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNV>l)HdK%Sm!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNV>l)HdK%Sm!!%TM^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:OKrJUl1!cMmkEJcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!)Qh!!(:D!!)Wj!!(pV!!((>rW)ZlJ,~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!)Qh!!(:D!!)Wj!!(pV!!((>rW)ZlJ,~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!)Qh!!(:D!!)Wj!!(pV!!((>!W[b$pA]X~>
+cMmkEKE(oNJcF7"!W`6#JcG?A!!%TM^&S'3`W#o<nc&Rho)A[icMmkEec,ULdJs1GpA]X~>
+cMmkEKE(oNJcF7"!^QcNJcG?A!!%TM^&S'3`W#o<nc&Rho)A[icMmkEec,ULdJs1GpA]X~>
+cMmkEKDtuQJ:N4NeGfS8s$2/8oD\djJcEF`!W[b$`W#o<nc&Rho)A[icMmkEec,ULdJj7JJ:R@n
+J,~>
+ci8OrrW%NLeGfRMrr@WMoDa@A\H'VK!!)fo!!)or!!*#urW)osrVururW)`nrW)uu!<E0!!<2uu
+!<2uu!;ZX!!<<'!rr<&ts8E!!rrE&urW)rt!!*#u!s&B$!<)rr!<<'!!<3!+!<<'!s8N*!!!*'!
+rW(CHrW)ZlJ,~>
+ci8OrrW%NLeGfS8s$2/8oDa@A\H'VK!!)fo!!)or!!*#urW)osrVururW)`nrW)uu!<E0!!<2uu
+!<2uu!;ZX!!<<'!rr<&ts8E!!rrE&urW)rt!!*#u!s&B$!<)rr!<<'!!<3!+!<<'!s8N*!!!*'!
+rW(CHrW)ZlJ,~>
+ci8Or!W[b$JcF7"!^QcNJcG?AJH3:^s+&)g!!)fo!!)or!!*#urW)osrVururW)`nrW)uu!<E0!
+!<2uu!<2uu!;ZX!!<<'!rr<&ts8E!!rrE&urW)rt!!*#u!s&B$!<)rr!<<'!!<3!+!<<'!s8N*!
+!!*'!rW(CH!W[b$pA]X~>
+cMmkEKE(oNJcF7"!W`6#JcG?A!!%TM^&S'3`W#o<q#:<oqu6`us8N)urrW9$rrDus!!)fo!!)rs
+rrE&u!s&B$!<2uu!;ZX%!<<'!!<<'!s8N)us8N*!rr<&urr<&urrN3#!;c]q!<3!#!<<'!rr3E-
+s8N*!rr<'!rrE*!!7CiG!;?GC~>
+cMmkEKE(oNJcF7"!^QcNJcG?A!!%TM^&S'3`W#o<q#:<oqu6`us8N)urrW9$rrDus!!)fo!!)rs
+rrE&u!s&B$!<2uu!;ZX%!<<'!!<<'!s8N)us8N*!rr<&urr<&urrN3#!;c]q!<3!#!<<'!rr3E-
+s8N*!rr<'!rrE*!!7CiG!;?GC~>
+cMmkEKDtuQJ:N4NeGfS8s$2/8oD\djJcEF`!W[b$`W#o<q#:<oqu6`us8N)urrW9$rrDus!!)fo
+!!)rsrrE&u!s&B$!<2uu!;ZX%!<<'!!<<'!s8N)us8N*!rr<&urr<&urrN3#!;c]q!<3!#!<<'!
+rr3E-s8N*!rr<'!rrE*!!7CfJ!.]Uns*t~>
+cMmkEKE(oNJcF:#!!*#u!!%TMo`"mkJcEF`rW'q;!!)fo!!)or!!)or!s&B$!;uis!;QQo!;uis
+!<)p"!<<'!rr2ruq>UNss8N)urrW9$rrE#t!s&B$!<2uu!<3!"!<3&qrr<&urrW9$rrE&u"p"]'
+!<<'!rr3'#s8N)Hs8E#ls*t~>
+cMmkEKE(oNJcF:#!'pP`!'l,8o`"mkJcEF`rW'q;!!)fo!!)or!!)or!s&B$!;uis!;QQo!;uis
+!<)p"!<<'!rr2ruq>UNss8N)urrW9$rrE#t!s&B$!<2uu!<3!"!<3&qrr<&urrW9$rrE&u"p"]'
+!<<'!rr3'#s8N)Hs8E#ls*t~>
+cMmkEKDtuQJ:N4Nec,V7rr2s`JcGBB!!%TM^&J-6J:PW=!!)fo!!)or!!)or!s&B$!;uis!;QQo
+!;uis!<)p"!<<'!rr2ruq>UNss8N)urrW9$rrE#t!s&B$!<2uu!<3!"!<3&qrr<&urrW9$rrE&u
+"p"]'!<<'!rr3'#s8N)HrrN1NJG0"n~>
+cMmkEKE(oNJcF:#!!*#u!!%TMo`"mkJcEF`rW'q;!!)orq>gNp!!*#ur;cisrrE&u!!)fo!!)rs
+!!)ut!s&B$!<2uu!;ZWs!<<'!rr3'#s8N)trrN3#s82lqrr<&prr<&urrW9$rrE&u"p"]'!<<'!
+rr3'#s8N)Hs8E#ls*t~>
+cMmkEKE(oNJcF:#!'pP`!'l,8o`"mkJcEF`rW'q;!!)orq>gNp!!*#ur;cisrrE&u!!)fo!!)rs
+!!)ut!s&B$!<2uu!;ZWs!<<'!rr3'#s8N)trrN3#s82lqrr<&prr<&urrW9$rrE&u"p"]'!<<'!
+rr3'#s8N)Hs8E#ls*t~>
+cMmkEKDtuQJ:N4Nec,V7rr2s`JcGBB!!%TM^&J-6J:PW=!!)orq>gNp!!*#ur;cisrrE&u!!)fo
+!!)rs!!)ut!s&B$!<2uu!;ZWs!<<'!rr3'#s8N)trrN3#s82lqrr<&prr<&urrW9$rrE&u"p"]'
+!<<'!rr3'#s8N)HrrN1NJG0"n~>
+cMmkEKE(oNJcF:#!!*#u!!%TMo`"mkJcEF`rW'q;!!)fo!!)or!s&B$!<2uu!;uj!!<<'!q#:<o
+r;Q`srVls"s8N)urr<&prrW9$rrE&u!s&B$!<)p"!<<'!qYpTsrrDoq!!*#u!s&B$!<3!&!<<'!
+s8N)urrW9$rrCIHrW)ZlJ,~>
+cMmkEKE(oNJcF:#!'pP`!'l,8o`"mkJcEF`rW'q;!!)fo!!)or!s&B$!<2uu!;uj!!<<'!q#:<o
+r;Q`srVls"s8N)urr<&prrW9$rrE&u!s&B$!<)p"!<<'!qYpTsrrDoq!!*#u!s&B$!<3!&!<<'!
+s8N)urrW9$rrCIHrW)ZlJ,~>
+cMmkEKDtuQJ:N4Nec,V7rr2s`JcGBB!!%TM^&J-6J:PW=!!)fo!!)or!s&B$!<2uu!;uj!!<<'!
+q#:<or;Q`srVls"s8N)urr<&prrW9$rrE&u!s&B$!<)p"!<<'!qYpTsrrDoq!!*#u!s&B$!<3!&
+!<<'!s8N)urrW9$rrCIH!W[b$pA]X~>
+cMmkEKE(oNJcF=$!!)rs!!%TMp&>!lJcEF`rW'q;!!)fo!!)or!s&B$!<2uu!;uj!!<<'!q#:<o
+r;Zcsrr33's8N*!rr<&prrW9$rrE&u!s&B$!<3#u!<<'!!;c]s!<3&qrt,82rr<'!rrE*!!!*'!
+!<<'!rr3'#s8N)Hs8E#ls*t~>
+cMmkEKE(oNJcF=$!'pJ^!'l,8p&>!lJcEF`rW'q;!!)fo!!)or!s&B$!<2uu!;uj!!<<'!q#:<o
+r;Zcsrr33's8N*!rr<&prrW9$rrE&u!s&B$!<3#u!<<'!!;c]s!<3&qrt,82rr<'!rrE*!!!*'!
+!<<'!rr3'#s8N)Hs8E#ls*t~>
+cMmkEKDtuQJ:N4Nf)G_8r;Qa^JcGEC!!%TM^&J-6J:PW=!!)fo!!)or!s&B$!<2uu!;uj!!<<'!
+q#:<or;Zcsrr33's8N*!rr<&prrW9$rrE&u!s&B$!<3#u!<<'!!;c]s!<3&qrt,82rr<'!rrE*!
+!!*'!!<<'!rr3'#s8N)HrrN1NJG0"n~>
+cMmkEKE(oNJcF=$!!)rs!!%TMp&>!lJcEF`rW'q;!!)fo!!)or!!*#uqu?`srW)os!!)forW)uu
+!<E0!!<)rt!!3*"q>UNss8N)urr<&us8E!!rrE&ur;clt!!*#u!s&B$!<)rt!!3*"rr;uu#QFf(
+rrE*!!<2uu!<2uu!7LoH!;?GC~>
+cMmkEKE(oNJcF=$!'pJ^!'l,8p&>!lJcEF`rW'q;!!)fo!!)or!!*#uqu?`srW)os!!)forW)uu
+!<E0!!<)rt!!3*"q>UNss8N)urr<&us8E!!rrE&ur;clt!!*#u!s&B$!<)rt!!3*"rr;uu#QFf(
+rrE*!!<2uu!<2uu!7LoH!;?GC~>
+cMmkEKDtuQJ:N4Nf)G_8r;Qa^JcGEC!!%TM^&J-6J:PW=!!)fo!!)or!!*#uqu?`srW)os!!)fo
+rW)uu!<E0!!<)rt!!3*"q>UNss8N)urr<&us8E!!rrE&ur;clt!!*#u!s&B$!<)rt!!3*"rr;uu
+#QFf(rrE*!!<2uu!<2uu!7LlK!.]Uns*t~>
+cMmkEKE(oNJcF=$!!)rs!!%TMp&>!lJcEF`rW'q;!!(jTr;cZn!!)Wjr;bIL!!'_4rW)ZlJ,~>
+cMmkEKE(oNJcF=$!'pJ^!'l,8p&>!lJcEF`rW'q;!!(jTr;cZn!!)Wjr;bIL!!'_4rW)ZlJ,~>
+cMmkEKDtuQJ:N4Nf)G_8r;Qa^JcGEC!!%TM^&J-6J:PW=!!(jTr;cZn!!)Wjr;bIL!!'_4!W[b$
+pA]X~>
+cMmkEKE(oNJcF@%!!)lq!!%TMpAY*mJcEF`rW'q;!!(FH!!(.@r;aM1rW)ZlJ,~>
+cMmkEKE(oNJcF@%!'pD\!'l,8pAY*mJcEF`rW'q;!!(FH!!(.@r;aM1rW)ZlJ,~>
+cMmkEKDtuQJ:N4NfDbh9qYpO\JcGHD!!%TM^&J-6J:PW=!!(FH!!(.@r;aM1!W[b$pA]X~>
+cMmkEKE(oNJcF@%!!)lq!!%TMpAY*mJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF@%!'pD\!'l,8pAY*mJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4NfDbh9qYpO\JcGHD!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF@%!!)lq!!%TMpAY*mJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF@%!'pD\!'l,8pAY*mJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4NfDbh9qYpO\JcGHD!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcFC&!!)fo!!%TMp\t3nJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcFC&!'p>Z!'l,8p\t3nJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Nf`(q:q#:=ZJcGKE!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEdf0:Ili-qbnG`Rjs8N)^rr<&qs8E"Ls4I>O!;QQo!.k1Err<&Irr<&brr<&grrW9$rrD6^
+!!'D+rW'q;!!%TMci<tEpA]X~>
+cMmkEdf0:Ili-qbnG`Rjs8N)^rr<&qs8E"Ls4I>O5kt?Z5_8t0rr<&Irr<&brr<&grrW9$rrD6^
+!!'D+rW'q;!!%TMci<tEpA]X~>
+cMmkEdf0:Ili-qbnG`Rjs8N)^rr<&qrrN1NJ:[aQrr>=Zrr><8s7cNn!7LlI!:0Xb!:^!j!<<'!
+kPkM^[/U1-J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEli-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lr;Z`rJcFC&!!)fo
+!!%TMp\t3nli-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6l[f?=,`W#o<
+JcF'rrW)ZlJ,~>
+cMmkEli-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lr;Z`rJcFC&!'p>Z
+!'l,8p\t3nli-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6l[f?=,`W#o<
+JcF'rrW)ZlJ,~>
+cMmkEli-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lr;QfuJ:N4Nf`(q:
+q#:=ZJcGKE!!)?b!!)cn!!)Zk!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquF2*!W[b$
+`W#o<JcF'r!W[b$pA]X~>
+cMmkEq#:<oqZ$Np!<<#urr;rts8W&urr;rts8N'!rr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u
+!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDoqrW%NLg&D$PpAY*mJcGNF!!)fo
+!!)lqrVururW)rtrW)uurW)rtrW)uu!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rVururW)uu
+#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uu[/^+*`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oqZ$Np!<<#urr;rts8W&urr;rts8N'!rr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u
+!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDoqrW%NLg&D%;pAY+XJcGNF!!)fo
+!!)lqrVururW)rtrW)uurW)rtrW)uu!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rVururW)uu
+#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uu[/^+*`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oqZ$Np!<<#urr;rts8W&urr;rts8N'!rr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u
+!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDoq!W[b$JcFF'!'p8X!'l,8q#:<o
+q#:<oqZ$Np!<<#urr;rts8W&urr;rts8N'!rr2rurVuis!<<#u!WN/trs&Q(rrE'!s8W&u!<<#u
+s8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrBG+!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEq#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&orr<&srr<&urr<&urr<&urr<&urrN3#!<2uu
+!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!qu?WqJcFF'oDjIBq#:<o
+q#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&orr<&srr<&urr<&urr<&urr<&urrN3#!<2uu!<2uu
+!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'![K$4+`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&orr<&srr<&urr<&urr<&urr<&urrN3#!<2uu
+!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!qu?WqJcFF'oK\!-q#:<o
+q#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&orr<&srr<&urr<&urr<&urr<&urrN3#!<2uu!<2uu
+!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'![K$4+`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oqu6Wrr;Q`srr2rurr3'#s8N)urr<&orr<&srr<&urr<&urr<&urr<&urrN3#!<2uu
+!<2uu!<3#u!<3!$!<<'!!<3!#!<<'!rr3'#s8N)urr<&urriE&rrE'!qu6]tJ:N4Ng&L\0JcGNF
+!!)fo!!)or!!)rs!!*#u!!*#u!s&B$!<2uu!;QQo!;uis!<2uu!<2uu!<2uu!<3!"!<3&urr<&u
+rr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrBJ,!W[b$`W#o<JcF'r!W[b$
+pA]X~>
+cMmkEq#:<oqu6Wrr;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!*#u!!)`mrW%NLe,KCJJcG<@!!)fo!!)or!!)rs
+!!)lq!s&B$!<2uu!;QQo!;uis!<2uu!<2uu!<3!#!<<'!rr3'#s8N)urr<&urr<&trrW9$rrE#t
+!s&B$!<3!#!<<'!rr2rurr2ruYlF\&`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oqu6Wrr;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!*#u!!)`mrW%NLe,KD5JcG<@!!)fo!!)or!!)rs
+!!)lq!s&B$!<2uu!;QQo!;uis!<2uu!<2uu!<3!#!<<'!rr3'#s8N)urr<&urr<&trrW9$rrE#t
+!s&B$!<3!#!<<'!rr2rurr2ruYlF\&`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oqu6Wrr;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!*#u!!)`m!W[b$JcF4!!'l,8o)A[iq#:<oqu6Wr
+r;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<2uu!<2uu!<)p"!<<'!
+rVls"s8N)urrW9$rrE&u!!*#u!!'8'!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEqu?KmrVultrr2rurVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHHjrW%NLe,KCJJcG<@!!)orq>gKorrE&u!!)ut
+r;clt!!)utrrDoq!!)rs!!*#u!!)ut!W`6#rr2rurr3'#s8N)urr<&urr<&trrW9$rrE#t!s&B$
+!<3!#!<<'!rr;lrYlF\&`W(Jhb5h89J,~>
+cMmkEqu?KmrVultrr2rurVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHHjrW%NLe,KD5JcG<@!!)orq>gKorrE&u!!)ut
+r;clt!!)utrrDoq!!)rs!!*#u!!)ut!W`6#rr2rurr3'#s8N)urr<&urr<&trrW9$rrE#t!s&B$
+!<3!#!<<'!rr;lrYlF\&`W(Jhb5h89J,~>
+cMmkEqu?KmrVultrr2rurVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu
+!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHHj!W[b$JcF4!!'l,8o)A[iqu?KmrVultrr2ru
+rVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$!<2uu!<2uu!<)p"!<<'!rVls"
+s8N)urrW9$rrE&uquEu$!W[b$`W(JhblIcopA]X~>
+cMmkEq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2ruo)J[hJcF4!!!%TMo)A[iq#:<oq#:Ers8N)urr<&u
+rrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&urr<&trrW9$rrE#t!s&B$!<3!#
+!<<'!rr2ruXT/8"`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2ruo)J[hJcF4!!'l,8o)A[iq#:<oq#:Ers8N)urr<&u
+rrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&urr<&trrW9$rrE#t!s&B$!<3!#
+!<<'!rr2ruXT/8"`W#o<JcF'rrW)ZlJ,~>
+cMmkEq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rr<&u
+rr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2ruo)AakJ:N4Ne,KD5JcG<@!!)fo!!)fo!s&B$!<2uu
+!<3!#!<<'!qu6Wrqu6Wrr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"!<<'!rVls"s8N)u
+rrW9$rrE&u!!',#!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#!<2uu
+!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&is8E"Ls3puJ!.k1@rr<&orr<&orrW9$rrE&u
+!!*#u!s&B$!;lcr!;lcr!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr2rurr2rurVm!#s8N'!rr3<*
+s8N*!rr<'!rrE&u!!',#rW'q;!!%TMci<tEpA]X~>
+cMmkEq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#!<2uu
+!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&is8E"Ls3puJ5_8t+rr<&orr<&orrW9$rrE&u
+!!*#u!s&B$!;lcr!;lcr!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr2rurr2rurVm!#s8N'!rr3<*
+s8N*!rr<'!rrE&u!!',#rW'q;!!%TMci<tEpA]X~>
+cMmkEq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#!<2uu
+!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&irrN1NJ:[aLrr><8s760i!;QQo!;QQr!<<'!
+rr2rurr3'#s8N)rrr<&rrr<&srr<&urr<&trriE&!<<'!r;QfurrE&u!!*#u!!)ut"9AK%!!*#u
+$3:,+!<<'!!<<'!rr2ruXT&>%J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEq#:<oqu?WqrVlitrr;lrs8N-#s8W&urr2rurr;lrs8N'!rr2rurVls"s8N)qrrN3#!<3!#
+!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;?Hl!.k1!rr<%Ms760i!;QQo!;lfq!<)ot!<3#r
+!<<'#!<<)u!<2uu!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u!s&B$!<)p#!<<'!s8E#ss8N'"
+rrE&u!!*#ur;a)%rW'q;!!%TMci<tEpA]X~>
+cMmkEq#:<oqu?WqrVlitrr;lrs8N-#s8W&urr2rurr;lrs8N'!rr2rurVls"s8N)qrrN3#!<3!#
+!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;?Hl!.k1!rr><8s760i!;QQo!;lfq!<)ot!<3#r
+!<<'#!<<)u!<2uu!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u!s&B$!<)p#!<<'!s8E#ss8N'"
+rrE&u!!*#ur;a)%rW'q;!!%TMci<tEpA]X~>
+cMmkEq#:<oqu?WqrVlitrr;lrs8N-#s8W&urr2rurr;lrs8N'!rr2rurVls"s8N)qrrN3#!<3!#
+!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;?Eo!.]TNs3puJ5_8t+rr<&orr<&rs8E#srr<&u
+s82lsrrN3#s8E#trr<&us82lsrr<&urr<&trrW9$rrDoq!W`6#rr3'#s8N)trr`?%rrE)u!<)rt
+!!3*"rr2rurr;osYl=b)J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNJcF4!!!%TMo)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNJcF4!!'l,8o)A[iJcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:N4Ne,KD5JcG<@!!%TM^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlH:7!!';(!!%TMr;Q`sli-qbnG`Rjs8N)fs8E#;rr<%Ms3L`E!;?GC~>
+cMmkEKE(oNPlH:7!!';(!!%TMr;Q`sli-qbnG`Rjs8N)fs8E#;rr<%Ms3L`E!;?GC~>
+cMmkEKDtuQJ:NmaJH,ZMZ2Xe(JcGZJ!!)?b!!)Ng!s&B$!:Tph!.]U=rr<%Ms3L]H!.]Uns*t~>
+cMmkEKE(oNPlC^`K)YfNZ2Xe(bl7YCh>[HTo)A[ikPkM^r;Q`srr2rup&>!lrVlitrr2rupAY*m
+oD\djrr;rt`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`K)YfNZ2Xe(bl7YCh>[HTo)A[ikPkM^r;Q`srr2rup&>!lrVlitrr2rupAY*m
+oD\djrr;rt`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!%WN!!';(!!(7C!!(jT!!)Ti!!)3^!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m
+!!)Wj!!*#u!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)YfNZ2Xe(q#:<oqZ$Nps8N'!rr3E-s8N*!!!*$!rr<'!s8E#trriE&!!*'!
+rW)`nrW)uu!!)rs!<E0!!<3!%!<3$!s8W&urr;rtqZ$Nps8N6&rr<'!s8E#ss8E#trr<&urr<&t
+s8Duus8E!!rrDus#6=f(!<3'!s8Duus8E#urs8]*!!*$!s8N*!rW)rt!!*#u!<E0!!<<)u!6+s<
+!.k0rs8E#ls*t~>
+cMmkEKE(oNPlC^`K)YfNZ2Xe(q#:<oqZ$Nps8N'!rr3E-s8N*!!!*$!rr<'!s8E#trriE&!!*'!
+rW)`nrW)uu!!)rs!<E0!!<3!%!<3$!s8W&urr;rtqZ$Nps8N6&rr<'!s8E#ss8E#trr<&urr<&t
+s8Duus8E!!rrDus#6=f(!<3'!s8Duus8E#urs8]*!!*$!s8N*!rW)rt!!*#u!<E0!!<<)u!6+s<
+!.k0rs8E#ls*t~>
+cMmkEKDtuQJ:Nma!!%WN!!';(!!)fo!!)lqrW)uu!!*#u%06G.!<3$!rrE'!!<<)u!<3!%!<3$!
+s8W&uq#C<ns8N'!r;Qcts8E#trriE&!!*'!rW)rtrW)fprW)uu"T\Q&!<<)u!<)rs!<2uu!<2uu
+!<)rs!!*&u!!3*"r;R!%s8N*!!<<)u!!*&u!<<'*!<3$!rrE*!!<<#urr2rurr3!!s8E#urrN1N
+JAqNg!.k0rrrN1NJG0"n~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3*$s8N'!rr;uurr2rurr3<*s8N'!s8N*!
+rrDio!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!<2uu!;?Em!<3#u!<2uu!<3!#!<<'!rr2ru
+qu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#urrE&u"9AK%!!*#u!s&B$!<3!#!<<'!
+rr;rt`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3*$s8N'!rr;uurr2rurr3<*s8N'!s8N*!
+rrDio!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!<2uu!;?Em!<3#u!<2uu!<3!#!<<'!rr2ru
+qu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#urrE&u"9AK%!!*#u!s&B$!<3!#!<<'!
+rr;rt`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*q#:<oqu6Wrr;Q`srr3*$s8N'!rr;uurr2rurr3<*s8N'!
+s8N*!rrDio!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!<2uu!;?Em!<3#u!<2uu!<3!#!<<'!
+rr2ruqu6Wrr;Q`srr2rurr2rurr2rurr3$"rrE&u!!*#u!!*#urrE&u"9AK%!!*#u!s&B$!<3!#
+!<<'!rr3$"J:PW=!!%TMci4%HJ:R@nJ,~>
+ci8OrrW&2_!!)$Yq#KUXr;an<rW';)!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!<3!#!<<'!
+rr3'#s8N)orr<&urrW9$rrE&u!W`6#rr3'#s8N)urrW9$rrE&u!!)`m!!*#u!!)ut!!*#u!s&B$
+!<2uu!;lcr!;uis!<2uu!<2uu!<3!#!<<'!rr3'#s8N)urr<&urr<&trrW9$rrE#t!s&B$!<3!#
+!<<'!rr;rt`W#o<JcF'rrW)ZlJ,~>
+ci8OrrW&2_!!)$Yq#KUXr;an<rW';)!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!<3!#!<<'!
+rr3'#s8N)orr<&urrW9$rrE&u!W`6#rr3'#s8N)urrW9$rrE&u!!)`m!!*#u!!)ut!!*#u!s&B$
+!<2uu!;lcr!;uis!<2uu!<2uu!<3!#!<<'!rr3'#s8N)urr<&urr<&trrW9$rrE#t!s&B$!<3!#
+!<<'!rr;rt`W#o<JcF'rrW)ZlJ,~>
+ci8Or!W[b$PlC^`irAfSkPtJ\a8Z2@J:P!+!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!<3!#
+!<<'!rr3'#s8N)orr<&urrW9$rrE&u!W`6#rr3'#s8N)urrW9$rrE&u!!)`m!!*#u!!)ut!!*#u
+!s&B$!<2uu!;lcr!;uis!<2uu!<2uu!<3!#!<<'!rr3'#s8N)urr<&urr<&trrW9$rrE#t!s&B$
+!<3!#!<<'!rr3$"J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlC^`huE]Vjo>>\rr3*$s8N'!p](6nf`1pNZi:"*qu?Kmrr2rur;Q`srr3'#s8N)t
+rr<&ts82lsrr<&urrW9$rrDioquH`r"9AH%s8Vuss8N'!rr3'#s8N)ts8N)orr<&urr<&ts82ls
+s82lorr<&srr<&urr<&trrN3#!<2uu!<3!#!<<'!rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$
+!<3#t!6+s<!.k0rs8E#ls*t~>
+cMmkEKE(oNPlC^`huE]Vjo>>\rr3*$s8N'!p](6nf`1pNZi:"*qu?Kmrr2rur;Q`srr3'#s8N)t
+rr<&ts82lsrr<&urrW9$rrDioquH`r"9AH%s8Vuss8N'!rr3'#s8N)ts8N)orr<&urr<&ts82ls
+s82lorr<&srr<&urr<&trrN3#!<2uu!<3!#!<<'!rr2rurr2rurVls"s8N)trrW9$rrE&u!s&B$
+!<3#t!6+s<!.k0rs8E#ls*t~>
+cMmkEKDtuQJ:Nma!!(pVrrD0\rrE&u"9AK%!!)cnrrC^O!W[b$Zi:"*qu?Kmrr2rur;Q`srr3'#
+s8N)trr<&ts82lsrr<&urrW9$rrDioquH`r"9AH%s8Vuss8N'!rr3'#s8N)ts8N)orr<&urr<&t
+s82lss82lorr<&srr<&urr<&trrN3#!<2uu!<3!#!<<'!rr2rurr2rurVls"s8N)trrW9$rrE&u
+!s&B$!<3!"!.]U=rr<%Ms3L]H!.]Uns*t~>
+cMmkEKE(oNPlC^`huE]VrVult!ri9#r;cfrr;cltrW)uurrDusr;cltr;cltr;cisr;bdUrW';)
+!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!;lcr!<3!#!<<'!q#:<oqYp^!rrE*!!;lcr!<3!#
+!<<'!qu6Wrq>UEprr2rurVlitqu6Wrp\t3nr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&urW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`huE]VrVult!ri9#r;cfrr;cltrW)uurrDusr;cltr;cltr;cisr;bdUrW';)
+!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!;lcr!<3!#!<<'!q#:<oqYp^!rrE*!!;lcr!<3!#
+!<<'!qu6Wrq>UEprr2rurVlitqu6Wrp\t3nr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu!<)p"
+!<<'!rVls"s8N)urrW9$rrE&urW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trr<-#!<;utrVufrs8W&us8W*!r;Z]qs8W#ts8W#trr;osi;WiY
+J:P!+!!)fo!!)or!!)rs!!*#u!s&B$!<)ot!<)ot!;lcr!<3!#!<<'!q#:<oqYp^!rrE*!!;lcr
+!<3!#!<<'!qu6Wrq>UEprr2rurVlitqu6Wrp\t3nr;Q`srr2rurVm!#rrE*!q>^Qr!<2uu!<2uu
+!<)p"!<<'!rVls"s8N)urrW9$rrE&u!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`huE]VrVuisr;Zcss8W*!rVult"9/?$s8E#rs8N)rs8N*!s8N)us8N)Ts8E#)
+rr<&orr<&rrr<&srs&Q(rr<'!rrE#t!!)ut!!)or!!*#u!s&B$!;QQo!;c^!!<3'!rrDrr!!*#u
+!s&B$!;lcr!;ZWp!<2uu!<)ot!;lcr!;HKn!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr2rurr2ru
+rVm!#s8N'!rr3<*s8N*!rr<'!rrE&urW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`huE]VrVuisr;Zcss8W*!rVult"9/?$s8E#rs8N)rs8N*!s8N)us8N)Ts8E#)
+rr<&orr<&rrr<&srs&Q(rr<'!rrE#t!!)ut!!)or!!*#u!s&B$!;QQo!;c^!!<3'!rrDrr!!*#u
+!s&B$!;lcr!;ZWp!<2uu!<)ot!;lcr!;HKn!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr2rurr2ru
+rVm!#s8N'!rr3<*s8N*!rr<'!rrE&urW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trW)lrrrE*!rrE#trr<0$!!*&u!;uls!;lfr!<<*!!<3#u!8[YV
+!.]U+rr<&orr<&rrr<&srs&Q(rr<'!rrE#t!!)ut!!)or!!*#u!s&B$!;QQo!;c^!!<3'!rrDrr
+!!*#u!s&B$!;lcr!;ZWp!<2uu!<)ot!;lcr!;HKn!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr2ru
+rr2rurVm!#s8N'!rr3<*s8N*!rr<'!rrE&u!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`huE]VrVultqu?Zrs8W*!rVult"TJH%s8W#trr;uuqu?Zrs8W*!rr;rthZ*QT
+Zi:"*q#:<oqZ$Nprr;uu"TJK%rrE#t!!)rsr;clt!!*#u!!*#u!!)for;cfr!!)utr;clt!!*#u
+!!*#u!W`9#rW)]m!s&B$!;ulq!<3#s!<<'!!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u!s&B$
+!<)p#!<<'!s8E#ss8N'"rrE&u!W`9#rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`huE]VrVultqu?Zrs8W*!rVult"TJH%s8W#trr;uuqu?Zrs8W*!rr;rthZ*QT
+Zi:"*q#:<oqZ$Nprr;uu"TJK%rrE#t!!)rsr;clt!!*#u!!*#u!!)for;cfr!!)utr;clt!!*#u
+!!*#u!W`9#rW)]m!s&B$!;ulq!<3#s!<<'!!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u!s&B$
+!<)p#!<<'!s8E#ss8N'"rrE&u!W`9#rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trrDrrrrE*!rrE#trr<3%!!*'!r;cisrrDrrrrE*!rrE&urW(gT
+!W[b$Zi:"*q#:<oqZ$Nprr;uu"TJK%rrE#t!!)rsr;clt!!*#u!!*#u!!)for;cfr!!)utr;clt
+!!*#u!!*#u!W`9#rW)]m!s&B$!;ulq!<3#s!<<'!!<3#r!<<'!!<2uu!<)p"!<<'!qYpTsrrE&u
+!s&B$!<)p#!<<'!s8E#ss8N'"rrE&u"T\T&!.]U=rr<%Ms3L]H!.]Uns*t~>
+cMmkEKE(oNPlC^`huE]VrVultrVufrs8W*!rVucqrVuiss8W*!rVufrs8W*!rVuishuEZUZi:"*
+aT)2=gAh*OV>pMp`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`huE]VrVultrVufrs8W*!rVucqrVuiss8W*!rVufrs8W*!rVuishuEZUZi:"*
+aT)2=gAh*OV>pMp`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trrE#tr;cltrrE#tquH]qrW)uurrE#tr;cltrrE#trW(jU!W[b$
+Zi:"*aT)2=gAh*OV>gSsJ:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlC^`huE]VrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!rr;uu#6+Z's8N'!r;Z`r
+i;`cVZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`huE]VrVultrr;uu#6+Z's8N'!rVultq>^Hps8W*!rr;uu#6+Z's8N'!r;Z`r
+i;`cVZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trrE&urr<9'!!*'!!!)utrrDlprrE*!rrE&urr<9'!!*'!!!)rs
+rW(mV!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`huE]VrVultrr;uu#6+Z's8N'!rVultrVlitrr;uus8W*!rr;uu#6+Z's8N'!
+qu?Zri;`cVZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`huE]VrVultrr;uu#6+Z's8N'!rVultrVlitrr;uus8W*!rr;uu#6+Z's8N'!
+qu?Zri;`cVZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trrE&urr<9'!!*'!!!)utrrE#t!!*#urrE*!rrE&urr<9'!!*'!
+!!)orrrD!W!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`huE]VrVultrVucqs8W#ts8W#ts8W#trVuiss8Vuss8W&u!<;uthuEZUZi:"*
+JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`huE]VrVultrVucqs8W#ts8W#ts8W#trVuiss8Vuss8W&u!<;uthuEZUZi:"*
+JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!(pVrrE#trrE#tquHcsr;cltr;cltr;cfrrW)uuquHcsrVurur;baT!W[b$
+Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcFR+!!)?b!!)iprW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcFR+!!)?b!!)iprW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcFR+!!)?b!!)ip!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*bl7YCh>[HTq#:<oh>[HTkPkM^r;Q`srr2rup&>!lrVlitrr;rt
+`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*bl7YCh>[HTq#:<oh>[HTkPkM^r;Q`srr2rup&>!lrVlitrr;rt
+`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*bl7YCh>[HTq#:<oh>[HTkPkM^r;Q`srr2rup&>!lrVlit
+rr3$"J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqZ$Nps8N'!rr3E-s8N*!!!*$!rr<'!s8E#trriE&!!*'!
+rW)`nrW)uu!!)rs!<E0!!<3!%!<3$!s8W&uqZ$Np!WN/ts8N'!s8E#ss8E#ss8E#ps8E#urriE&
+!!*'!rW)osrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rVurur;ah:!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqZ$Nps8N'!rr3E-s8N*!!!*$!rr<'!s8E#trriE&!!*'!
+rW)`nrW)uu!!)rs!<E0!!<3!%!<3$!s8W&uqZ$Np!WN/ts8N'!s8E#ss8E#ss8E#ps8E#urriE&
+!!*'!rW)osrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rVurur;ah:!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*q#:<oqZ$Nps8N'!rr3E-s8N*!!!*$!rr<'!s8E#trriE&
+!!*'!rW)`nrW)uu!!)rs!<E0!!<3!%!<3$!s8W&uqZ$Np!WN/ts8N'!s8E#ss8E#ss8E#ps8E#u
+rriE&!!*'!rW)osrW)rt!!*#u!!)utrVururW!!!!;uj%!<<'!rrE*!rW!*$!!%P"`W#o<JcF'r
+!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3*$s8N'!rr;uurr2rurr3<*s8N'!s8N*!
+rrDio!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!;QQr!<<'!r;Z`rrr3'#s8N)urrW9$rrDcm
+!!*#urrE&u!!*#u!s&B$!<2uu!;lcr!;uis!<2uu!<2uu!<2uu!<3!"!<3&urr<&us8E#;rr<%M
+s3L`E!;?GC~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3*$s8N'!rr;uurr2rurr3<*s8N'!s8N*!
+rrDio!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!;QQr!<<'!r;Z`rrr3'#s8N)urrW9$rrDcm
+!!*#urrE&u!!*#u!s&B$!<2uu!;lcr!;uis!<2uu!<2uu!<2uu!<3!"!<3&urr<&us8E#;rr<%M
+s3L`E!;?GC~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*q#:<oqu6Wrr;Q`srr3*$s8N'!rr;uurr2rurr3<*s8N'!
+s8N*!rrDio!!*#u!s&B$!<3!"!<3&ursAc+rr<'!rrE*!!;QQr!<<'!r;Z`rrr3'#s8N)urrW9$
+rrDcm!!*#urrE&u!!*#u!s&B$!<2uu!;lcr!;uis!<2uu!<2uu!<2uu!<3!"!<3&urr<&urrN1N
+JAqNg!.k0rrrN1NJG0"n~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3'#s8N)trr<&trr<&urrW9$rrE&u!s&B$
+!;QQo!<3!#!<<'!rr3$"rrE&u!s&B$!<3!#!<<'!q#:<orr2rurr3$"rrE#t!s&B$!<3!#!<<'!
+pAY*mrr2rurVlitrr3'#s8N)urr<&rrr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<3#t!6+s<
+!.k0rs8E#ls*t~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3'#s8N)trr<&trr<&urrW9$rrE&u!s&B$
+!;QQo!<3!#!<<'!rr3$"rrE&u!s&B$!<3!#!<<'!q#:<orr2rurr3$"rrE#t!s&B$!<3!#!<<'!
+pAY*mrr2rurVlitrr3'#s8N)urr<&rrr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<3#t!6+s<
+!.k0rs8E#ls*t~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*q#:<oqu6Wrr;Q`srr3'#s8N)trr<&trr<&urrW9$rrE&u
+!s&B$!;QQo!<3!#!<<'!rr3$"rrE&u!s&B$!<3!#!<<'!q#:<orr2rurr3$"rrE#t!s&B$!<3!#
+!<<'!pAY*mrr2rurVlitrr3'#s8N)urr<&rrr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$!<3!"
+!.]U=rr<%Ms3L]H!.]Uns*t~>
+cMmkEKE(oNPlC^`K)bfMZi:"*qu?Kmrr2rur;Q`srr3'#s8N)trr<&ts82lsrr<&urrW9$rrDio
+quH`r"9AH%s8Vuss8N'!rr3'#s8N)orr<&urr<&urrN3#!<)p!!<<)s!<3#u!;QQo!<2uu!<)rq
+!<<)s!;lcr!;uis!<2uu!<)p!!<3&urr<&urrW9$rrE&urW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*qu?Kmrr2rur;Q`srr3'#s8N)trr<&ts82lsrr<&urrW9$rrDio
+quH`r"9AH%s8Vuss8N'!rr3'#s8N)orr<&urr<&urrN3#!<)p!!<<)s!<3#u!;QQo!<2uu!<)rq
+!<<)s!;lcr!;uis!<2uu!<)p!!<3&urr<&urrW9$rrE&urW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*qu?Kmrr2rur;Q`srr3'#s8N)trr<&ts82lsrr<&urrW9$
+rrDioquH`r"9AH%s8Vuss8N'!rr3'#s8N)orr<&urr<&urrN3#!<)p!!<<)s!<3#u!;QQo!<2uu
+!<)rq!<<)s!;lcr!;uis!<2uu!<)p!!<3&urr<&urrW9$rrE&u!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3'#s8N)trr<&trr<&rrr<&urrW9$rrDio
+!!)lq"T\Q&s8N)rrr<&urrW9$rrDio!!)ut"T\Q&s8N)trrW9$rrDio!!)ip!!*#u!!)ut!!)or
+!!)cn!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!s8E#;rr<%Ms3L`E!;?GC~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqu6Wrr;Q`srr3'#s8N)trr<&trr<&rrr<&urrW9$rrDio
+!!)lq"T\Q&s8N)rrr<&urrW9$rrDio!!)ut"T\Q&s8N)trrW9$rrDio!!)ip!!*#u!!)ut!!)or
+!!)cn!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!s8E#;rr<%Ms3L`E!;?GC~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*q#:<oqu6Wrr;Q`srr3'#s8N)trr<&trr<&rrr<&urrW9$
+rrDio!!)lq"T\Q&s8N)rrr<&urrW9$rrDio!!)ut"T\Q&s8N)trrW9$rrDio!!)ip!!*#u!!)ut
+!!)or!!)cn!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!rrN1NJAqNg!.k0rrrN1NJG0"n~>
+cMmkEKE(oNPlH:7rW';)!!)fo!!)or!!)rs#6=f(!!*'!!<)ot!<)ot!;lcr!<3!#!<<'!q#:<o
+qYp^!rrE*!!;lcr!<3!#!<<'!q#:<orVm'%rrE*!!!*#u!s&B$!;QQo!;ZWp!<2uu!<)ot!;lcr
+!;HKn!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr;rt`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlH:7rW';)!!)fo!!)or!!)rs#6=f(!!*'!!<)ot!<)ot!;lcr!<3!#!<<'!q#:<o
+qYp^!rrE*!!;lcr!<3!#!<<'!q#:<orVm'%rrE*!!!*#u!s&B$!;QQo!;ZWp!<2uu!<)ot!;lcr
+!;HKn!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr;rt`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:NmaJH,`OJ:P!+!!)fo!!)or!!)rs#6=f(!!*'!!<)ot!<)ot!;lcr!<3!#!<<'!
+q#:<oqYp^!rrE*!!;lcr!<3!#!<<'!q#:<orVm'%rrE*!!!*#u!s&B$!;QQo!;ZWp!<2uu!<)ot
+!;lcr!;HKn!;uis!<2uu!<)p$!<3'!rrDus!W`6#rr3$"J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqZ$Nprr;uu"TJK%rrE#t!!)rsr;clt!!*#u!!*#u!!)fo
+r;cfr!!)utr;clt!!*#u!!*#u!!)fo!!)ut!!*#u!<E0!!<)rr!<<)u!;HKq!<<'!r;Z]qrr;os
+s8N'!rr;lrs8N'!rr2rurVls"s8N)qrr`?%!<<)u!6+s<!.k0rs8E#ls*t~>
+cMmkEKE(oNPlC^`K)bfMZi:"*q#:<oqZ$Nprr;uu"TJK%rrE#t!!)rsr;clt!!*#u!!*#u!!)fo
+r;cfr!!)utr;clt!!*#u!!*#u!!)fo!!)ut!!*#u!<E0!!<)rr!<<)u!;HKq!<<'!r;Z]qrr;os
+s8N'!rr;lrs8N'!rr2rurVls"s8N)qrr`?%!<<)u!6+s<!.k0rs8E#ls*t~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*q#:<oqZ$Nprr;uu"TJK%rrE#t!!)rsr;clt!!*#u!!*#u
+!!)for;cfr!!)utr;clt!!*#u!!*#u!!)fo!!)ut!!*#u!<E0!!<)rr!<<)u!;HKq!<<'!r;Z]q
+rr;oss8N'!rr;lrs8N'!rr2rurVls"s8N)qrs&Q(!<<'!J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*aT)2=i;``Uq>UEprr2rumJm+b`;ff:`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*aT)2=i;``Uq>UEprr2rumJm+b`;ff:`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*aT)2=i;``Uq>UEprr2rumJm+b`;]l=J:PW=!!%TMci4%H
+J:R@nJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*R/[-drVlitXT/8"`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*R/[-drVlitXT/8"`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*R/[-drVlitXT&>%J:PW=!!%TMci4%HJ:R@nJ,~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`K)bfMZi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!%WN!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`df0:Ili-qbnG`Rjs8N)^rr<&ps8E#)s+(0\!6+s<!.k0rs8E#ls*t~>
+cMmkEKE(oNPlC^`df0:Ili-qbnG`Rjs8N)^rr<&ps8E#)s+(0\!6+s<!.k0rs8E#ls*t~>
+cMmkEKDtuQJ:Nma!!(II!!)?b!!)Ng!s&B$!9a@^!;ZWr!.]U+s+(0^!<7Sgrr<%Ms3L]H!.]Un
+s*t~>
+cMmkEKE(oNPlC^`li-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lqu?Wq
+Zi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKE(oNPlC^`li-qbp\t3no`"mkr;Q`srr2rup&>!lrVlitrr2rupAY*moD\djq#C6lqu?Wq
+Zi:"*JcEF`rW'q;!!%TMci<tEpA]X~>
+cMmkEKDtuQJ:Nma!!)?b!!)cn!!)Zk!!)rs!!*#u!!)]l!!)ut!!*#u!!)`m!!)Wj!!)foquHWo
+!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+cMmkEKE(oNPlC^`q#:<oqZ$Np!<<#urr;rts8W&urr;rts8N'!rr2rurVuis!<<#u!WN/trs&Q(
+rrE'!s8W&u!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDlprW';)!!%TM^&S'3
+`W#o<JcF'rrW)ZlJ,~>
+cMmkEKE(oNPlC^`q#:<oqZ$Np!<<#urr;rts8W&urr;rts8N'!rr2rurVuis!<<#u!WN/trs&Q(
+rrE'!s8W&u!<<#us8NB*rr<'!!<<'!s8E#trr<&urrE-"rW)rtrW)rtrrDlprW';)!!%TM^&S'3
+`W#o<JcF'rrW)ZlJ,~>
+cMmkEKDtuQJ:Nma!!)fo!!)lqrVururW)rtrW)uurW)rtrW)uu!!*#u!!)utrVururW!!!!;uj%
+!<<'!rrE*!rVururW)uu#lsu*!<3'!rrE)u!<2uu!<3!!!<<#urr;rtrr;uuq>UKrJ:P!+!!%TM
+^&J-6J:PW=!!%TMci4%HJ:R@nJ,~>
+cMrFqrrA;`!!)fo!!)or!!)rs!!*#u!!*#u!s&B$!<2uu!;QQo!;uis!<2uu!<2uu!<2uu!<3!"
+!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoqrW';)!!%TM
+^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMrFqrrA;`!!)fo!!)or!!)rs!!*#u!!*#u!s&B$!<2uu!;QQo!;uis!<2uu!<2uu!<2uu!<3!"
+!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoqrW';)!!%TM
+^&S'3`W#o<JcF'rrW)ZlJ,~>
+cMrFqs+$@6!!)fo!!)or!!)rs!!*#u!!*#u!s&B$!<2uu!;QQo!;uis!<2uu!<2uu!<2uu!<3!"
+!<3&urr<&urr<&us8N)urr`?%rr<&urrW9$rrE&u!s&B$!<2uu!<3!%!<<'!rrDoq!W[b$Zi:"*
+JcEF`!W[b$`W#o<JcF'r!W[b$pA]X~>
+bQ!.oPlC^`q#:<oqu6Wrr;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!*#u!!)]lrW';)!!%TM^&S'3`W#o<JcF'r
+rW)ZlJ,~>
+bQ!.oPlC^`q#:<oqu6Wrr;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!*#u!!)]lrW';)!!%TM^&S'3`W#o<JcF'r
+rW)ZlJ,~>
+bQ!0EPlC^`q#:<oqu6Wrr;Q`sqYpWts8N)urr<&orr<&srr<&urr<&urr<&urrW9$rrE&u!s&B$
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&u!!*#u!!)]l!W[b$Zi:"*JcEF`!W[b$`W#o<
+JcF'r!W[b$pA]X~>
+bQ!.oPlC^`qu?KmrVultrr2rurVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHEirW';)!!%TM^&S'3`W#o<JcF'rrW)Zl
+J,~>
+bQ!.oPlC^`qu?KmrVultrr2rurVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHEirW';)!!%TM^&S'3`W#o<JcF'rrW)Zl
+J,~>
+bQ!0EPlC^`qu?KmrVultrr2rurVufrs8N'!rVultqYpNqr;Q`srr2rurVlp!rrE&u!!*#u!s&B$
+!<2uu!<2uu!<)p"!<<'!rVls"s8N)urrW9$rrE&uquHEi!W[b$Zi:"*JcEF`!W[b$`W#o<JcF'r
+!W[b$pA]X~>
+JcC<$hu<ZVq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!
+rr<&urr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2runc/RgZi:"*JcEF`rW'q;JH3jnpA]X~>
+JcC<$hu<ZVq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!
+rr<&urr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2runc/RgZi:"*JcEF`rW'q;JH3jnpA]X~>
+JcC<$hu<ZVq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"9AH%s8Voq!WN0!
+rr<&urr<&trrW9$rrE#t!s&B$!<3!#!<<'!rr2runc&XjJ:P!+!!%TM^&J-6J:PW=JH3pps+'hC
+J,~>
+JcC<$hu<ZVq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#
+!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&hs8E#)rr<%Ms1SI3!5ebe!6tT<s*t~>
+JcC<$hu<ZVq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#
+!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&hs8E#)rr<%Ms1SI3!5ebe!6tT<s*t~>
+JcC<$hu<ZVq#:<oq#:Ers8N)urr<&urrW9$rrDrr!!)or!!)rs!!*#u!!)ut"T\Q&s8N)srrN3#
+!<2uu!<2uu!<)p#!<<'!!<3!*!<<'!s8N'!s8N)urr<&hrrN1NJ@#7U!.k0`rrN1NJAV>;JBi]=
+s*t~>
+JcC<$hu<ZVq#:<oqu?WqrVlitrr;lrs8N-#s8W&urr2rurr;lrs8N'!rr2rurVls"s8N)qrrN3#
+!<3!#!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;6Bk!42\*!.k0`s8E#8s+(0q!;?GC~>
+JcC<$hu<ZVq#:<oqu?WqrVlitrr;lrs8N-#s8W&urr2rurr;lrs8N'!rr2rurVls"s8N)qrrN3#
+!<3!#!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;6Bk!42\*!.k0`s8E#8s+(0q!;?GC~>
+JcC<$hu<ZVq#:<oqu?WqrVlitrr;lrs8N-#s8W&urr2rurr;lrs8N'!rr2rurVls"s8N)qrrN3#
+!<3!#!<<'!rVm!#s8N*!rW)osrr<*"!<2uu!<3#s!;6?n!.]U+rr<%Ms1SF6!.]U:s+,^GJG0"n~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$huA6-rW';)!!%TM^&S'3JcCE'J,~>
+JcC<$huA6-rW';)!!%TM^&S'3JcCE'J,~>
+JcC<$huA6-!W[b$Zi:"*JcEF`!W[b$JcCE'J,~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)bfMZi:"*JcEF`rW%NLK`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+!!%TM^&J-6J:N4NK`?Q~>
+JcC<$hu<ZVK)bfMZi>RV\H%3\K`?Q~>
+JcC<$hu<ZVK)bfMZi>RV\H%3\K`?Q~>
+JcC<$hu<ZVK)YlPJ:P!+JH3:^s+#\#K`?Q~>
+JcC<$hu<ZVK)bfMYlB7S]E!N_K`?Q~>
+JcC<$hu<ZVK)bfMYlB7S]E!N_K`?Q~>
+JcC<$hu<ZVK)YlPJ:Om(JUkC`JcCE'J,~>
+JcC<$hu<ZVK)bfMYlB7S]E!N_K`?Q~>
+JcC<$hu<ZVK)bfMYlB7S]E!N_K`?Q~>
+JcC<$hu<ZVK)YlPJ:Om(JUkC`JcCE'J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)bfMJcC<$JcC<$mf.e~>
+JcC<$hu<ZVK)YlPJ:N4NJcC<$JcG0<J,~>
+JcC<$huA6-rW%NLJcC<$JcG0<J,~>
+JcC<$huA6-rW%NLJcC<$JcG0<J,~>
+JcC<$huA6-!W[b$JcC<$JcC<$mf.e~>
+JcC<$h#Dp*JcC<$JcC<$mf.e~>
+JcC<$h#Dp*JcC<$JcC<$mf.e~>
+JcC<$h#DqUJcC<$JcC<$mf.e~>
+JcC<$h#Dp*JcC<$JcC<$mf.e~>
+JcC<$h#Dp*JcC<$JcC<$mf.e~>
+JcC<$h#DqUJcC<$JcC<$mf.e~>
+JcC<$JcC<$JcC<$JcEjlJ,~>
+JcC<$JcC<$JcC<$JcEjlJ,~>
+JcC<$JcC<$JcC<$JcEjlJ,~>
+%%EndData
+showpage
+%%Trailer
+end
+%%EOF
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.png
new file mode 100644 (file)
index 0000000..a5b3d70
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/docbook/lttv-context.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/Makefile.am
new file mode 100644 (file)
index 0000000..a2b99fd
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST = c18.html c40.html c67.html index.html lttv-context.png x23.html x33.html x46.html x50.html x72.html x77.html x81.html x84.html
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c18.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c18.html
new file mode 100644 (file)
index 0000000..f8687fe
--- /dev/null
@@ -0,0 +1,149 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Linux Trace Toolkit Viewer Text Module Tutorial</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="NEXT"
+TITLE="A typical module"
+HREF="x23.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="index.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x23.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN18"
+></A
+>Chapter 1. Linux Trace Toolkit Viewer Text Module Tutorial</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN20"
+>1.1. Introduction</A
+></H1
+><P
+>&#13;This chapter explains all the steps that are necessary to create a text module
+in LTTV.
+</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x23.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Linux Trace Toolkit Viewer Developer Guide</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>A typical module</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c40.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c40.html
new file mode 100644 (file)
index 0000000..a21da87
--- /dev/null
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>How to use the Linux Trace Toolkit Viewer's Reading Context</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="The hooks"
+HREF="x33.html"><LINK
+REL="NEXT"
+TITLE="Why an event driven trace reader ?"
+HREF="x46.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x33.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x46.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN40"
+></A
+>Chapter 2. How to use the Linux Trace Toolkit Viewer's Reading Context</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN42"
+>2.1. Introduction</A
+></H1
+><P
+>&#13;This chapter describes how to use the Linux Trace Toolkit reading context, a
+data structure that is given as call data parameter of the modules'callbacks.
+</P
+><P
+>&#13;Linux Trace Toolkit Viewer provides a backend that reads the traces. In combines
+them in tracesets. A trace is an abstaction over many tracefiles, one per CPU.
+LTTV reads the whole trace together, providing the events to modules by calling
+their pre-registered hook lists in a chronological order.
+</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x33.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x46.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The hooks</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Why an event driven trace reader ?</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c67.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/c67.html
new file mode 100644 (file)
index 0000000..656c37e
--- /dev/null
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Linux Trace Toolkit Viewer Graphical Module Tutorial</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Using the reading context"
+HREF="x50.html"><LINK
+REL="NEXT"
+TITLE="The static part of a module"
+HREF="x72.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x50.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x72.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN67"
+></A
+>Chapter 3. Linux Trace Toolkit Viewer Graphical Module Tutorial</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN69"
+>3.1. Introduction</A
+></H1
+><P
+>&#13;As a matter of fact, most of the things said for the text modules still hold for
+the graphical modules. However, the fact that every module must instanciate
+objects (called viewers) more than once changes a little bit the scenario. It is
+then impossible to use static structures : everything must be instanciated at
+run-time, except the structures related to the module itself.
+</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x50.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x72.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Using the reading context</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The static part of a module</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/index.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/index.html
new file mode 100644 (file)
index 0000000..5dfa59c
--- /dev/null
@@ -0,0 +1,250 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Linux Trace Toolkit Viewer Developer Guide</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="NEXT"
+TITLE="Linux Trace Toolkit Viewer Text Module Tutorial"
+HREF="c18.html"><META
+NAME="KEYWORD"
+CONTENT="Linux Trace Toolkit Viewer"><META
+NAME="KEYWORD"
+CONTENT="text"><META
+NAME="KEYWORD"
+CONTENT="module"><META
+NAME="KEYWORD"
+CONTENT="context"></HEAD
+><BODY
+CLASS="book"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="BOOK"
+><A
+NAME="AEN1"
+></A
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="title"
+><A
+NAME="AEN2"
+>Linux Trace Toolkit Viewer Developer Guide</A
+></H1
+><H3
+CLASS="author"
+><A
+NAME="AEN5"
+></A
+>Mathieu Desnoyers</H3
+><DIV
+><DIV
+CLASS="abstract"
+><P
+></P
+><A
+NAME="AEN10"
+></A
+><P
+>&#13;This document describes the basic steps necessary to develop within the 
+<SPAN
+CLASS="application"
+>Linux Trace Toolkit Viewer</SPAN
+> project.
+
+</P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="c18.html"
+>Linux Trace Toolkit Viewer Text Module Tutorial</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="c18.html#AEN20"
+>Introduction</A
+></DT
+><DT
+>1.2. <A
+HREF="x23.html"
+>A typical module</A
+></DT
+><DT
+>1.3. <A
+HREF="x33.html"
+>The hooks</A
+></DT
+></DL
+></DD
+><DT
+>2. <A
+HREF="c40.html"
+>How to use the Linux Trace Toolkit Viewer's Reading Context</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="c40.html#AEN42"
+>Introduction</A
+></DT
+><DT
+>2.2. <A
+HREF="x46.html"
+>Why an event driven trace reader ?</A
+></DT
+><DT
+>2.3. <A
+HREF="x50.html"
+>Using the reading context</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="c67.html"
+>Linux Trace Toolkit Viewer Graphical Module Tutorial</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="c67.html#AEN69"
+>Introduction</A
+></DT
+><DT
+>3.2. <A
+HREF="x72.html"
+>The static part of a module</A
+></DT
+><DT
+>3.3. <A
+HREF="x77.html"
+>The dynamic part of a module : the viewer</A
+></DT
+><DT
+>3.4. <A
+HREF="x81.html"
+>How to request background computation</A
+></DT
+><DT
+>3.5. <A
+HREF="x84.html"
+>How to handle events and use the graphical trace reading service</A
+></DT
+><DD
+><DL
+><DT
+>3.5.1. <A
+HREF="x84.html#AEN87"
+>Module Related API</A
+></DT
+><DT
+>3.5.2. <A
+HREF="x84.html#AEN91"
+>Main Window</A
+></DT
+><DT
+>3.5.3. <A
+HREF="x84.html#AEN97"
+>Viewer Instance Related API</A
+></DT
+><DT
+>3.5.4. <A
+HREF="x84.html#AEN100"
+>Notices from Main Window</A
+></DT
+><DT
+>3.5.5. <A
+HREF="x84.html#AEN123"
+>Reporting Changes to the Main Window</A
+></DT
+><DT
+>3.5.6. <A
+HREF="x84.html#AEN134"
+>Requesting Events to Main Window</A
+></DT
+><DT
+>3.5.7. <A
+HREF="x84.html#AEN152"
+>GTK Events</A
+></DT
+></DL
+></DD
+></DL
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c18.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Linux Trace Toolkit Viewer Text Module Tutorial</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/lttv-context.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/lttv-context.png
new file mode 100644 (file)
index 0000000..a5b3d70
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/lttv-context.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x23.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x23.html
new file mode 100644 (file)
index 0000000..fdbff00
--- /dev/null
@@ -0,0 +1,200 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>A typical module</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Linux Trace Toolkit Viewer Text Module Tutorial"
+HREF="c18.html"><LINK
+REL="PREVIOUS"
+TITLE="Linux Trace Toolkit Viewer Text Module Tutorial"
+HREF="c18.html"><LINK
+REL="NEXT"
+TITLE="The hooks"
+HREF="x33.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c18.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 1. Linux Trace Toolkit Viewer Text Module Tutorial</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x33.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN23"
+>1.2. A typical module</A
+></H1
+><P
+>&#13;A typical module must have a init() and destroy() function. Please refer to
+lttv/modules/text/textDump.c for the detail of these functions.
+</P
+><P
+>&#13;The init() function is called when the library is loaded and destroy()
+inversely. It adds options to the command line by calling "lttv_option_add" from
+option.h
+</P
+><P
+>&#13;The module communicates with the main lttv program through the use of global
+attributes. Use lttv/attribute.h, lttv/iattribute.h and lttv/lttv.h, and then
+LTTV_IATTRIBUTE(lttv_global_attributes()) to get the pointer to these
+global attributes.
+</P
+><P
+>&#13;You can then add your hooks (functions that follows the prototype of a hook, as
+defined in lttv/hook.h) in the different hook lists defined in lttv/lttv.h. Note
+that hooks have an assigned priority. This is necessary to inform the trace
+reader that a specific hook needs to be called, for example, before or after the
+state update done for an event by the state module. For that specific example, a
+hook could use the LTTV_PRIO_STATE-5 to get called before the state update and a
+second hook could use the LTTV_PRIO_STATE+5 to get called after the state
+update. This is especially important for graphical module, which is the subject
+of a the chapter named "Linux Trace Toolkit Viewer Graphical Module Tutorial".
+</P
+><P
+>&#13;You should also take a look at lttv/state.c, where by_id hooks are used. When
+you only need some specific events, you should use this interface. It makes the
+event filtering sooner in the dispatch chain : you hook doesn't have to be
+called for each event, only the ones selected. That improves the performances a
+lot!
+</P
+><P
+>&#13;Note that you should use the lttv_trace_find_hook method from
+lttv/tracecontext.h to connect the hook to the right facility/event type. See
+state.c for an example. A problem that may arise is that the LttvTraceHook
+structure must be passed as hook_data when registering the hook. In fact, it is
+not necessary for it to be directly passed as the hook_data parameter. As long
+as the hook function can access the LttvTraceHook fields necessary to parse the
+LttEvent, there is no problem. In a complex viewer where you need a pointer to
+your own data structure, just keep a pointer to the LttvTraceHook structure
+inside your own data structure, and give to pointer to your data structure in
+parameter as the hook_data.
+</P
+><P
+>&#13;Then, you should use the macro LTTV_MODULE, defined in lttv/module.h. It allows
+you to specify the module name, a short and a long description, the init and
+destroy functions and the module dependencies. That permits to the module
+backend to load the right dependencies when needed.
+</P
+><P
+>&#13;A typical text module will depend on batchAnalysis for the batch computation of a
+trace, and simply register before and after trace hooks, as weel as the most
+important one : a event hook.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c18.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x33.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Linux Trace Toolkit Viewer Text Module Tutorial</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c18.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The hooks</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x33.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x33.html
new file mode 100644 (file)
index 0000000..754136b
--- /dev/null
@@ -0,0 +1,184 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>The hooks</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Linux Trace Toolkit Viewer Text Module Tutorial"
+HREF="c18.html"><LINK
+REL="PREVIOUS"
+TITLE="A typical module"
+HREF="x23.html"><LINK
+REL="NEXT"
+TITLE="How to use the Linux Trace Toolkit Viewer's Reading Context"
+HREF="c40.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x23.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 1. Linux Trace Toolkit Viewer Text Module Tutorial</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c40.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN33"
+>1.3. The hooks</A
+></H1
+><P
+>&#13;The before and after trace hooks only exists to be able to generate a report at
+the end of a trace computation. The effective computation is done by the event
+hooks.
+</P
+><P
+>&#13;These hooks does particular computation on data arriving as argument, a
+call_data. The type of the call_data, when a hook is called during the trace
+read, is a traceset context. It contains all the necessary information about the
+read in progress. This is the base class from which inherits trace set
+state, and trace set/trace/tracefile state is the base classe of trace
+set/trace/tracefile statistics. All these types can be casted to another without
+problem (a TracesetState, for example, can be casted to a TracesetContext, but
+it's not true for the casting between a TraceContext and a TracesetContext, see
+the chapter "How to use the trace reading context" for details). They offer the
+input data and they give a container (the attributes of the trace set/trace/tracefile
+statistics) to write the output of this hook.
+</P
+><P
+>&#13;The idea behind writing in the attributes container is to provide an extensible
+way of storing any type of information. For example, a specific module that adds
+statistics to a trace can store them there, and the statistic printout will
+automatically include the results produced by the specific module.
+</P
+><P
+>&#13;Output data does not necessarily need to be stored in such a global container
+though. If we think of data of which we need to keed track during the execution,
+an event counter for example, we should create our own data structure that
+contains this counter, and pass the address of the allocated structure as the
+hook_data parameter of the hook list creation function. That way, the hook will
+be called with its hook_data as first parameter, which it can read and write. We
+can think of this structure as the data related to the function that persists
+between each call to the hook. You must make sure that you cast the hook_data to
+the type of the structure before you use it in the hook function.
+</P
+><P
+>&#13;The detail about how to access the different fields of the reading context (the
+hook's call_data) will be discussed in the chapter  "How to use the trace
+reading context".
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x23.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c40.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>A typical module</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c18.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>How to use the Linux Trace Toolkit Viewer's Reading Context</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x46.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x46.html
new file mode 100644 (file)
index 0000000..3cd2e69
--- /dev/null
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Why an event driven trace reader ?</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="How to use the Linux Trace Toolkit Viewer's Reading Context"
+HREF="c40.html"><LINK
+REL="PREVIOUS"
+TITLE="How to use the Linux Trace Toolkit Viewer's Reading Context"
+HREF="c40.html"><LINK
+REL="NEXT"
+TITLE="Using the reading context"
+HREF="x50.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c40.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. How to use the Linux Trace Toolkit Viewer's Reading Context</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x50.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN46"
+>2.2. Why an event driven trace reader ?</A
+></H1
+><P
+>&#13;The complexity of synchronizing the tracesets is then hidden to the viewer. Some
+future plans involve to be able to put many traces together in a trace set.
+Before this becomes possible, the time of each trace must be synchronized in
+some way. Some work is actually done to create a module that uses the network
+traffic shared by different computers to synchronize the time of different
+traces.
+</P
+><P
+>&#13;In order to make each module integrate well with each other, we made the trace
+reader a simple hook caller. For each event it reads, it just calls the hook
+lists for this event. For each event, it calls the by_id specific hooks
+registered for this event and also the "main" hooks, registered for all events.
+Note that the two hook lists are merged when called so the priority of the
+hooks of each list is respected. For example, a hook of higher priority (20) in
+the main list will be called before a hook of lower priority (40) from the
+by_id specific list.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c40.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x50.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>How to use the Linux Trace Toolkit Viewer's Reading Context</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c40.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Using the reading context</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x50.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x50.html
new file mode 100644 (file)
index 0000000..f93edb1
--- /dev/null
@@ -0,0 +1,193 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Using the reading context</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="How to use the Linux Trace Toolkit Viewer's Reading Context"
+HREF="c40.html"><LINK
+REL="PREVIOUS"
+TITLE="Why an event driven trace reader ?"
+HREF="x46.html"><LINK
+REL="NEXT"
+TITLE="Linux Trace Toolkit Viewer Graphical Module Tutorial"
+HREF="c67.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x46.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. How to use the Linux Trace Toolkit Viewer's Reading Context</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c67.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN50"
+>2.3. Using the reading context</A
+></H1
+><P
+>&#13;If you have read the tutorials about writing a text and a graphic module, you
+should be fairly ready to use the information provided to your hook by the
+reading API.
+</P
+><P
+>&#13;The data structures of the reading context are based on the gobject, a
+object-oriented library from the glib. Some evolved types that are found in the
+context also comes from the "glib" (GArray, GHashTable and so on). For detailed
+information about "gobjects" and the "glib", see the <A
+HREF="http://www.gtk.org"
+TARGET="_top"
+>www.gtk.org</A
+> website. They provide a complete
+API reference about the data types they provide.
+</P
+><P
+>&#13;The reading context is object oriented. It is described by the lttv/tracecontext.h
+header. Is can be illustrated with this UML class diagram :
+</P
+><P
+>&#13;<DIV
+CLASS="mediaobject"
+><P
+><IMG
+SRC="lttv-context.png"
+ALIGN="center"><DIV
+CLASS="caption"
+><P
+>Linux Trace Toolkit Viewer Reading Context Class Diagram</P
+></DIV
+></P
+></DIV
+>
+</P
+><P
+>&#13;Though, for performance's sake, navigating through it is not as encapsulated as
+it could. Consider the class attributes to be all public (no get/set functions).
+Sometimes, iteration upon a specific element can be uneasy. For example, you may
+have to get the number of tracefiles in a trace from the "vt" field of the trace
+context to be able to iterate over all the tracefiles contained by the trace.
+</P
+><P
+>&#13;To facilitate the common operations on the reading context, LTTV now provides a
+header that consists of simple macros : lttv/contextmacros.h. It gives an object
+look-and-feel to the context classes. Simple "GET" macros can be used to easily
+access the different fields are iterate over the elements (and get the total
+number of elements too).
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x46.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c67.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Why an event driven trace reader ?</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c40.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Linux Trace Toolkit Viewer Graphical Module Tutorial</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x72.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x72.html
new file mode 100644 (file)
index 0000000..bbb21cb
--- /dev/null
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>The static part of a module</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Linux Trace Toolkit Viewer Graphical Module Tutorial"
+HREF="c67.html"><LINK
+REL="PREVIOUS"
+TITLE="Linux Trace Toolkit Viewer Graphical Module Tutorial"
+HREF="c67.html"><LINK
+REL="NEXT"
+TITLE="The dynamic part of a module : the viewer"
+HREF="x77.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c67.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. Linux Trace Toolkit Viewer Graphical Module Tutorial</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x77.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN72"
+>3.2. The static part of a module</A
+></H1
+><P
+>&#13;A module must have a static part to be able to get loaded just like a text
+module. Now, let's see the differences. The graphical module depends on the
+"lttvwindow" module. See module.c from the control flow viewer for an example.
+</P
+><P
+>&#13;The init() and destroy() functions must register functions that can be called by
+user interaction to instanciate the viewers. That's the goal of
+lttvwindow_register_constructor() and lttvwindow_unregister_constructor() :
+they register a function with a menu entry and an icon. The main window will
+shown them in its interface and call the function when the button or menu item
+is selected. This hook function must receive a pointer to a "Tab" object in
+parameter.
+</P
+><P
+>&#13;Also note the presence of the destroy_walk() method. It is called when the
+module is unloaded : it must destroy all the instances of the viewers from the
+module.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c67.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x77.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Linux Trace Toolkit Viewer Graphical Module Tutorial</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c67.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The dynamic part of a module : the viewer</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x77.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x77.html
new file mode 100644 (file)
index 0000000..30827a5
--- /dev/null
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>The dynamic part of a module : the viewer</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Linux Trace Toolkit Viewer Graphical Module Tutorial"
+HREF="c67.html"><LINK
+REL="PREVIOUS"
+TITLE="The static part of a module"
+HREF="x72.html"><LINK
+REL="NEXT"
+TITLE="How to request background computation"
+HREF="x81.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x72.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. Linux Trace Toolkit Viewer Graphical Module Tutorial</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x81.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN77"
+>3.3. The dynamic part of a module : the viewer</A
+></H1
+><P
+>&#13;The dynamic part starts with the constructor of the viewer. It is called by the
+main window when the corresponding button or menu item is selected. See
+h_guicontrolflow() from control flow viewer eventhooks.c for an example. It does
+basic connexion to the tab's events available : time window change notification,
+current time notification, redraw notification, continue notification. All these
+function should be implemented in your viewer if you want the data you shown to
+be synchronised with the main window and the other viewers. It also calls the
+background computation, which will be discussed in the next section.
+</P
+><P
+>&#13;This is also at this point that the viewer does create it's own memory footprint
+: its inner structure. This structure will have to be passed as hook_data to
+each function registered by the viewer : this is what makes the functions
+"belong" to this instance of the viewer.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x72.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x81.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The static part of a module</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c67.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>How to request background computation</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x81.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x81.html
new file mode 100644 (file)
index 0000000..c12a65b
--- /dev/null
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>How to request background computation</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Linux Trace Toolkit Viewer Graphical Module Tutorial"
+HREF="c67.html"><LINK
+REL="PREVIOUS"
+TITLE="The dynamic part of a module : the viewer"
+HREF="x77.html"><LINK
+REL="NEXT"
+TITLE="How to handle events and use the graphical trace reading service"
+HREF="x84.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x77.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. Linux Trace Toolkit Viewer Graphical Module Tutorial</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x84.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN81"
+>3.4. How to request background computation</A
+></H1
+><P
+>&#13;You will also notice the presence of a request_background_data() called in the
+constructor. This function, in eventhooks.c, does verify for the presence of the
+state information that could be precomputed by the main window background
+computation. If it has not been precomputed, we ask for a computation and show
+partial data. We also register a hook that will be called (notified) by the main
+window when the requested data will become ready, so the viewer can update
+itself with the new data. If no partial information would have made sense in a
+particular viewer, one could choose to shown a "waiting for computation" message
+while waiting for the notification. See lttvwindow/lttvwindowtraces.h for the API
+of the background requests.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x77.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x84.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The dynamic part of a module : the viewer</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c67.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>How to handle events and use the graphical trace reading service</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x84.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/developer_guide/html/x84.html
new file mode 100644 (file)
index 0000000..639350a
--- /dev/null
@@ -0,0 +1,537 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>How to handle events and use the graphical trace reading service</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer Developer Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Linux Trace Toolkit Viewer Graphical Module Tutorial"
+HREF="c67.html"><LINK
+REL="PREVIOUS"
+TITLE="How to request background computation"
+HREF="x81.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer Developer Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x81.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. Linux Trace Toolkit Viewer Graphical Module Tutorial</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="AEN84"
+>3.5. How to handle events and use the graphical trace reading service</A
+></H1
+><P
+>&#13;The events that are delivered by the main window are defined in
+lttvwindow/lttvwindow.h. Let's describe them and their use in details. Remember
+that you can refer to the control flow viewer module as an example.
+</P
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN87"
+>3.5.1. Module Related API</A
+></H2
+><P
+>&#13;A viewer plugin is, before anything, a plugin. As a dynamically loadable
+module, it thus has an init and a destroy function called whenever it is
+loaded/initialized and unloaded/destroyed. A graphical module depends on
+lttvwindow for construction of its viewer instances. In order to achieve
+this, it must register its constructor function to the main window along
+with button description or text menu entry description. A module keeps
+a list of every viewer that currently sits in memory so it can destroy
+them before the module gets unloaded/destroyed.
+</P
+><P
+>&#13;The contructor registration to the main windows adds button and menu
+entry to each main window, thus allowing instanciation of viewers.
+</P
+></DIV
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN91"
+>3.5.2. Main Window</A
+></H2
+><P
+>&#13;The main window is a container that offers menus, buttons and a
+notebook. Some of those menus and buttons are part of the core of the
+main window, others are dynamically added and removed when modules are
+loaded/unloaded.
+</P
+><P
+>&#13;The notebook contains as much tabs as wanted. Each tab is linked with
+a set of traces (traceset). Each trace contains many tracefiles (one
+per cpu).  A trace corresponds to a kernel being traced. A traceset
+corresponds to many traces read together. The time span of a traceset
+goes from the earliest start of all the traces to the latest end of all
+the traces.
+</P
+><P
+>&#13;Inside each tab are added the viewers. When they interact with the main
+window through the lttvwindow API, they affect the other viewers located
+in the same tab as they are.
+</P
+><P
+>&#13;The insertion of many viewers in a tab permits a quick look at all the
+information wanted in a glance. The main window does merge the read
+requests from all the viewers in the same tab in a way that every viewer
+will get exactly the events it asked for, while the event reading loop
+and state update are shared. It improves performance of events delivery
+to the viewers.
+</P
+></DIV
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN97"
+>3.5.3. Viewer Instance Related API</A
+></H2
+><P
+>&#13;The lifetime of a viewer is as follows. The viewer constructor function
+is called each time an instance view is created (one subwindow of this
+viewer type is created by the user either by clicking on the menu item
+or the button corresponding to the viewer). Thereafter, the viewer gets
+hooks called for different purposes by the window containing it. These
+hooks are detailed below. It also has to deal with GTK Events. Finally,
+it can be destructed by having its top level widget unreferenced by the
+main window or by any GTK Event causing a "destroy-event" signal on the
+its top widget. Another possible way for it do be destroyed is if the
+module gets unloaded. The module unload function will have to emit a
+"destroy" signal on each top level widget of all instances of its viewers.
+</P
+></DIV
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN100"
+>3.5.4. Notices from Main Window</A
+></H2
+><P
+></P
+><DIV
+CLASS="variablelist"
+><DL
+><DT
+>time_window</DT
+><DD
+><P
+>This is the time interval visible on the viewer's tab. Every
+              viewer that cares about being synchronised by respect to the
+              time with other viewers should register to this notification.
+              They should redraw all or part of their display when this
+              occurs.</P
+></DD
+><DT
+>traceset</DT
+><DD
+><P
+>This notification is called whenever a trace is added/removed
+              from the traceset. As it affects all the data displayed by the
+              viewer, it sould redraw itself totally.</P
+></DD
+><DT
+>filter</DT
+><DD
+><P
+>This feature has not been implemented yet.</P
+></DD
+><DT
+>current_time</DT
+><DD
+><P
+>Being able to zoom nearer a specific time or highlight a specific
+              time on every viewer in synchronicity implies that the viewer
+              has to shown a visual sign over the drawing or select an event
+              when it receives this notice. It should also inform the main
+              window with the appropriate report API function when a user
+              selects a specific time as being the current time.</P
+></DD
+><DT
+>dividor</DT
+><DD
+><P
+>This notice links the positions of the horizontal dividors
+              between the graphic display zone of every viewer and their Y axis,
+              typically showing processes, cpus, ...</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN123"
+>3.5.5. Reporting Changes to the Main Window</A
+></H2
+><P
+>&#13;In most cases, the enclosing window knows about updates such as described
+in the Notification section higher. There are a few cases, however, where
+updates are caused by actions known by a view instance. For example,
+clicking in a view may update the current time; all viewers within
+the same window must be told about the new current time to change the
+currently highlighted time point. A viewer reports such events by calling
+lttvwindow_report_current_time on its lttvwindow.  The lttvwindow will
+consequently call current_time_notify for each of its contained viewers.
+</P
+><P
+>&#13;Available report methods are :
+<P
+></P
+><UL
+><LI
+><P
+>&#13;lttvwindow_report_time_window : reports the new time window.
+</P
+></LI
+><LI
+><P
+>&#13;lttvwindow_report_current_time : reports the new current time.
+</P
+></LI
+><LI
+><P
+>&#13;lttvwindow_report_dividor : reports the new horizontal dividor's position.
+</P
+></LI
+></UL
+>
+</P
+></DIV
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN134"
+>3.5.6. Requesting Events to Main Window</A
+></H2
+><P
+>&#13;Events can be requested by passing a EventsRequest structure to the main
+window.  They will be delivered later when the next g_idle functions
+will be called.  Event delivery is done by calling the event hook for
+this event ID, or the main event hooks. A pointer to the EventsRequest
+structure is passed as hook_data to the event hooks of the viewers.
+</P
+><P
+>&#13;EventsRequest consists in 
+<P
+></P
+><UL
+><LI
+><P
+>&#13;a pointer to the viewer specific data structure
+</P
+></LI
+><LI
+><P
+>&#13;a start timestamp or position
+</P
+></LI
+><LI
+><P
+>&#13;a stop_flag, ending the read process when set to TRUE
+</P
+></LI
+><LI
+><P
+>&#13;a end timestamp and/or position and/or number of events to read
+</P
+></LI
+><LI
+><P
+>&#13;hook lists to call for traceset/trace/tracefile begin and end, and for each
+  event (event hooks and event_by_id hooks).
+</P
+></LI
+></UL
+>
+</P
+><P
+>&#13;The main window will deliver events for every EventRequests it has
+pending through an algorithm that guarantee that all events requested,
+and only them, will be delivered to the viewer between the call of the
+tracefile_begin hooks and the call of the tracefile_end hooks.
+</P
+><P
+>&#13;If a viewer wants to stop the event request at a certain point inside the
+event hooks, it has to set the stop_flag to TRUE and return TRUE from the
+hook function. Then return value will stop the process traceset. Then,
+the main window will look for the stop_flag and remove the EventRequests
+from its lists, calling the process_traceset_end for this request (it
+removes hooks from the context and calls the after hooks).
+</P
+><P
+>&#13;It no stop_flag is risen, the end timestamp, end position or number
+of events to read has to be reached to determine the end of the
+request. Otherwise, the end of traceset does determine it.
+</P
+></DIV
+><DIV
+CLASS="sect2"
+><H2
+CLASS="sect2"
+><A
+NAME="AEN152"
+>3.5.7. GTK Events</A
+></H2
+><DIV
+CLASS="sect3"
+><H3
+CLASS="sect3"
+><A
+NAME="AEN154"
+>3.5.7.1. Events and Signals</A
+></H3
+><P
+>&#13;GTK is quite different from the other graphical toolkits around
+there. The main difference resides in that there are many X Windows
+inside one GtkWindow, instead of just one. That means that X events are
+delivered by the glib main loop directly to the widget corresponding to
+the GdkWindow affected by the X event.
+</P
+><P
+>&#13;Event delivery to a widget emits a signal on that widget. Then, if a
+handler is connected to this widget's signal, it will be executed. There
+are default handlers for signals, connected at class instantiation
+time. There is also the possibility to connect other handlers to these
+signals, which is what should be done in most cases when a viewer needs
+to interact with X in any way.
+</P
+><P
+>&#13;Signal emission and propagation is described there : 
+
+<P
+></P
+><UL
+><LI
+><P
+>&#13;http://www.gtk.org/tutorial/sec-signalemissionandpropagation.html
+</P
+></LI
+></UL
+>
+</P
+><P
+>&#13;For further information on the GTK main loop (now a wrapper over glib main loop)
+see :
+
+<P
+></P
+><UL
+><LI
+><P
+>&#13;http://developer.gnome.org/doc/API/2.0/gtk/gtk-General.html
+</P
+></LI
+><LI
+><P
+>&#13;http://developer.gnome.org/doc/API/2.0/glib/glib-The-Main-Event-Loop.html
+</P
+></LI
+></UL
+>
+</P
+><P
+>&#13;For documentation on event handling in GTK/GDK, see :
+
+<P
+></P
+><UL
+><LI
+><P
+>&#13;http://developer.gnome.org/doc/API/2.0/gdk/gdk-Events.html
+</P
+></LI
+><LI
+><P
+>&#13;http://developer.gnome.org/doc/API/2.0/gdk/gdk-Event-Structures.html
+</P
+></LI
+></UL
+>
+</P
+><P
+>&#13;Signals can be connected to handlers, emitted, propagated, blocked, 
+stopped. See :
+
+<P
+></P
+><UL
+><LI
+><P
+>&#13;http://developer.gnome.org/doc/API/2.0/gobject/gobject-Signals.html
+</P
+></LI
+></UL
+>
+</P
+></DIV
+><DIV
+CLASS="sect3"
+><H3
+CLASS="sect3"
+><A
+NAME="AEN178"
+>3.5.7.2. The "expose_event"</A
+></H3
+><P
+>&#13;Provides the exposed region in the GdkEventExpose structure. 
+</P
+><P
+>&#13;There are two ways of dealing with exposures. The first one is to directly
+draw on the screen and the second one is to draw in a pixmap buffer,
+and then to update the screen when necessary.
+</P
+><P
+>&#13;In the first case, the expose event will be responsible for registering
+hooks to process_traceset and require time intervals to the main
+window. So, in this scenario, if a part of the screen is damaged, the
+trace has to be read to redraw the screen.
+</P
+><P
+>&#13;In the second case, with a pixmap buffer, the expose handler is only
+responsible of showing the pixmap buffer on the screen. If the pixmap
+buffer has never been filled with a drawing, the expose handler may ask
+for it to be filled.
+</P
+><P
+>&#13;The interest of using events request to the main window instead of reading
+the events directly from the trace comes from the fact that the main
+window does merge requests from the different viewers in the same tab so
+that the read loop and the state update is shared. As viewers will, in
+the common scenario, request the same events, only one pass through the
+trace that will call the right hooks for the right intervals will be done.
+</P
+><P
+>&#13;When the traceset read is over for a events request, the traceset_end
+hook is called. It has the responsibility of finishing the drawing if
+some parts still need to be drawn and to show it on the screen (if the
+viewer uses a pixmap buffer).
+</P
+><P
+>&#13;It can add dotted lines and such visual effects to enhance the user's
+experience.
+</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x81.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>How to request background computation</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c67.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/discuss.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/discuss.html
new file mode 100644 (file)
index 0000000..b615925
--- /dev/null
@@ -0,0 +1,189 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Tracing Tools</title>
+</head>
+  <body>
+
+<h1>Tracing Tools</h1>
+
+<p>Tracing is routinely used to help understanding the behavior and performance
+of various aspects of the Linux kernel and associated drivers. 
+Many of the 80K+ printk statements in the Linux kernel 
+serve this purpose, although printk is relatively low
+performance and unreliable. The small default printk buffer size coupled with
+the low performance brings lost messages as soon as the volume becomes
+significant.
+
+<p>For this reason, a number of drivers include their own tracing macros
+and infrastructure. A quick search looking for TRACE and related keywords
+in the Linux kernel source reveals some form of tracing in at least 
+the following files:
+
+<UL>
+<LI>./fs/hpfs/hpfs_fn.h
+<LI>./fs/smbfs/smb_debug.h
+<LI>./fs/autofs/autofs_i.h
+<LI>./fs/jffs2/nodelist.h
+<LI>./include/linux/wait.h
+<LI>./include/linux/parport_pc.h
+<LI>./include/linux/amigaffs.h
+<LI>./include/linux/parport_pc.h
+<LI>./include/linux/ncp_fs.h
+<LI>drivers/net/wireless airport and orinoco
+<LI>drivers/char/ftape
+<LI>drivers/char/dtlk.c
+<LI>drivers/char/mwave
+<LI>drivers/char/n_r3964.c
+<LI>drivers/scsi/qlogicfc.c
+<LI>drivers/usb/pwc-if.c
+<LI>drivers/usb/hpusbscsi.c
+<LI>drivers/acpi/include/acmacros.h
+<LI>arch/sparc/kernel/signal.c
+<LI>arch/mips/math-emu/cp1emu.c
+<LI>drivers/net/wavelan.c
+<LI>drivers/net/hp100.c
+<LI>drivers/net/wan/lmc/lmc_debug.c
+<LI>drivers/net/skfp/h/targetos.h
+<LI>drivers/char/ip2main.c
+<LI>drivers/scsi/gdth.c
+<LI>drivers/scsi/megaraid.c
+<LI>drivers/scsi/qlogicisp.c
+<LI>drivers/scsi/ips.c
+<LI>drivers/scsi/qla1280.c
+<LI>drivers/scsi/cpqfcTSstructs.h
+<LI>drivers/cdrom/sjcd.c
+<LI>drivers/isdn/eicon/sys.h
+<LI>drivers/sbus/char/bbc_envctrl.c
+<LI>drivers/ide/ide-tape.c
+<LI>drivers/video/radeonfb.c
+<LI>fs/intermezzo/sysctl.c
+<LI>fs/ext3/balloc.c
+<LI>net/ipv6/ip6_fib.c
+<LI>net/irda/irnet/irnet.h
+<UL>
+
+<p>A number of tracing tools have been developed for the Linux kernel.
+The best known, particularly in the embedded systems area, is the Linux Trace
+Toolkit, <A HREF="http://www.opersys.com/LTT">LTT at 
+http://www.opersys.com/LTT</A>. It
+comes with a nice graphical user interface and is currently under active
+development to add dynamically defined event types and graphical trace
+analysis modules.
+
+<P>
+The <A HREF="http://lkst.sf.net">Linux Kernel State Tracer at
+http://lkst.sf.net</A>was developed by Hitachi and offers basic,
+low overhead, tracing functionality. There is no grahical user interface
+available.
+
+<P>
+MAGNET was recently released. It was initially developed to trace the network
+stack and drivers. Its performance has not been optimized for SMP systems.
+It is available from 
+<A HREF="http://public.lanl.gov/radiant/software/magnet.html">
+http://public.lanl.gov/radiant/software/magnet.html
+</A>. 
+
+<P>
+The IKD patch from Andrea Arcangeli 
+<A HREF="ftp://ftp.kernel.org/pub/linux/kernel/people/andrea/ikd/">
+ftp://ftp.kernel.org/pub/linux/kernel/people/andrea/ikd/
+</A>
+includes ktrace which adds the -pg gcc compilation option 
+to specified source files. This adds a call to function <i>mcount</i> 
+upon entry in any function compiled with that option. A function <i>mcount</i>
+is provided which records in a trace the address of the function entered.
+Using the system map, this is later translated into a trace of names of
+functions entered.
+
+<H2>Reliability, Availability and Serviceability</H2>
+
+<P>
+Tracing may be placed in the larger context of Reliability, Availability and
+Serviceability (RAS). The Linux RAS project is probably the most active and
+well organized,
+<A HREF="http://systemras.sourceforge.net/">
+http://systemras.sourceforge.net/
+</A>
+<A HREF="http://www-124.ibm.com/linux/projects/linuxras/">
+http://www-124.ibm.com/linux/projects/linuxras/
+</A>.
+It links to several underlying projects, including the Linux Trace Toolkit
+<A HREF="http://www.opersys.com/LTT">LTT</A>.
+
+<P>
+Several other projects within Linux RAS directly relate to tracing.
+
+<H3>Enterprise Event Logging</H3>
+
+<p>The Enterprise Event Logging project,
+<A HREF="http://evlog.sourceforge.net/">EVLOG project
+at http://evlog.sourceforge.net/</A>, produces traces and thus shares a number
+of underlying implementation needs 
+(events recording, kernel to user mode transfer,
+trace analysis and viewing tools, event types format). The intended purpose
+and thus implementation constraints differ significantly, however. 
+EVLOG records important system events for two purposes,
+to trigger service and security alarms (e.g. weak signals in a magnetic disk,
+unauthorized access attempt) and to provide permament records. The volume
+is typically low and full context is required for each event. While logging
+(EVLOG) is therefore implemented separately from tracing (LTT), some
+underlying technology may be reused as appropriate (e.g. kernel hooks,
+kernel to user mode data relay...).
+
+<H3>Kernel Crash Dump</H3>
+
+<P>A common symptom of a serious kernel problem is a crash. Traces may
+be extremely useful to understand the problem except that, because of the
+crash, the important last events in the current trace buffer cannot be 
+stored on disk. The Linux Kernel Crash Dump facility (LKCD) at
+<A HREF="http://oss.software.ibm.com/developer/opensource/linux/projects/flexdump/">
+http://oss.software.ibm.com/developer/opensource/linux/projects/flexdump/
+</A> is used to recover such information, when <i>warm</i> rebooting from a
+crash while this information is still available in memory.
+
+<P>LKCD needs to be told how to find the tracing buffers in the memory
+(address in a map or signature to look for) and in which file to save
+their content.
+
+<H3>Kernel Hooks</H3>
+
+<p>
+Kernel hooks, at
+<A HREF="http://www-124.ibm.com/developerworks/oss/linux/projects/kernelhooks/">
+http://www-124.ibm.com/developerworks/oss/linux/projects/kernelhooks/
+</A> are a mechanism to insert hooks at desired locations in the kernel.
+Handlers may later be registered to be called at these hooks locations.
+When no handler is registered, the cost associated with a hook is almost
+negligeable, a few NOPs. Skipping NOPs is even faster than testing a 
+global boolean variable. Kernel hooks would be ideally suited for the
+dynamic activation of trace points. Furthermore, kernel hooks allow registering
+multiple handlers. A same location could have a tracing handler and a
+performance tool handler, reducing the number of points needed to be 
+inserted in the kernel source code.
+
+<p>Interactive tools may be used to rapidly select groups of hooks to be
+activated based on facilities (networking, block devices...), level
+of details (core events, detailed events) or severity level (warning, info,
+debug).
+
+<p>As part of Kernel Hooks and Dynamic Probes, were defined handlers
+which produce tracing information. The tracing data models for Dynamic Probes 
+and LTT are fairly similar and may eventually be consolidated.
+
+<H3>Dynamic Probes</H3>
+
+<p>The Dynamic Probes,
+<A HREF="http://www-124.ibm.com/linux/projects/kprobes/">
+http://www-124.ibm.com/linux/projects/kprobes/
+</A>,
+allow inserting kernel hooks dynamically in a running kernel, just like
+breakpoints in debuggers. The instruction
+at the desired location is saved and replaced by an interrupt instruction.
+When the interrupt instruction is executed, the handlers are called, the
+original instruction restored and executed in single step mode, and the
+interrupt instruction is reinserted.
+
+</body>
+</html>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/filter_specification.docbook b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/filter_specification.docbook
new file mode 100644 (file)
index 0000000..9de15a0
--- /dev/null
@@ -0,0 +1,502 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+                      "/usr/share/sgml/docbook/dtd/4.3/xdocbook.dtd">
+<!--<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" >-->
+
+<book>
+
+<bookinfo>
+<title>Spécifications du filtre de Linux Trace Toolkit Viewer</title>
+<authorgroup>
+<author>
+<firstname>Mathieu</firstname>
+<surname>Desnoyers</surname>
+</author>
+</authorgroup>
+
+<date>26/01/2005</date>
+<releaseinfo>1.00.00</releaseinfo>
+
+<abstract>
+<para>
+Ce document décrit les spécifications requises pour la fonctionnalité de
+filtrage pour l'application 
+<application>Linux Trace Toolkit Viewer</application>.
+
+</para>
+</abstract>
+
+<keywordset>
+<keyword>Linux Trace Toolkit Viewer</keyword>
+<keyword>spécification</keyword>
+<keyword>filtre</keyword>
+<keyword>specification</keyword>
+<keyword>filter</keyword>
+</keywordset>
+
+</bookinfo>
+<chapter>
+<title>Introduction</title>
+
+<para>
+Le filtre de Linux Trace Toolkit Viewer est une fonctionnalité nécessaire pour
+rendre l'outil pleinement utilisable. Des cas typiques de filtrage ont déjà Ã©té
+identifiés : filtrer par CPU ou par ID d'événement.
+</para>
+<para>
+Cependant, un utilisateur plus avancé peut vouloir filtrer selon n'importe quel
+champs d'information disponible lors de la lecture d'un Ã©vénement. L'approche
+qui sera suivie, afin d'assurer l'applicabilité du filtrage aux différents types
+de traces, sera de ne pas limiter les champs selon lesquels le filtrage pourra
+être fait.
+</para>
+<para>
+Comme le filtrage se fait Ã  la lecture de chaque Ã©vénement, il peut rapidement
+devenir un goulot d'étranglement important. Les performances doivent donc Ãªtre
+un souci de taille lors de la réalisation de cette fonctionnalité. C'est
+pourquoi l'architecture proposée se base sur une compilation des règles de
+filtrage lors de leur définition afin de générer une structure de données
+optimale pour le parcours de la trace.
+</para>
+<para>
+Ce document explique les différents défis Ã  surmonter dans les différents
+sous-modules du filtre, soit : la partie "core" du filtre, qui sera intégrée,
+comme son nom l'indique, au coeur de l'application ainsi que les parties
+modulaires textes et graphiques. Ã€ la fin du document, des optimisations
+éventuelles sont Ã©noncées, sans plus. Elles pourront Ãªtre utiles dans le cas où
+les performances s'avéreraient problématiques.
+</para>
+<para>
+Ce document est le fruit d'un Ã©change entre Michel Dagenais et moi-même, Mathieu
+Desnoyers. Certains passages sont laissés sous leur forme originale.
+</para>
+
+</chapter>
+
+
+<chapter>
+<title>Design</title>
+
+<sect1>
+<title>Core</title>
+
+<para>
+     Application des règles de filtrage aux Ã©vénements. Les règles de
+     filtrage pourraient Ãªtre représentées par un arbre. Cette section du
+     filtrage est assez intégrée au reste de l'application pour mériter d'être
+     au coeur même de lttv (pas dans un module séparé). Les feuilles de l'arbre
+     sont des 3-tuples (champs, relation, valeur), alors que les noeuds
+     intermédiaires sont des relations logiques (and, or, xor, not). Le and, le
+     or et le xor sont limités Ã  deux enfants, alors que le not est limité Ã  un
+     seul enfant.
+</para>
+<para>
+     Les champs du 3-tuple devraient respecter une arborescence qui représente
+     l'organisation des données dans les Ã©vénements. Celles-ci sont, lors de la
+     lecture de la trace, accessibles via les structures :
+</para>
+<itemizedlist>
+<listitem><para>LttEvent (plus les champs spécifiques Ã  l'événement)</para></listitem>
+<listitem><para>LttvTracefile</para></listitem>
+<listitem><para>LttvTrace</para></listitem>
+<listitem><para>LttvTraceset</para></listitem>
+<listitem><para>LttvState</para></listitem>
+</itemizedlist>
+<para>
+     On pourrait donc, au niveau de la description du champs, représenter
+     celui-ci par une chaîne de caractères imbriquable dont les niveaux sont
+     séparés par le ".". Voici la représentation des niveaux d'imbrication :
+</para>
+<para>
+<literallayout class="monospaced">
+     *
+     |->event (pour accéder aux champs sous LttEvent)
+     |  |->name (string)
+     |  |->category (string)
+     |  |->time (LttTime)
+     |  |->tsc (LttCycleCount)
+     |  |->fields
+     |     |->"event name"
+     |        |->"field name"
+     |           |->"sub-field name"
+     |              |->...
+     |                 |->"leaf-field name" (field type)
+     |
+     |->tracefile
+     |  |->name (string)
+     |->trace
+     |  |->name (string)
+     |->state
+        |->pid (guint)
+        |->ppid (guint)
+        |->creation_time (LttTime)
+        |->insertion_time (LttTime)
+        |->process_name (string)
+        |->execution_mode (user_mode, syscall, trap, irq, unknown)
+        |->execution_submode (none, unknown)
+        |->process_status (wait_fork,wait_cpu,exit,zombie,wait,run,unnamed)
+        |->cpu (guint)
+</literallayout>
+</para>
+
+<para>
+L'objet contenant l'arbre des règles de filtrage ainsi que la cache du filtre,
+  qu'on pourrait appeler "LttvFilter", serait associé Ã  une trace, non pas Ã  un
+  trace set, pour des raisons de performance. En effet, le même nom d'événement
+  peut très bien Ãªtre associé Ã  un ID différent d'une trace Ã  l'autre. Comme on
+  ne souhaite pas faire la translation nom->id (qui est coûteuse) Ã  chaque
+  utilisation du filtre, on le ferait lors de sa construction. Ceci implique de
+  garder un objet LttvFilter par trace. Rien n'empêche cependant d'avoir une
+  façon de créer, au niveau usager, des filtres pour toutes les traces d'un
+  traceset, mais ceux-ci seront associés Ã  chaque trace du trace set.
+</para>
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Je m`inquiète beaucoup pour la performance. Il faut pouvoir précompiler
+ces expressions en offset (ltt_field) et avoir un espèce d`index pour ne
+pas passer séquentiellement Ã  travers toutes les règles et pour chaque
+règle interpréter les noms de champs Ã  chaque Ã©vénement traité!!
+</para>
+
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+C'est ce que j'avais en tête : fixer les positions des champs au moment de la
+création de la règle de filtrage, quitte Ã  la recalculer si jamais la trace
+change en cours de route (mais Ã§a ne devrait pas arriver, puisque les paires
+(facility, event id) sont uniques au cours d'une trace).
+</para>
+
+<para>
+Cependant, de la manière dont je vois Ã§a, on aura pas le choix de se garder un
+arbre représentant l'expression logique et de le parcourir séquentiellement pour
+chaque Ã©vénement. On peut Ã©videmment Ã©viter de balayer certaines branches en se
+basant sur les relations and, or, xor lors du parcours.
+</para>
+
+<para>
+Donc, je vois Ã§a, dans le pire cas, comme un parcours infixe de l'arbre
+représentant les règles. Chaque feuille serait une règle représentée par un
+3-tuple (position, (type, relation), valeur), où chaque paire de (type,relation)
+devrait Ãªtre défini pour chaque type (possiblement incorrect, comme la relation
+< sur un type string). Lors de la compilation, on passerait du 3-tuple (champs,
+relation, valeur) Ã  un 3-tuple (position, (type, relation), valeur).
+</para>
+
+<para>
+À noter : un simple offset n'est en réalité pas assez pour représenter la
+position, puisque toutes les données ne résident pas dans une seule structure.
+Certaines sont dans le contexte (TracesetContext), d'autres dans la structure de
+l'événement. Il faut donc décrire la position, en réalité, comme une paire
+(structure, offset), où nous limitons structure aux noms de structure connus
+(qui peuvent Ãªtre encodés sur la forme de GQuarks) : {LTTV_TRACE,
+LTTV_TRACEFILE, LTTV_TRACE_STATE, LTT_EVENT}.
+</para>
+
+<para>
+Lors de la compilation, on a, en entrée, le tuple :
+</para>
+
+<para>
+(champs, relation, valeur)
+</para>
+
+<para>
+où champs est un tuple : (structure, offset, type)
+</para>
+
+<para>
+On produit, en sortie, (toujours dans la même structure en arbre pour les
+expressions logiques), les 3-tuples suivants (aux feuilles) :
+</para>
+
+<para>
+(position, fonction, valeur)
+</para>
+
+<para>
+où :
+<simplelist type="inline">
+<member>position = (structure, offset)</member>
+<member>fonction = (type, relation)</member>
+</simplelist>
+</para>
+
+<para>
+Il me reste une question : que fait-on lors qu'un facility est rechargé en cours
+de traçage ? Les Ã©vénements vont-ils changer d'id ?
+</para>
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Non, c`est un nouveau facility avec le même nom mais un fingerprint
+différent qui s`ajoute puisqu`il est possible que des modules utilisent
+l`ancienne version alors que d`autres utilisent la nouvelle
+simultanément. Il est possible que les règles ne spécifient que le nom
+de la facilité auquel cas elles pourraient s`appliquer Ã  toutes les
+facilités du même nom et demanderaient d`avoir une précompilation
+différente pour chaque facilité.
+</para>
+
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+J'en conclue que le 2-tuple (facility, event id) est unique pour la trace, c'est
+ça ?
+</para>
+<para>
+Michel Dagenais :
+</para>
+<para>
+> Oui.
+</para>
+
+</sect1>
+
+<sect1>
+<title>Module texte</title>
+
+<para>
+Lecture d'une chaîne de caractères formée d'expressions
+booléennes qui décrivent le filtre Ã  partir des opérations de base :
+and, or, xor, not
+et de parenthèses : ( et ).
+Les entrées logiques de ce filtre sont composées 3-tuples
+(champs, relation, valeur),
+où le champs est le type d'information (i.e. pid)
+la relation est la limite sur la valeur (i.e. <)
+la valeur est la valeur qui doit Ãªtre respectée par le champs selon la
+relation. Doit Ãªtre du type associé au champs. Ã€ priori, on utilise
+le type de champs pour savoir sous quel type encoder l'information
+lue, tout en vérifiant le contenu de la chaîne lue pour des
+débordements (overflow) avant encodage vers le type associé.
+La lecture de cette expression booléenne formerait un arbre de règles de
+filtrage, qui serait ensuite utilisé par la partie "core" de filtrage de
+lttv pour Ãªtre appliqué aux Ã©vénements lors de la lecture de trace.
+</para>
+
+</sect1>
+
+<sect1>
+<title>Module graphique</title>
+
+<para>
+Une classe filtre graphique serait associée Ã  un arbre
+de règles de filtrage. On pourrait le modifier les objets de la classe
+filtre graphique en invoquant une fenêtre de modification de filtre qui
+permettrait d'entrer les spécifications du filtre Ã  l'aide de champs
+graphiques de sélection (drop down list) pour les types d'éléments selon
+lesquels filtrer, et d'un champs d'entrée de texte libre pour spécifier la
+valeur que ce champs doit prendre. La relation qui doit Ãªtre appliquée
+(<, >, <=, >=, =) doit Ãªtre sélectionnée dans un autre drop-down list.
+En plus de la sélection graphique, l'entrée d'une chaîne de caractère serait
+possible pour spécifier le filtre selon l'entrée décrite ci-haut pour le
+module texte.
+</para>
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Oui, Ã  la rigueur la partie graphique n`est probablement pas tellement
+plus difficile que celle textuelle. On pourrait commencer avec seulement
+la partie graphique qui produit directement la représentation en arbre.
+</para>
+
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+Comme je prévois réutiliser l'entrée texte Ã  l'intérieur de la fenêtre
+graphique, je crois qu'il est préférable de commencer par l'entrée texte.
+D'ailleurs, l'avantage pour quelqu'un qui commence Ã  contribuer au projet est de
+ne pas avoir Ã  apprendre l'API de GTK en même temps qu'il fait le développement
+de son module. Il est un peu trop facile de ne pas assez découpler la logique
+interne de la présentation.
+</para>
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Le cas classique est de choisir un CPU ou un type d`événement, auquel
+cas un menu simple de CPU et type serait beaucoup plus pratique que
+d`avoir Ã  taper une expression.
+</para>
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+On pourrait penser Ã  faire un module graphique de création de filtre de base,
+pour les fonctionnalités les plus utilisées. Celui-ci pourra Ãªtre Ã©tendu par
+la suite, si besoin est. L'intérêt est d'avoir quand-même la possibilité, pour
+un utilisateur plus avancé, de spécifier toutes les caractéristiques via
+l'interface. Dans ce cas, quelqu'un serait tout-à-fait prêt Ã  faire une
+expression pour décrire en détail son filtre. C'est quand-même quelque chose de
+plus en plus commun avec la venue des moteurs de recherche.
+</para>
+
+</sect1>
+
+<sect1>
+<title>Choix de syntaxe, documentation et messages d'erreur</title>
+<para>
+Michel Dagenais :
+</para>
+<para>
+Oui, une partie non négligeable est un choix de syntaxe convivial, la
+documentation et les messages d`erreur...
+</para>
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+C'est bel et bien ce qui sera perçu par l'utilisateur, de là l'importance..
+</para>
+<para>
+Je me demande s'il est mieux d'adopter une syntaxe un peu Ã  la Google ou bien Ã 
+la C :
+</para>
+
+<para>
+(, ), and, or, xor, not, field op value
+où op peut prendre : <, >, <=, >=, =
+</para>
+
+<para>
+ou bien Ã  la C
+(, ), &, |, ^, !, field op value
+</para>
+
+
+<para>
+Ou bien on peut faire un alphabet mixte entre les deux, où les mots and et &
+seraient Ã©quivalents. Ce serait probablement plus facile de reconnaître les
+symboles comme & par contre, et moins limitant sur le traitement du mot
+identifiant le field.
+</para>
+
+<para>
+Mais cette question est de moindre importance : tant qu'on se fixe un standard
+et qu'on le documente, je crois qu'il n'y a pas vraiment de mauvais choix.
+</para>
+
+<para>
+Pour la documentation, l'ajout d'une section au guide de l'utilisateur (déjà en
+docbook) me semble très adéquat.
+</para>
+
+<para>
+Pour les messages d'erreur, il faudra entres autres penser Ã  valider les
+opération par rapport Ã  celles permises pour chaque type. Par exemple, un > n'a
+pas vraiment de sens pour un string.
+</para>
+
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Je tendrais Ã  prendre la syntaxe C.
+</para>
+
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+Si on utilise de manière stricte la syntaxe C, il faudrait utiliser ceci :
+</para>
+
+<para>
+&&, ||, ==, (rien pour le xor logique ?)
+</para>
+
+<para>
+Je me dis que, puisque nous n'avons pas besoin des opérations "bitwise", nous
+pourrions utiliser celles-ci.
+</para>
+
+<para>
+Donc, ce que je propose, est d'utiliser l'alphabet utilisé pour les opérateurs
+bitwise du C en tant qu'opérateurs logiques pour notre parser d'expressions de
+filtre :
+</para>
+
+<para>
+&, |, =, ^
+</para>
+
+<para>
+Ceci est un détail sémantique, mais je veux juste m'assurer qu'on est d'accord.
+</para>
+
+
+</sect1>
+
+<sect1>
+<title>Optimisation Ã©ventuelles</title>
+
+
+<para>
+ "Cache" de filtre, afin d'optimiser le cas courant.
+  Au niveau de la partie "core" du filtrage, on pourrait faire une hash
+  table indexée par une clé formée d'un xor des champs Ã  filtrer. Alors, si un
+  Ã©vénement possède les même caractéristiques de filtrage, on pourrait accéder Ã 
+  la solution (V/F) en O(1). Le coût est de calculer la clé de hashage pour
+  chaque Ã©vénement. L'avantage apparaît lorsqu'il y a plusieurs critères de
+  filtrage Ã  comparer. La remise Ã  zéro de cette cache devrait Ãªtre faite
+  lorsqu'il y a des modifications au filtre.
+</para>
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Les travaux sur l`optimisation de requêtes dans les bases de données est
+probablement pertinent pour ce genre de choses.
+</para>
+
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+Il faudra que je m'y arrête. Cependant, ceci constitue une optimisation et n'est
+donc pas crucial pour le fonctionnement.
+</para>
+
+
+<para>
+Michel Dagenais :
+</para>
+<para>
+Sauf si c`est inutilisable sans une telle optimisation :-).
+</para>
+
+<para>
+Mathieu Desnoyers :
+</para>
+<para>
+N'est-ce pas toi qui m'a déjà dit, citant Donald Knuth  : "Premature
+optimisation is the root of all evil" ? :)
+</para>
+
+<para>
+Effectivement, si on s'aperçoit que c'est trop lent, il faudra passer Ã  cette
+étape.
+</para>
+
+
+</sect1>
+
+</chapter>
+
+
+
+</book>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/format.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/format.html
new file mode 100644 (file)
index 0000000..d41df44
--- /dev/null
@@ -0,0 +1,379 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>The new LTT trace format</title>
+</head>
+  <body>
+
+<h1>The new LTT trace format</h1>
+
+<P>
+A trace is contained in a directory tree. To send a trace remotely,
+the directory tree may be tar-gzipped. Trace foo, placed in the home
+directory of user john, /home/john, would have the following content:
+
+<PRE><TT>
+$ cd /home/john
+$ tree foo
+foo/
+|-- eventdefs
+|   |-- core.xml
+|   |-- net.xml
+|   |-- ipv4.xml
+|   `-- ide.xml
+|-- info
+|   |-- bookmarks.xml
+|   `-- system.xml
+|-- control
+|   |-- facilities
+|   |-- interrupts
+|   `-- processes
+`-- cpu
+    |-- 0
+    |-- 1
+    |-- 2
+    `-- 3
+</TT></PRE>
+
+<P>
+The eventdefs directory contains the events descriptions for all the
+facilities used. The syntax is a simple subset of XML; XML is widely
+known and easily parsed or hand edited. Each file contains one or more
+<FACILITY NAME=name>...</FACILITY> elements. Indeed, several
+facilities may have the same name but different content (and thus will
+generate a different checksum). It typically happens when, while tracing
+is enabled, a module using the named facility is unloaded, modified
+(along with the description of some events), recompiled and reloaded.
+Then, the trace will contain events from two different, similarly named,
+facility versions.
+
+<P>
+A small number of events are predefined, part of the "builtin" facility, 
+and are not present there. These "builtin" events include "facility_load", 
+"block_start", "block_end" and "time_heartbeat".
+
+<P>
+The cpu directory contains a tracefile for each cpu, numbered from 0, 
+in .trace format. A uniprocessor thus only contains the file cpu/0. 
+A multi-processor with some unused (possibly hotplug) CPU slots may have some
+unused CPU numbers. For instance a 8 way SMP board with 6 CPUs randomly 
+installed may produce tracefiles named 0, 1, 2, 4, 6, 7.
+
+<P>
+The files in the control directory also follow the .trace format. 
+The "facilities" file only contains "builtin" facility_load events
+and is used to determine the facilities used and the code range assigned 
+to each facility. The other control files contain the initial system
+state and various subsequent important events, for example process 
+creations and exit. The interest of placing such subsequent events 
+in control trace files instead of (or in addition to) in the per cpu 
+trace files is that they may be accessed more quickly/conveniently 
+and that they may be kept even when the per cpu files are overwritten 
+in "flight recorder mode".
+
+<P>
+The info directory contains in system.xml a description of the system on which
+the trace was created as well as different user annotations in bookmark.xml.
+This directory may also contain various information about the trace, generated 
+during trace analysis (statistics, index...).
+
+
+<H2>Trace format</H2>
+
+<P>
+Each tracefile is divided into equal size blocks with an uint32 at the block 
+end giving the offset to the last event in the block. Events are packed
+sequentially in the block starting at offset 0 with a "block_start" event
+and ending, at the offset stored in the last 4 bytes of the block, with a
+block_end event. Both the block_start and block_end events
+contain the kernel timestamp (timespec binary structure, 
+uint32 seconds, uint32 nanoseconds), the cycle counter (uint64 cycles), 
+and the buffer id (uint64).
+
+<P>
+Each event consists in an event type id (uint16 which is the event type id 
+within the facility + the facility base id), a time delta (uint32 in cycles
+or nanoseconds, depending on configuration, since the last time value, in the 
+block header or in a "time_heartbeat" event) and the event type specific data.
+All values are packed in native byte order binary format.
+
+
+<H2>System description</H2>
+
+<P>
+The system type description, in system.xml, looks like:
+
+<PRE><TT>
+&lt;system 
+ node_name="vaucluse"
+ domainname="polymtl.ca" 
+ cpu=4
+ arch_size="ILP32" 
+ endian="little" 
+ kernel_name="Linux" 
+ kernel_release="2.4.18-686-smp" 
+ kernel_version="#1 SMP Sun Apr 14 12:07:19 EST 2002"
+ machine="i686" 
+ processor="unknown" 
+ hardware_platform="unknown"
+ operating_system="Linux" 
+ ltt_major_version="2"
+ ltt_minor_version="0"
+ ltt_block_size="100000"
+&gt;
+Some comments about the system
+&lt;/system&gt;
+</TT></PRE>
+
+<P>
+The system attributes kernel_name, node_name, kernel_release,
+ kernel_version, machine, processor, hardware_platform and operating_system
+come from the uname(1) program. The domainname attribute is obtained from
+the "hostname --domain" command. The arch_size attribute is one of
+LP32, ILP32, LP64 or ILP64 and specifies the length in bits of integers (I),
+long (L) and pointers (P). The endian attribute is "little" or "big".
+While the arch_size and endian attributes could be deduced from the platform
+type, having these explicit allows analysing traces from yet unknown
+platforms. The cpu attribute specifies the maximum number of processors in
+the system; only tracefiles 0 to this maximum - 1 may exist in the cpu
+directory.
+
+<P>
+Within the system element, the text enclosed may describe further the
+system traced.
+
+
+<H2>Event type descriptions</H2>
+
+<P>
+A facility contains the descriptions of several event types. When a structure
+is reused in several event types, a named type is defined and may be referenced
+by several other event types or named types.
+
+<PRE><TT>
+&lt;facility name=facility_name&gt;
+  &lt;description&gt;Some text&lt;/description&gt;
+  &lt;event name=eventtype_name&gt;
+    &lt;description&gt;Some text&lt;/description&gt;
+    --type structure--
+  &lt;/event&gt;
+  ...
+  &lt;type name=type_name&gt;
+    --type structure--
+  &lt;/type&gt;
+&lt;/facility&gt;
+</TT></PRE>
+
+<P>
+The type structure may be one of the following primitive type elements.
+Whenever the keyword isize is used, the allowed values are 
+short, medium, long, 1, 2, 4, 8, indicating the size in bytes.
+The fsize keyword represents one of medium, long, 4 and 8 bytes.
+
+<PRE><TT>
+&lt;int size=isize format="printf format"/&gt;
+
+&lt;uint size=isize format="printf format"/&gt;
+
+&lt;float size=fsize format="printf format"/&gt;
+
+&lt;string format="printf format"/&gt;
+
+&lt;enum size=isize format="printf format"&gt;label1 label2 ...&lt;/enum&gt;
+</TT></PRE>
+
+<P>
+The string is null terminated. For the enumeration, the size of the integer
+used for its representation is specified.
+
+<P>
+The type structure may also be a compound type.
+
+<PRE><TT>
+&lt;array size=n&gt; --type structure-- &lt;/array&gt;
+
+&lt;sequence lengthsize=isize&gt; --type structure-- &lt;/sequence&gt;
+
+&lt;struct&gt;
+  &lt;field name=field_name&gt;
+    &lt;description&gt;Some text&lt;/description&gt;
+    --type structure--
+  &lt;/field&gt;
+  ...
+&lt;/struct&gt;
+
+&lt;union typecodesize=isize&gt;
+  &lt;field name=field_name&gt;
+    &lt;description&gt;Some text&lt;/description&gt;
+    --type structure--
+  &lt;/field&gt;
+  ...
+&lt;/union&gt;
+</TT></PRE>
+
+<P>
+Array is a fixed size array of length size. Sequence is a variable size
+array with its length stored as a prepended uint of length lengthsize. 
+A structure is simply an aggregation of fields. An union is one of its n 
+fields (variant record), as indicated by a preceeding code (0 to n - 1)
+of the specified size typecodesize.
+
+<P>
+Finally the type structure may be defined by referencing a named type.
+
+<PRE><TT>
+&lt;typeref name=type_name/&gt;
+</PRE></TT>
+
+<H2>Builtin events</H2>
+
+<P>
+The facility named "builtin" is always present and contains at least the
+following event types.
+
+<PRE><TT>
+&lt;event name=facility_load&gt;
+  &lt;description&gt;Facility used in the trace&lt;/description&gt;
+  &lt;struct&gt;
+    &lt;field name="name"&gt;&lt;string/&gt;&lt;/field&gt;
+    &lt;field name="checksum"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="base_code"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+  &lt;/struct&gt;
+&lt;/event&gt;
+
+&lt;event name=block_start&gt;
+  &lt;description&gt;Block start timestamp&lt;/description&gt;
+  &lt;typeref name=block_timestamp/&gt;
+&lt;/event&gt;
+
+&lt;event name=block_end&gt;
+  &lt;description&gt;Block end timestamp&lt;/description&gt;
+  &lt;typeref name=block_timestamp/&gt;
+&lt;/event&gt;
+
+&lt;event name=time_heartbeat&gt;
+  &lt;description&gt;System time values sent periodically to minimize cycle counter 
+    drift with respect to real time clock and to detect cycle counter
+    rollovers
+  &lt;/description&gt;
+  &lt;typeref name=timestamp/&gt;
+&lt;/event&gt;
+
+&lt;type name=block_timestamp&gt;
+  &lt;struct&gt;
+    &lt;field name=timestamp&gt;&lt;typeref name=timestamp&gt;&lt;/field&gt;
+    &lt;field name=block_id&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+  &lt;/struct&gt;
+&lt;/type&gt;
+
+&lt;type name=timestamp&gt;
+  &lt;struct&gt;
+    &lt;field name=time&gt;&lt;typeref name=timespec/&gt;&lt;/event&gt;
+    &lt;field name="cycle_count"&gt;&lt;uint size=8/&gt;&lt;/field&gt;
+  &lt;/struct&gt;
+&lt;/event&gt;
+
+&lt;type name=timespec&gt;
+  &lt;struct&gt;
+    &lt;field name="seconds"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="nanoseconds"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+  &lt;/struct&gt;
+&lt;/type&gt;
+</TT></PRE>
+
+<H2>Control files</H2>
+
+<P>
+The interrupts file reflects the content of the /proc/interrupts system file.
+It contains one event describing each interrupt. At trace start, events are
+generated describing all the current interrupts. If the assignment of
+interrupts changes later, due to devices or device drivers being activated or
+deactivated, additional events may be added to the file. Each interrupt
+event has the following structure.
+
+<PRE><TT>
+&lt;event name=interrupt&gt;
+  &lt;description&gt;Interrupt request number assignment&lt;description&gt;
+  &lt;struct&gt;
+    &lt;field name="number"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="count"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="controller"&gt;&lt;string/&gt;&lt;/field&gt;
+    &lt;field name="name"&gt;&lt;string/&gt;&lt;/field&gt;
+  &lt;/struct&gt;
+&lt;/event&gt;
+</TT></PRE>
+
+<P>
+The processes file contains the list of processes already created when the
+trace starts. Each process describing event is modeled after the 
+/proc/self/status system file. The number of fields in this event is
+expected to be expanded in the future to include groups, signal masks,
+opened file descriptors and address maps.
+
+<PRE><TT>
+&lt;event name=process&gt;
+  &lt;description&gt;Existing process&lt;description&gt;
+  &lt;struct&gt;
+    &lt;field name="name"&gt;&lt;string/&gt;&lt;/field&gt;
+    &lt;field name="pid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="ppid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="tracer_pid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="uid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="euid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="suid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="fsuid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="gid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="egid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="sgid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="fsgid"&gt;&lt;uint size=4/&gt;&lt;/field&gt;
+    &lt;field name="state"&gt;&lt;enum size=4&gt;
+        Running WaitInterruptible WaitUninterruptible Zombie Traced Paging
+    &lt;/enum&gt;&lt;/field&gt;
+  &lt;/struct&gt;
+&lt;/event&gt;
+</TT></PRE>
+
+<H2>Facilities</H2>
+
+<P>
+Facilities define a granularity of events grouping for filtering, activation
+and compilation. Each facility does cost a table entry in the kernel (name,
+checksum, event type code range), or somewhere between 20 and 30 bytes. Having
+one facility per tracing statement in the kernel would be too much (assuming
+that they eventually are routinely inserted in the kernel code and replace 
+the 80000+ printk statements in some proportion). However, having a few 
+facilities, up to a few tens, would make sense.
+
+<P>
+The "builtin" facility contains a small number of predefined events which must
+always exist. The "core" facility contains a small subset of OS events which
+are almost always of interest (scheduling, interrupts, faults, system calls).
+Then, specialized facilities may exist for each subsystem (network, disks,
+USB, SCSI...).
+
+<H2>Bookmarks</H2>
+
+<P>
+Bookmarks are user supplied information added to a trace. They contain user
+annotations attached to a time interval.
+
+<PRE><TT>
+&lt;bookmarks&gt;
+  &lt;location name=name cpu=n start_time=t end_time=t&gt;Some text&lt;/location&gt;
+  ...
+&lt;/bookmarks&gt;
+</TT></PRE>
+
+<P>
+The interval is defined using either "time=" or "start_time=" and 
+"end_time=", or "cycle=" or "start_cycle=" and "end_cycle=". 
+The time is in seconds with decimals up to nanoseconds and cycle counts 
+are unsigned integers with a 64 bits range. The cpu attribute is optional.
+
+</BODY>
+</HTML>
+
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/guiControlFlow.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/guiControlFlow.html
new file mode 100644 (file)
index 0000000..c12fef6
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Control Flow Viewer Module</title>
+</head>
+<body>
+
+<h1>Control Flow Viewer Module</h1>
+
+
+<P>
+
+
+<P>
+Mathieu Desnoyers, September 2003
+
+</body>
+</html>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/gui_layout.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/gui_layout.txt
new file mode 100644 (file)
index 0000000..c3a82d2
--- /dev/null
@@ -0,0 +1,142 @@
+GUI Layout
+
+
+
+
+In order to implement the GUI, choices has to be made based on habitual interfaces that we know users are familiar with. The inspiration for these choices came mainly from the Mozilla browser project and also from Openoffice, which are currently used as two userfriendly applications in various Linux distribution at the time of this writing.
+
+This document describes the layout of the GUI in three sections : containers, menus and toolbars.
+
+A status bar is also placed at the bottom of the window.
+
+- Containers
+
+elements hierarchy
+
+Window Mainwindow
+|->vbox
+   |->menus
+   |->toolbar of the main window
+   |->toolbar of the currently selected viewer
+   |->notebook
+   |  |->vpaned
+   |  |->viewer's widget
+   |  |->vpaned
+   |  |->viewer's widget
+   |  |->vpaned
+   |  |->...
+   |->Status bar
+
+- Menus
+
+Here is a short description of each menu entry
+*   by itself means a separator
+
+
+- File
+*New -> *Empty trace set : open a new window with an empty trace set.
+        *Clone trace set : copy the content of the current window in a new
+                          window.
+       *
+       *Tab : Opens a new tab.
+*Open : open a trace set. Calls a file selection dialog.
+*Close : close the current window.
+*Close Tab : close the current tab.
+*
+*Add trace : Add a trace to the window's traceset. Calls file selection dialog.
+*Remove trace : Removes a trace from the traceset.
+*Save : save the trace set. Calls a file save dialog of no current filename.
+*Save as : save a trace set. Calls a file save dialog.
+*
+*Quit : quit the program.
+
+- Edit ? (not needed for now)
+
+- View
+*Zoom In : Multiply the zoom factor by a certain quantity.
+*Zoom Out : Divide the zoom factor by a certain quantity.
+*Zoom Extended : Show the entire traceset's largest time interval.
+*Go to time : Keep same zoom, ask user for time to center view on and make
+              it the current time.
+*Show time frame : ask user for time interval to show.
+              (modify zoom and current event in consequence)
+
+- Tools (this is an example of how viewer's menu entries should look like)
+*Move viewer up -> Moves the current viewer up one position.
+*Move viewer down -> Moves the current viewer down one position.
+*Remove : remove the current viewer
+*
+*DumpToFile -> *Dump Text (This is a text module which adds graphical menu
+                           entries)
+               *Dump binary
+* (separator between text tools and graphical tools implies different function
+   to register each type of menu entries)
+*Insert Events View : insert this type of viewer
+*Insert ControlFlow View
+- Plugins
+*Load module : ask the user a module to load (list modules in search path).
+*Unload module : list all modules, click to choose, then unload button.
+*Add module search path : ask user for a new path (file selection dialog).
+
+- Options
+//FIXME *Color : change the color of the currently selected element ?
+*Filter : Show traceset's filter option window.
+*Save configuration : Save the currently loaded modules/traceset/filters
+                      to gconf.
+
+
+(aligned to the right)
+- Help
+*Content
+*About
+
+
+- Toolbar
+
+The toolbar is separated in two parts : like the two lines used in Openoffice. The first one is applying to the top level window (or current tab) while the one below contains the current viewer's toolbar.
+
+So we have something like this :
+
+--------------------------------------------------------------------------------
+| Menus                                                                        |
+--------------------------------------------------------------------------------
+| Toolbar of the top level window                                              |
+--------------------------------------------------------------------------------
+| Toolbar of the current viewer                                                |
+--------------------------------------------------------------------------------
+||Current Tab|                                                                 |
+|-----------------------------------------------------------------------------||
+||viewers in vpaned                                                           ||
+||                                                                            ||
+||----------------------------------------------------------------------------||
+--------------------------------------------------------------------------------
+| Status bar                                                                   |
+--------------------------------------------------------------------------------
+
+
+The toolbar of the top level window is the only one described in this document, as the second one is defined by the viewers and specific to each of them.
+
+This toolbar is mainly a selection of the menu entries.
+
+New : New window with empty trace set.
+Open : open a trace set.
+Add Trace
+Remove Trace
+Save : save the current trace set.
+Save as
+*
+Zoom in
+(Show the current zoom factor, modifiable)
+Zoom out
+Zoom Extended
+Go to time (shows time directly)
+Show time frame (Could be a special field showing the time frame)
+*
+Move up current viewer
+Move down current viewer
+Delete current viewer
+*
+Add viewer's specific insertion buttons are added here.
+
+
+Mathieu Desnoyers, June 2003
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/guidetailed-event-list-redesign.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/guidetailed-event-list-redesign.txt
new file mode 100644 (file)
index 0000000..8159f46
--- /dev/null
@@ -0,0 +1,139 @@
+
+Redesign of the GUI detailed event list
+
+Mathieu Desnoyers 08/2005
+
+The basic problem about this list is that it uses the number of events, not the
+time, as a vertical axis (for the Y axis scrollbar).
+
+Seeking in the traces is done by time. We have no clue of the number of events
+between two times without doing preparsing.
+
+If we want to fully reuse textDump, it's bettwer if we depend upon state
+computation. It would be good to make the viewer work with this information
+missing though.
+
+textDump's print_field should be put in a lttv/lttv core file, so we can use it
+as is in the detailed event list module without depending upon batchAnalysis.
+
+
+* With preparsing only :
+
+The problem then becomes simpler :
+
+We can precompute the event number while doing state computation and save it
+periodically with saved states. We can then use the event number in the trace
+as scrollbar value, which, when scrolled, would result into a search in the
+saved states by event number.
+
+How much time would it take to seek back to the wanted position from the last
+saved state ?
+
+compudj@dijkstra:~/local/bin$ ./lttv -m batchtest -1 -2 -t
+/home/compudj/traces/200MB 
+** Message: Processing trace while counting events (12447572 events in 14.0173
+seconds)
+** Message: Processing trace while updating state (9.46535 seconds)
+
+9.46535 s / 12447572 events * 50000 events = 0.038 s
+
+38 ms latency shouldn't be too noticeable by a user when scrolling.
+
+(note : counting events batchtest does also verify time flow integrity and get
+the position for each event (not optimal), that's why it takes 14s)
+
+As an optimisation, we could use a backing text buffer (an array of strings),
+where we would save the 50000 computed events between two consecutive saved
+states.
+
+Memory required : 50000 * 20 bytes/event = 1MB
+
+Which seems ok, but costy. In would be better, in fact, not to depend on the
+saved states interval for such a value : we could keep a 1000 events array, for
+instance (for 20KB cost, which is really better).
+
+The backing text buffer would, by itself, make sure it has a sufficient
+number of events so a scroll up/down of one page would be responded directly.
+That imply that a scroll up/down would first update the shown fields, and only
+afterward make the backing buffer resync its events in the background. In the
+case where the events were not directly available, it would have to update the
+buffer in the foreground and only then show the requested events.
+
+
+Important note : this design doesn't support filtering of events, which is
+                 an important downside.
+
+
+
+* If we want the viewer to be able to show information without preparsing :
+
+This is the hardest the problem could get. We have to seek by time (even the
+scrollbar must seek by time), but increment/decrement event by event when using
+the scrollbar up/down, page up/page down. Let's call them "far scroll" and "near
+scroll", respectively.
+
+A far scroll must resync the trace to the time requested by the scrollbar value.
+
+A near scroll must sync the trace to a time that is prior to the requested
+event, show the events requested, and then sync the scrollbar value (without
+event updating) to the shown event time.
+
+* seek n events backward
+
+We have no information about how far back we must request events in the trace :
+
+The algorithm would look like :
+
+seek_n_events_backward(current time, current position, time_offset, filter)
+Returns : a TracesetPosition
+  - If the current time < beginning of trace, is means we cannot get any more
+    events, inform the requester that a list of less than n events is ready.
+  - Else, request a read to a the time_offset backward, calling the
+    per event hook, and calling the after_traceset hook when finished. The end
+    position would be the position of the current first event.
+  
+per_event_hook
+  - if filter returns true
+    - Append the traceset position to a list of maximum size n. Remove the first
+      entries.
+
+after_traceset_hook
+  - if the list has a size less than n, invoke a seek_n_events_backward
+    subsequent iteration, for completing the list. The new time_offset is the
+    last time_offset used multiplied by 2. (can be done by tail recursion (if we
+    want to split this operation in multiple segments) or by an iterative
+    algorithm (seek_n_events_backward would be a while() calling its own
+    process_traceset_middle()).
+  - if the list a a size of n, it's complete : call the viewer get_print_events
+    hook.
+
+
+* seek n events forward
+
+seek_n_events_forward(current position, filter)
+  - Simple : seek to the current position, request read of trace calling an
+    event counting hook (starts at 0).
+    
+event_counting_hook
+  - if filter returns true
+    - increment event count.
+    - if event count > requested count, inform that the current position if the
+      wanted position. Return TRUE, so the read will stop.
+
+
+* Printing events
+
+get_print_events
+  - seek to the position at the beginning of the list. End position is the
+    current one (not in the list! the one currently shown). Call a events
+    request between this positions, printing the fields to strings shown in the
+    viewer.
+
+
+
+seek_n_events backward and forward seems to be interesting algorithms that
+should be implemented in the tracecontext library. With those helpers, it would
+become simpler to implement a detailed event list not depending on state
+computation.
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/hook_prio.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/hook_prio.txt
new file mode 100644 (file)
index 0000000..910d86b
--- /dev/null
@@ -0,0 +1,24 @@
+Linux Trace Toolkit
+
+Mathieu Desnoyers 18-05-2004
+
+
+Seeing that a very precise hook call ordering is needed when processing events
+(especially the order for calling state update hooks and event delivery hooks),
+this document defines a new type and interface that permits to merge all kind of
+hooks, eventually sorted by the priority associated to them.
+
+- Type LttvHooks with priorities
+
+This is a modification to the actual LttvHooks that associates a priority with
+each hook. The container for this type would be a garray, just like hook.c, but
+hooks would be added at the right position in the list, by priority. Hooks in a
+hook list are ordered by priority : from highest priority (0) to
+lowest (99). The default priority is 50 (defined as LTTV_PRIO_DEFAULT).
+
+A new lttv_hooks_call_merge that will get the hooks from two hook lists in the
+right order will deal with the multiple lists priority problem.
+
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/index.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/index.html
new file mode 100644 (file)
index 0000000..1b79388
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Linux Trace Toolkit trace analysis tools development</title>
+</head>
+  <body>
+<h1>Linux Trace Toolkit trace analysis tools development</h1>
+
+<UL>
+<LI><A HREF="discuss.html">Discussion of existing Linux tracing tools.</A>
+<LI><A HREF="format.html">New format for Linux Trace Toolkit (LTT) traces.</A>
+<LI><A HREF="lttv.html">
+Architecture for the modular Linux Trace Toolkit trace analysis tools.</A>
+<LI><A HREF="coding.html">Coding practices.</A>
+<LI><A HREF="status.html">Current status.</A>
+<LI><A HREF="todo.html">Roadmap.</A>
+</UL>
+</BODY>
+</HTML>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/library-header.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/library-header.txt
new file mode 100644 (file)
index 0000000..00e2ecf
--- /dev/null
@@ -0,0 +1,17 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Your Name
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/ltt-to-do.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/ltt-to-do.html
new file mode 100644 (file)
index 0000000..0fda117
--- /dev/null
@@ -0,0 +1,204 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Linux Trace Toolkit Status</title>
+</head>
+  <body>
+        
+<h1>Linux Trace Toolkit Status</h1>
+        
+<p><i>Last updated July 1, 2003.</i> </p>
+     
+<p>During the 2002 Ottawa Linux Symposium tracing BOF, a list of desirable 
+  features for LTT was collected by Richard Moore. Since then, a lot of infrastructure 
+ work on LTT has been taking place. This status report aims to track current 
+ development efforts and the current status of the various features. This
+status page is most certainly incomplete, please send 
+any additions and corrections to Michel Dagenais (michel.dagenais at polymtl.ca)</p>
+
+<p>As of this writing, the most active LTT contributors include Karim Yaghmour,
+author and maintainer from opersys.com, Tom Zanussi, Robert Wisniewski,
+Richard J Moore and others from IBM, mainly at the Linux Technology Center,
+XiangXiu Yang, Mathieu Desnoyers, Benoit des Ligneris and Michel Dagenais,
+from the department of Computer Engineering at Ecole Polytechnique de
+Montreal, and Frank Rowand, from Monte Vista.</p>
+
+<h2>Work recently performed</h2>
+        
+<p><b>Lockless per cpu buffers:</b> Tom Zanussi of IBM has implemented per CPU lockless buffering,  with low
+overhead very fine grained timestamping, and has updated accordingly  the
+kernel patch and the trace visualizer except for viewing multiple per CPU
+traces simultaneously.  </p>
+     
+<p><b>RelayFS:</b> Tom Zanussi has implemented RelayFS, a separate, simple 
+and efficient component for moving data between the kernel and user space
+applications. This component is reusable by other projects (printk, evlog, 
+lustre...) and removes a sizeable chunk from the current LTT, making each 
+piece (relayfs and relayfs-based LTT) simpler, more modular and possibly 
+more palatable for inclusion in the standard Linux kernel. Besides LTT on
+RelayFS, He has implemented printk over RelayFS with an automatically 
+resizeable printk buffer. </p>
+
+<p><b>New trace format:</b> Karim Yaghmour and Michel Dagenais, with input
+from several LTT contributors, have designed a new trace format to accomodate
+per buffer tracefiles and dynamically defined event types. The new format
+includes both the binary trace format and the event type description format.
+XiangXiu Yang has developed a simple parser for the event type description 
+format. This parser is used to generate the tracing macros in the kernel
+(genevent) and to support reading tracefiles in the trace reading library
+(libltt).
+
+<h2>Ongoing work</h2>
+
+<p><b>Libltt:</b> XiangXiu Yang is finishing up an event reading library
+and API which parses event descriptions and accordingly reads traces and
+decodes events.  </p>
+     
+<p><b>lttv:</b> XiangXiu Yang, Mathieu Desnoyers and Michel Dagenais are
+remodeling the trace visualizer to use the new trace format and libltt API,
+and to allow compiled and scripted plugins, which can dynamically 
+add new custom trace analysis functions.  </p>
+     
+<h2>Planned work</h2>
+        
+<p>LTT already interfaces with Dynamic Probes. This feature will need to
+be updated for the new LTT version.   </p>
+     
+<p>The Kernel Crash Dump utilities is  another very interesting complementary 
+ project. Interfacing it with RelayFS will help implement useful 
+flight-recorder like tracing for post-mortem analysis.  </p>
+     
+<p>User level tracing is available in the current LTT version but requires
+one system call per event. With the new RelayFS based infrastructure, it
+would be interesting to use a shared memory buffer directly accessible from
+user space. Having one RelayFS   channel per user would allow an extremely
+efficient, yet secure, user level  tracing mechanism.  </p>
+     
+<p>Sending important events (process creation, event types/facilities
+definitions) to a separate channel could be used to browse traces
+interactively more efficiently.  Only this concise trace of important
+events would need to be processed in its entirety, other larger
+gigabyte size traces could be used in random access without requiring
+a first preprocessing pass. A separate channel would also be required
+in case of incomplete traces such as when tracing to a circular buffer
+in "flight recorder" mode; the important events would all be kept
+while only the last buffers of ordinary events would be kept.  </p>
+     
+<p>Once the visualizer is able to read and display several traces, it
+  will be interesting to produce side by side synchronized views
+  (events from two interacting machines A and B one above the other)
+  or even merged views (combined events from several CPUs in a single
+  merged graph). Time differences between interacting systems will
+  need to be estimated and somewhat compensated for.  </p>
+     
+<p>LTT currently writes a <i>proc</i> file at trace start time. This
+  file only contains minimal information about processes and
+  interrupts names.  More information would be desirable for several
+  applications (process maps, opened descriptors, content of buffer
+  cache). Furthermore, this information may be more conveniently
+  gathered from within the kernel and simply written to the trace as
+  events at start time.  </p>
+     
+<h2>New features already implemented since LTT 0.9.5</h2>
+        
+<ol>
+    <li> Per-CPU Buffering scheme. </li>
+     <li> Logging without locking. </li>
+     <li> Minimal latency - minimal or no serialisation. (<i>Lockless tracing
+using  read_cycle_counter instead of gettimeofday.</i>) </li>
+               <li> Fine granularity time stamping - min=o(CPU cycle time),
+max=.05 Gb  Ethernet interrupt rate. (<i>Cycle counter being used</i>). </li>
+     <li> Random access to trace event stream. (<i>Random access reading
+of  events  in the trace is already available in LibLTT. However, one first
+pass   is required through the trace to find all the process creation events;
+the  cost of this first pass may be reduced in the future if process creation
+ events are sent to a separate much smaller trace</i>.) </li>
+     
+</ol>
+        
+<h2>Features being worked on</h2>
+        
+<ol>
+    <li> Simple wrapper macros for trace instrumentation. (<i>GenEvent</i>)
+   </li>
+     <li> Easily expandable with new trace types.  (<i>GenEvent</i>) </li>
+     <li> Multiple buffering schemes - switchable globally or selectable
+by  trace client. (<i>Will be simpler to obtain with RelayFS</i>.) </li>
+     <li> Global buffer scheme. (<i>Will be simpler to obtain with RelayFS</i>.)
+    </li>
+     <li> Per-process buffer scheme. (<i>Will be simpler to obtain with RelayFS.</i>)
+    </li>
+     <li> Per-NGPT thread buffer scheme. (<i>Will be simpler to obtain with 
+ RelayFS</i>.) </li>
+     <li> Per-component buffer scheme. (<i>Will be simpler to obtain with 
+RelayFS</i>.)    </li>
+          <li> A set of extensible and modular performance analysis post-processing
+programs. (<i>Lttv</i>)     </li>
+  <li> Filtering and selection mechanisms within formatting utility. (<i>Lttv</i>)
+    </li>
+     <li> Variable size event records. (<i>GenEvent, LibEvent, Lttv</i>)
+   </li>
+     <li> Data reduction facilities able to logically combine traces  from
+ more than one system. (<i>LibEvent, Lttv</i>) </li>
+     <li> Data presentation utilities to be able to present data from multiple 
+  trace instances in a logically combined form (<i>LibEvent, Lttv</i>) 
+  </li>
+     <li> Major/minor code means of identification/registration/assignment.
+ (<i>GenEvent</i>)    </li>
+     <li> A flexible formatting mechanism that will cater for structures
+and  arrays of structures with recursion. (<i>GenEvent</i>) </li>
+     
+</ol>
+        
+<h2>Features already planned for</h2>
+        
+<ol>
+    <li> Init-time tracing. (<i>To be part of RelayFS</i>.) </li>
+     <li>Updated interface for Dynamic Probes. (<i>As soon as things stabilize.</i>)
+    </li>
+     <li> Support "flight recorder" always on tracing with minimal resource
+consumption.  (<i>To be part of RelayFS and interfaced to the Kernel crash
+dump   facilities.)</i>    </li>
+     <li> Fine grained dynamic trace instrumentation for kernel space and 
+user   subsystems. (<i>Dynamic Probes, more efficient user level tracing.</i>)</li>
+     <li>System information logged at trace start. (<i>New special events 
+to add</i>.)</li>
+     <li>Collection of process memory map information at trace start/restart 
+ and updates of that information at fork/exec/exit. This allows address-to-name 
+  resolution for user space. </li>
+     <li>Include the facility to write system snapshots (total memory  layout 
+ for kernel, drivers, and all processes) to a file.  This is required  for 
+ trace post-processing on a system other than the one producing the trace.
+  Perhaps some of this is already implemented in the Kernel Crash Dump.</li>
+     <li>Even more efficient tracing from user space.</li>
+     <li>Better integration with tools to define static trace hooks.</li>
+     <li> Better integration with tools to dynamically activate tracing statements.</li>
+          
+</ol>
+        
+<h2>Features not currently planned</h2>
+        
+<ol>
+    <li>POSIX Tracing API compliance. </li>
+     <li>Ability to do function entry/exit tracing facility. (<i>Probably 
+ a totally orthogonal mechanism using either Dynamic Probes hooks or static
+  code instrumentation using the suitable GCC options for basic blocks instrumentation.</i>)</li>
+     <li>Processor performance counter (which most modern CPUs have) sampling 
+and recording. (<i>These counters can be read and their value sent in traced 
+events. Some support to collect these automatically at specific state change 
+times and to visualize the results would be nice.)</i></li>
+          <li>Suspend &amp; Resume capability. (<i>Why not simply stop the
+ trace and start a new one later, otherwise important information like process
+creations while suspended must be obtained in some other way.</i>)</li>
+     <li>Per-packet send/receive event. (<i>New event types will be easily
+added as needed.)</i></li>
+               
+</ol>
+   <br>
+     <br>
+
+</body>
+</html>
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttng-lttv-roadmap.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttng-lttv-roadmap.html
new file mode 100644 (file)
index 0000000..902f60b
--- /dev/null
@@ -0,0 +1,112 @@
+<html>
+<body>
+<center><big><big>LTTV & LTTng roadmap<small><small></center>
+<br>
+<br>
+Here are the roadmaps for the LTTV and LTTng development. I use a priority indice
+for the TODO items :<br>
+(1) : very high priority<br>
+(10): lowest priority<br>
+<br>
+<br>
+<big>LTTV Roadmap<small><br>
+<br>
+* TODO<br>
+(4) create a event rate graphical view : Will be useful in conjonction with the
+  filter.<br>
+(6) migrate align to lttv parser.<br>
+(7) create an analysis of function time (like a precise gprof)<br>
+  -> with gcc -f inline-functions<br>
+<br>
+<br>
+* Done<br>
+Buffer aligned on page boundary -> use valloc.<br>
+per struct (struct align=x) support added to genevent (partial).<br>
+Add offset align generation for structs to genevent.<br>
+make lttv aware of the per facility long, void* and size_t types.<br>
+Read current trace header and buffer header.<br>
+redo lib tracefile : too much problems in there.<br>
+modify the rest of LTTV to match the API changes.<br>
+debian package<br>
+RPM package<br>
+<br>
+<big>LTT Next Generation Roadmap<small><br>
+<br>
+* TODO<br>
+(1) create RPM packages for lttng kernel<br>
+(1) make LTT tracing code completely atomic (thus remove locks)<br>
+(2) add efficient and secure user space tracing. (1 month)<br>
+(3) integrate LTTng State Dump : missing irq and process state.<br>
+(9) add genevent full functionnality : alignment, array, sequences, nested
+structures.<br>
+(7) add gcc -finstrument-functions instrumentation<br>
+<br>
+<br>
+* Done<br>
+remove ltt-headers.h<br>
+remove ltt-log.h<br>
+Put trace->active later in _ltt_trace_start()<br>
+ltt_trace_create() remove sleep in spinlock use GFP_ATOMIC kmalloc<br>
+Fix the locking of module hooks.<br>
+Fix the traps -> disable nested logging for now.<br>
+Use per cpu spinlock on trace list.<br>
+Finish the control module, libltt and lttctl : netlink interface<br>
+Finish integrating lttctl with lttd.<br>
+fix lttctl signal waiting : use a flag.<br>
+Add ltt_write_commit_counter call to genevent.<br>
+Add information in the buffer header : buffer size, etc etc...<br>
+       -> this information is so small that we can repeat it. Makes flight recorder
+       easier to decode.<br>
+Add trace start structure to buffer start header.<br>
+fix genevent : take no lock if num traces active is 0.<br>
+Add type information per facility : it will help having a standard way
+to understand information coming from both kernel space and user space, and deal
+easily with 64 bits kernel with 64 and 32 bits processes (and with size_t know
+at compile time which can differ inside the same process from one library to
+another).<br>
+fix structures alignment, array and sequences too. -> trace dynamic.<br>
+add per facility alignment (inside structures).<br>
+add control of alignment.<br>
+add control for subbuffer size and number of subbuffers.<br>
+Add reserve - get TSC - alignment atomicity through the use of cmpxchg.<br>
+Add configurable alignment (LTT_ALIGNMENT).<br>
+Get ultra-precise logging with use of TSC (only) : only one do_gettimeofday
+read, and then we don't want the time flow to be altered by ntp.<br>
+Debian kernel package<br>
+<br>
+<br>
+<br>
+* TODO (low priority)<br>
+Integrate header generation (genevent) in kernel build system.<br>
+Multithreaded lttd.<br>
+Find a different way to printk from instrumentation : forbidden from schedule
+and wakeup (causes a deadlock).<br>
+<br>
+* Need to be discussed<br>
+Drop ltt-module-register and ltt-module-unregister, use exported variables.<br>
+RelayFS ioctl interface vs control through LTT netlink interface.<br>
+drop ltt_filter_control, use functions pointers instead.<br>
+Merge facilities headers into one big header.<br>
+Change the name of XML files from XML to something else.<br>
+Remove ltt-base.c.<br>
+<br>
+* Not planned for integration<br>
+Remove the callback struct from the trace struct.<br>
+<br>
+<br>
+<br>
+* lttng patch division (0.4.2+) :<br>
+<br>
+ltt-instrumentation.diff<br>
+ltt-facilities-headers.diff<br>
+ltt-facilities-loader.diff<br>
+ltt-facilities.diff<br>
+ltt-relayfs.diff<br>
+ltt-core.diff<br>
+<br>
+<br>
+Mathieu Desnoyers<br>
+
+
+</body>
+</html>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttv.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttv.html
new file mode 100644 (file)
index 0000000..0f2f6dd
--- /dev/null
@@ -0,0 +1,417 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Linux Trace Toolkit trace analysis tools</title>
+</head>
+  <body>
+
+<h1>Linux Trace Toolkit trace analysis tools</h1>
+
+<P>The Linux Trace Toolkit Visualizer, lttv, is a modular and extensible
+tool to read, analyze, annotate and display traces. It accesses traces through
+the libltt API and produces either textual output or graphical output using
+the GTK library. This document describes the architecture of lttv for
+developers.
+
+<P>Lttv is a small executable which links to the trace reading API, libltt,
+and to the glib and gobject base libraries. 
+By itself it contains just enough code to
+convert a trace to a textual format and to load modules. 
+The public
+functions defined in the main program are available to all modules.
+A number of
+<I>text</I> modules may be dynamically loaded to extend the capabilities of
+lttv, for instance to compute and print various statistics.
+
+<P>A more elaborate module, traceView, dynamically links to the GTK library
+and to a support library, libgtklttv. When loaded, it displays graphical
+windows in which one or more viewers in subwindows may be used to browse 
+details of events in traces. A number of other graphical modules may be 
+dynamically loaded to offer a choice of different viewers (e.g., process, 
+CPU or block devices state versus time).
+
+<H2>Main program: main.c</H2>
+
+<P>The main program parses the command line options, loads the requested 
+modules and executes the hooks registered in the global attributes
+(/hooks/main/before, /hooks/main/core, /hooks/main/after).
+
+<H3>Hooks for callbacks: hook.h (hook.c)</H3>
+
+<P>In a modular extensible application, each module registers callbacks to
+insure that it gets called at appropriate times (e.g., after command line
+options processing, at each event to compute statistics...). Hooks and lists
+of hooks are defined for this purpose and are normally stored in the global
+attributes under /hooks/*.
+
+<H3>Browsable data structures: iattribute.h (iattribute.c)</H3>
+
+<P>In several places, functions should operate on data structures for which the
+list of members is extensible. For example, the statistics printing 
+module should not be
+modified each time new statistics are added by other modules.
+For this purpose, a gobject interface is defined in iattribute.h to
+enumerate and access members in a data structure. Even if new modules
+define custom data structures for efficiently storing statistics while they
+are being computed, they will be generically accessible for the printing
+routine as long as they implement the iattribute interface.
+
+<H3>Extensible data structures: attribute.h (attribute.c)</H3>
+
+<P>To allow each module to add its needed members to important data structures,
+for instance new statistics for processes, the LttvAttributes type is
+a container for named typed values. Each attribute has a textual key (name) 
+and an associated typed value. 
+It is similar to a C data structure except that the
+number and type of the members can change dynamically. It may be accessed
+either directly or through the iattribute interface.
+
+<P>Some members may be LttvAttributes objects, thus forming a tree of
+attributes, not unlike hierarchical file systems or registries. This is used
+for the global attributes, used to exchange information between modules.
+Attributes are also attached to trace sets, traces and contexts to allow
+storing arbitrary attributes.
+
+<H3>Modules: module.h (module.c)</H3>
+
+<P>The benefit of modules is to avoid recompiling the whole application when
+adding new functionality. It also helps insuring that only the needed code 
+is loaded in memory.
+
+<P>Modules are loaded explicitly, being on the list of default modules or
+requested by a command line option, with g_module_open. The functions in
+the module are not directly accessible.
+Indeed, direct, compiled in, references to their functions would be dangerous
+since they would exist even before (if ever) the module is loaded.
+Each module contains a function named <i>init</i>. Its handle is obtained by
+the main program using g_module_symbol and is called.
+The <i>init</i> function of the module 
+then calls everything it needs from the main program or from libraries,
+typically registering callbacks in hooks lists stored in the global attributes.
+No module function other than <i>init</i> is 
+directly called. Modules cannot see the functions from other modules since
+they may or not be loaded at the same time.
+
+<P>The modules must see the declarations for the functions
+used, from the main program and from libraries, by including the associated 
+.h files. The list of libraries used must be provided as argument when
+a module is linked. This will insure that these libraries get loaded
+automatically when that module is loaded.
+
+<P>Libraries contain a number of functions available to modules and to the main
+program. They are loaded automatically at start time if linked by the main
+program or at module load time if linked by that module. Libraries are
+useful to contain functions needed by several modules. Indeed, functions
+used by a single module could be simply part of that module.
+
+<P>A list of loaded modules is maintained. When a module is requested, it
+is verified if the module is already loaded. A module may request other modules
+at the beginning of its init function. This will insure that these modules
+get loaded and initialized before the init function of the current module
+proceeds. Circular dependencies are obviously to be avoided as the 
+initialization order among mutually dependent modules will be arbitrary.
+
+<H3>Command line options: option.h (option.c)</H3>
+
+<P>Command line options are added as needed by the main program and by modules
+as they are loaded. Thus, while options are scanned and acted upon (i.e.,
+options to load modules), the
+list of options to recognize continues to grow. The options module registers
+to get called by /hooks/main/before. It offers hooks /hooks/option/before
+and /hooks/option/after which are called just before and just after
+processing the options. Many modules register in their init function to
+be called in /hooks/options/after to verify the options specified and
+register further hooks accordingly.
+
+<H2>Trace Analysis</H2>
+
+<P>The main purpose of the lttv application is to process trace sets,
+calling registered hooks for each event in the traces and maintaining
+a context (system state, accumulated statistics).
+
+<H3>Trace Sets: traceSet.h (traceSet.c)</H3>
+
+<P>Trace sets are defined such that several traces can be analyzed together.
+Traces may be added and removed as needed to a trace set.
+The main program stores a trace set in /trace_set/default.
+The content of the trace_set is defined by command line options and it is
+used by analysis modules (batch or interactive).
+
+<H3>Trace Set Analysis: processTrace.h (processTrace.c)</H3>
+
+<p>The function <i>lttv_process_trace_set</i> loops over all the events
+in the specified trace set for the specified time interval. <I>Before</I> 
+Hooks are first
+called for the trace set and for each trace and tracefile 
+(one per cpu plus control tracefiles) in the trace set.
+Then hooks are called for
+each event in sorted time order. Finally, <i>after</i> hooks are called
+for the trace set and for each trace and tracefile in it. 
+
+<P>To call all the event hooks in sorted time order, a priority queue
+(or sorted tree) is used. The first event from each tracefile is read and its
+time used as key in the sorted tree. The event with the lowest key is removed
+from the tree, the next event from that tracefile is read and reinserted in
+the tree. 
+
+<p>Each hook is called with a LttvContext gobject as call data. The LttvContext
+object for the trace set before/after hooks is provided in the call to
+lttv_process_trace_set. Shallow copies of this context are made for each
+trace in the trace set for the trace before/after hooks. Again, shallow
+copies of each trace context are made for each tracefile in a trace.
+The context for each tracefile is used both for the tracefile before/after
+hooks and when calling the hooks for the contained events.
+
+<p>The lttv_process_trace_set function sets appropriately the fields in the
+context before calling a hook. For example, when calling a hook event,
+the context contains:
+
+<DL>
+<DT>trace_set_context<DD> context for the trace set.
+<DT>trace_context<DD> context for the trace.
+<DT>ts<DD> trace set.
+<DT>t<DD> trace.
+<DT>tf<DD> tracefile.
+<DT>e<DD> event.
+</DL>
+
+<P>The cost of providing all this information in the context is relatively
+low. When calling a hook from one event to the next, in the same tracefile,
+only the event field needs to be changed.
+The contexts used when processing traces are key to extensibility and
+performance. New modules may need additional data members in the context to
+store intermediate results. For this purpose, it is possible to derive
+subtypes of LttvContext in order to add new data members.
+
+
+<H3>Reconstructing the system state from the trace: state.h (state.c)</H3>
+
+<P>The events in a trace often represent state transitions in the traced
+system. When the trace is processed, and events accessed in time sorted
+order, it is thus possible to reconstruct in part the state of the 
+traced system: state of each CPU, process, disk queue. The state of each
+process may contain detailed information such as opened file descriptors
+and memory map if needed by the analysis and if sufficient information is
+available in the trace. This incrementally updated state information may be
+used to display state graphs, or simply to compute state dependent
+statistics (time spent in user or system mode, waiting for a file...).
+
+<P>
+When tracing starts, at T0, no state is available. The OS state may be
+obtained through "initial state" events which enumerate the important OS data
+structures.  Unless the state is obtained atomically, other events
+describing state changes may be interleaved in the trace and must be
+processed in the correct order.  Once all the special initial state
+events are obtained, at Ts, the complete state is available. From there the
+system state can be deduced incrementally from the events in the trace.
+
+<P>
+Analysis tools must be prepared for missing state information. In some cases
+only a subset of events is traced, in others the trace may be truncated
+in <i>flight recorder</i> mode.
+
+<P>
+In interactive processing, the interval for which processing is required 
+varies. After scrolling a viewer, the events in the new interval to display
+need to be processed in order to redraw the view. To avoid restarting
+the processing at the trace start to reconstruct incrementally the system
+state, the computed state may be memorized at regular interval, for example at
+each 100 000 events, in a time indexed database associated with a trace.
+To conserve space, it may be possible in some cases to only store state 
+differences. 
+
+<p>To process a specific time interval, the state at the beginning of the
+interval would be obtained by copying the last preceeding saved state
+and processing the events since then to update the state.
+
+<p>A new subtype of LttvContext, LttvStateContext, is defined to add storage
+for the state information. It defines a trace set state as a set of trace
+state. The trace state is composed of processes, CPUs and block devices.
+Each CPU has a currently executing process and each process state keeps
+track the interrupt stack frames (faults, interrupts,
+system calls), executable file name and other information such as opened
+file descriptors. Each frame stores the process status, entry time
+and last status change time.
+
+<p>File state.c provides state updating hooks to be called when the trace is
+processed. When a scheduling change event is delivered to the hook, for
+instance, the current process for the CPU is changed and the state of the
+incoming and outgoing processes is changed.
+The state updating hooks are stored in the global attributes under 
+/hooks/state/core/trace_set/before, after, 
+/hooks/state/core/trace/before, after...
+to be used by processing functions requiring state updating (batch and 
+interactive alalysis, computing the state at time T by updating a preceeding
+saved state...).
+
+<H3>Computing Statistics: stats.h (stats.c)</H3>
+
+<p>This file defines a subtype of LttvStateContext, LttvStatsContext,
+to store statistics on various aspects of a trace set. The LttvTraceSetStats
+structure contains a set of LttvTraceStats structures. Each such structure
+contains structures for CPUs, processes, interrupt types (IRQ, system call,
+fault), subtypes (individual system calls, IRQs or faults) and
+block devices. The CPUs also contain structures for processes, interrupt types,
+subtypes and block devices. Process structures similarly contain
+structures for interrupt types, subtypes and block devices. At each level
+(trace set, trace, cpu, process, interrupt stack frames)
+attributes are used to store statistics. 
+
+<p>File stats.c provides statistics computing hooks to be called when the
+trace is processed. For example, when a <i>write</i> event is processed, 
+the attribute <i>BytesWritten</i> in the corresponding system, cpu, process,
+interrupt type (e.g. system call) and subtype (e.g. write) is incremented 
+by the number of bytes stored in the event. When the processing is finished, 
+perhaps in the after hooks, the number of bytes written and other statistics 
+may be summed over all CPUs for a given process, over all processes for a 
+given CPU or over all traces.
+
+<p>The basic set of statistics computed by stats.c include for the whole
+   trace set:
+
+<UL>
+<LI>Trace start time, end time and duration.
+<LI>Total number of events.
+<LI>Number of each event type (Interrupts, faults, system calls...)
+<LI>For each interrupt type and each subtype, the number of each event type.
+<LI>For each system:
+  <UL>
+  <LI>Total number of events.
+  <LI>Number of each event type (Interrupts, faults, system calls...)
+  <LI>For each interrupt type and each subtype, the number of each event type.
+  <LI>For each CPU:
+    <UL>
+    <LI> CPU id
+    <LI> User/System time
+    <LI> Number of each event type
+    <LI> For each interrupt type and each subtype, 
+         the number of each event type.
+    </UL>
+  <LI>For each block device:
+    <UL>
+    <LI> block device name
+    <LI> time busy/idle, average queue length
+    <LI> Number of each relevant event type (requests added, merged, served)
+    </UL>
+  <LI>For each process:
+    <UL>
+    <LI> Exec'ed file names.
+    <LI> Start and end time, User/System time
+    <LI> Number of each event type
+    <LI> For each interrupt type and each subtype, 
+         the number of each event type.
+    </UL>
+  </UL>
+</UL>
+
+<P>The structure to store statistics differs from the state storage structure
+in several ways. Statistics are maintained in different ways (per CPU all
+processes, per process all CPUs, per process on a given CPU...). Furthermore,
+statistics are maintained for all processes which existed during the trace
+while the state at time T only stores information about current processes.
+
+<P>The hooks defined by stats.c are stored in the global attributes under
+/hooks/stats/core/trace_set/before, after, 
+/hooks/stats/core/trace/before, after to be used by processing functions
+interested in statistics.
+
+<H3>Filtering events: filter.h (filter.c)</H3>
+
+<P>
+Filters are used to select which events in a trace are shown in a viewer or are
+used in a computation. The filtering rules are based on the values of 
+events fields. The filter module receives a filter expression and computes
+a compiled filter. The compiled filter then serves as hook data for 
+<i>check</i> event 
+filter hooks which, given a context containing an event, 
+return TRUE or FALSE to 
+indicate if the event satisfies the filter. Trace and tracefile <i>check</i>
+filter hooks
+may be used to determine if a system and CPU satisfy the filter. Finally,
+the filter module has a function to return the time bounds, if any, imposed
+by a filter.
+
+<P>For some applications, the hooks provided by the filter module may not 
+be sufficient, since they are based on simple boolean combinations
+of comparisons between fields and constants. In that case, custom code may be
+used for <i>check</i> hooks during the processing. An example of complex
+filtering could be to only show events belonging to processes which consumed
+more than 10% of the CPU in the last 10 seconds.
+
+<p>In module filter.c, filters are specified using textual expressions 
+with AND, OR, NOT operations on
+nested subexpressions. Primitive expressions compare an event field to
+a constant. In the graphical user interface, a filter editor is provided.
+
+<PRE><TT>
+tokens: ( ! && || == <= >= > < != name [ ] int float string )
+
+expression = ( expression ) OR ! expression OR
+     expression && expression OR expression || expression OR 
+     simple_expression
+
+simple_expression = field_selector OP value
+
+value = int OR float OR string OR enum
+
+field_selector = component OR component . field_selector
+
+component = name OR name [ int ]
+</TT></PRE>
+
+
+<H3>Batch Analysis: batchAnalysis.h (batchAnalysis.c)</H3>
+
+<p>This module registers to be called by the main program (/hooks/main/core). 
+When called, it gets the current trace set (/trace_set/default), 
+state updating hooks (/hooks/state/*) the statistics hooks 
+(/hooks/stats/*) and other analysis hooks (/hooks/batch/*)
+and runs lttv_process_trace_set for the entire
+trace set time interval. This simple processing of the complete trace set
+is normally sufficient for batch operations such as converting a trace to
+text and computing various statistics.
+
+
+<H3>Text output for events and statistics: textDump.h (textDump.c)</H3>
+
+<P>
+This module registers hooks (/hooks/batch)
+to print a textual representation of each event
+(event hooks) and to print the content of the statistics accumulated in the
+context (after trace set hook).
+
+<H2>Trace Set Viewers</H2>
+
+<p>
+A library, libgtklttv, is defined to provide utility functions for 
+the second set of modules, wich compose the interactive graphical user 
+interface. It offers functions to create and interact with top level trace 
+viewing windows, and to insert specialized embedded viewer modules. 
+The libgtklttv library requires the gtk library.
+The viewer modules include a detailed event list, eventsTableView,
+a process state graph, processStateView, and a CPU state graph, cpuStateView.
+
+<p>
+The top level gtkTraceSet, defined in libgtklttv, 
+window has the usual FILE EDIT... menu and a toolbar.
+It has an associated trace set (and filter) and contains several tabs, each
+containing several vertically stacked time synchronized trace set viewers.
+It manages the space allocated to each contained viewer, the menu items and
+tools registered by each contained viewer and the current time and current
+time interval.
+
+<P>
+When viewers change the current time or time interval, the gtkTraceSet
+window notifies all contained viewers. When one or more viewers need
+redrawing, the gtkTraceSet window calls the lttv_process_trace_set
+function for the needed time interval, after computing the system state
+for the interval start time. While events are processed, drawing hooks 
+from the viewers are called.
+
+<P>
+TO COMPLETE; description and motivation for the gtkTraceSet widget structure
+and interaction with viewers. Description and motivation for the detailed
+event view and process state view.
+
+</BODY>
+</HTML>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttvwindow_events_delivery.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/lttvwindow_events_delivery.txt
new file mode 100644 (file)
index 0000000..c52b6a3
--- /dev/null
@@ -0,0 +1,427 @@
+Linux Trace Toolkit
+
+Mathieu Desnoyers 17-05-2004
+
+
+This document explains how the lttvwindow API could process the event requests
+of the viewers, merging event requests and hook lists to benefit from the fact
+that process_traceset can call multiple hooks for the same event.
+
+First, we will explain the detailed process of event delivery in the current
+framework. We will then study its strengths and weaknesses.
+
+In a second time, a framework where the events requests are dealt by the main
+window with fine granularity will be described. We will then discussed the
+advantages and inconvenients over the first framework.
+
+
+1. (Actual) Boundaryless event reading
+
+Actually, viewers request events in a time interval from the main window. They
+also specify a (not so) maximum number of events to be delivered. In fact, the
+number of events to read only gives a stop point, from where only events with
+the same timestamp will be delivered.
+
+Viewers register hooks themselves in the traceset context. When merging read
+requests in the main window, all hooks registered by viewers will be called for
+the union of all the read requests, because the main window has no control on
+hook registration.
+
+The main window calls process_traceset on its own for all the intervals
+requested by all the viewers. It must not duplicate a read of the same time
+interval : it could be very hard to filter by viewers. So, in order to achieve
+this, time requests are sorted by start time, and process_traceset is called for
+each time request. We keep the last event time between each read : if the start
+time of the next read is lower than the time reached, we continue the reading
+from the actual position.
+
+We deal with specific number of events requests (infinite end time) by
+garantying that, starting from the time start of the request, at least that
+number of events will be read. As we can't do it efficiently without interacting
+very closely with process_traceset, we always read the specified number of
+events requested starting from the current position when we answer to a request
+based on the number of events.
+
+The viewers have to filter events delivered by traceset reading, because they
+can be asked by another viewer for a totally (or partially) different time
+interval.
+
+
+Weaknesses
+
+- process_middle does not guarantee the number of events read
+
+First of all, a viewer that requests events to process_traceset has no garantee
+that it will get exactly what it asked for. For example, a direct call to
+traceset_middle for a specific number of events will delived _at least_ that
+quantity of events, plus the ones that have the same timestamp that the last one
+has.
+
+- Border effects
+
+Viewer's writers will have to deal with a lot of border effects caused by the
+particularities of the reading. They will be required to select the information
+they need from their input by filtering.
+
+- Lack of encapsulation and difficulty of testing
+
+The viewer's writer will have to take into account all the border effects caused
+by the interaction with other modules. This means that event if a viewer works
+well alone or with another viewer, it's possible that new bugs arises when a new
+viewer comes around. So, even if a perfect testbench works well for a viewer, it
+does not confirm that no new bug will arise when another viewer is loaded at the
+same moment asking for different time intervals.
+
+
+- Duplication of the work
+
+Time based filters and counters of events will have to be implemented at the
+viewer's side, which is a duplication of the functionnalities that would
+normally be expected from the tracecontext API.
+
+- Lack of control over the data input
+
+As we expect module's writers to prefer to be as close as possible from the raw
+datas, making them interact with a lower level library that gives them a data
+input that they only control by further filtering of the input is not
+appropriated. We should expect some reluctancy from them about using this API
+because of this lack of control on the input.
+
+- Speed cost
+
+All hooks of all viewers will be called for all the time intervals. So, if we
+have a detailed events list and a control flow view, asking both for different
+time intervals, the detailed events list will have to filter all the events
+delivered originally to the control flow view. This can be a case occuring quite
+often.
+
+
+
+Strengths
+
+- Simple concatenation of time intervals at the main window level.
+
+Having the opportunity of delivering more events than necessary to the viewers
+means that we can concatenate time intervals and number of events requested
+fairly easily, while being hard to determine if some specific cases will be
+wrong, in depth testing being impossible.
+
+- No duplication of the tracecontext API
+
+Viewers deal directly with the tracecontext API for registering hooks, removing
+a layer of encapsulation.
+
+
+
+
+
+2. (Proposed) Strict boundaries events reading
+
+The idea behind this method is to provide exactly the events requested by the
+viewers to them, no more, no less.
+
+It uses the new API for process traceset suggested in the document
+process_traceset_strict_boundaries.txt.
+
+It also means that the lttvwindow API will have to deal with viewer's hooks.
+Those will not be allowed to add them directly in the context. They will give
+them to the lttvwindow API, along with the time interval or the position and
+number of events. The lttvwindow API will have to take care of adding and
+removing hooks for the different time intervals requested. That means that hooks
+insertion and removal will be done between each traceset processing based on
+the time intervals and event positions related to each hook. We must therefore
+provide a simple interface for hooks passing between the viewers and the main
+window, making them easier to manage from the main window. A modification to the
+LttvHooks type solves this problem.
+
+
+Architecture
+
+Added to the lttvwindow API :
+
+
+void lttvwindow_events_request
+( Tab                  *tab,
+  const EventsRequest  *events_request);
+
+void lttvwindow_events_request_remove_all
+( Tab                *tab,
+  gconstpointer       viewer);
+
+
+Internal functions :
+
+- lttvwindow_process_pending_requests
+
+
+Events Requests Removal
+
+A new API function will be necessary to let viewers remove all event requests
+they have made previously. By allowing this, no more out of bound requests will
+be serviced : a viewer that sees its time interval changed before the first
+servicing is completed can clear its previous events requests and make a new
+one for the new interval needed, considering the finished chunks as completed
+area.
+
+It is also very useful for dealing with the viewer destruction case : the viewer
+just has to remove its events requests from the main window before it gets
+destroyed.
+
+
+Permitted GTK Events Between Chunks
+
+All GTK Events will be enabled between chunks. A viewer could ask for a
+long computation that has no impact on the display : in that case, it is
+necessary to keep the graphical interface active. While a processing is in
+progress, the whole graphical interface must be enabled.
+
+We needed to deal with the coherence of background processing and diverse GTK
+events anyway. This algorithm provides a generalized way to deal with any type
+of request and any GTK events.
+
+
+Background Computation Request
+
+A background computation has a trace scope, and is therefore not linked to a
+main window. It is not detailed in this document. 
+see requests_servicing_schedulers.txt
+
+A New "Redraw" Button
+
+It will be used to redraw the viewers entirely. It is useful to restart the
+servicing after a "stop" action.
+
+A New "Continue" Button
+
+It will tell the viewers to send requests for damaged areas. It is useful to
+complete the servicing after a "stop" action.
+
+
+
+Tab change
+
+If a tab change occurs, we still want to do background processing.
+Events requests must be stocked in a list located in the same scope than the
+traceset context. Right now, this is tab scope. All functions called from the
+request servicing function must _not_ use the current_tab concept, as it may
+change. The idle function must the take a tab, and not the main window, as
+parameter.
+
+If a tab is removed, its associated idle events requests servicing function must
+also be removed.
+
+It now looks a lot more useful to give a Tab* to the viewer instead of a
+MainWindow*, as all the information needed by the viewer is located at the tab
+level. It will diminish the dependance upon the current tab concept.
+
+
+
+Idle function (lttvwindow_process_pending_requests)
+
+The idle function must return FALSE to be removed from the idle functions when
+no more events requests are pending. Otherwise, it returns TRUE. It will service
+requests until there is no more request left.
+
+
+
+Implementation
+
+
+- Type LttvHooks
+
+see hook_prio.txt
+
+The viewers will just have to pass hooks to the main window through this type,
+using the hook.h interface to manipulate it. Then, the main window will add
+them and remove them from the context to deliver exactly the events requested by
+each viewer through process traceset.
+
+
+- lttvwindow_events_request
+
+It adds the an EventsRequest struct to the list of events requests
+pending and registers a pending request for the next g_idle if none is
+registered. The viewer can access this structure during the read as its
+hook_data. Only the stop_flag can be changed by the viewer through the
+event hooks.
+
+typedef struct _EventsRequest {
+  gpointer                     owner;           /* Owner of the request     */
+  gpointer                     viewer_data;     /* Unset : NULL             */
+  gboolean                     servicing;       /* service in progress: TRUE */ 
+  LttTime                      start_time;/* Unset : { G_MAXUINT, G_MAXUINT }*/
+  LttvTracesetContextPosition *start_position;  /* Unset : NULL             */
+  gboolean                     stop_flag;       /* Continue:TRUE Stop:FALSE */
+  LttTime                      end_time;/* Unset : { G_MAXUINT, G_MAXUINT } */
+  guint                        num_events;      /* Unset : G_MAXUINT        */
+  LttvTracesetContextPosition *end_position;    /* Unset : NULL             */
+  LttvHooks                   *before_chunk_traceset; /* Unset : NULL       */
+  LttvHooks                   *before_chunk_trace;    /* Unset : NULL       */
+  LttvHooks                   *before_chunk_tracefile;/* Unset : NULL       */
+  LttvHooks                   *event;           /* Unset : NULL             */
+  LttvHooksById               *event_by_id;     /* Unset : NULL             */
+  LttvHooks                   *after_chunk_tracefile; /* Unset : NULL       */
+  LttvHooks                   *after_chunk_trace;     /* Unset : NULL       */
+  LttvHooks                   *after_chunk_traceset;  /* Unset : NULL       */
+  LttvHooks                   *before_request;  /* Unset : NULL             */
+  LttvHooks                   *after_request;   /* Unset : NULL             */
+} EventsRequest;
+
+
+- lttvwindow_events_request_remove_all
+
+It removes all the events requests from the pool that has their "owner" field
+maching the owner pointer given as argument.
+
+It calls the traceset/trace/tracefile end hooks for each request removed if
+they are currently serviced.
+
+
+- lttvwindow_process_pending_requests
+
+This internal function gets called by g_idle, taking care of the pending
+requests. It is responsible for concatenation of time intervals and position
+requests. It does it with the following algorithm organizing process traceset
+calls. Here is the detailed description of the way it works :
+
+
+
+- Revised Events Requests Servicing Algorithm (v2)
+
+The reads are splitted in chunks. After a chunk is over, we want to check if
+there is a GTK Event pending and execute it. It can add or remove events 
+requests from the event requests list. If it happens, we want to start over
+the algorithm from the beginning. The after traceset/trace/tracefile hooks are
+called after each chunk, and before traceset/trace/tracefile are
+called when the request processing resumes. Before and after request hooks are
+called respectively before and after the request processing.
+
+
+Data structures necessary :
+
+List of requests added to context : list_in
+List of requests not added to context : list_out
+
+Initial state :
+
+list_in : empty
+list_out : many events requests
+
+
+0.1 Lock the traces
+0.2 Seek traces positions to current context position.
+
+A. While (list_in !empty or list_out !empty)
+  1. If list_in is empty (need a seek)
+    1.1 Add requests to list_in
+      1.1.1 Find all time requests with lowest start time in list_out (ltime)
+      1.1.2 Find all position requests with lowest position in list_out (lpos)
+      1.1.3 If lpos.start time < ltime
+        - Add lpos to list_in, remove them from list_out
+      1.1.4 Else, (lpos.start time >= ltime)
+        - Add ltime to list_in, remove them from list_out
+    1.2 Seek
+      1.2.1 If first request in list_in is a time request
+        - If first req in list_in start time != current time
+          - Seek to that time
+      1.2.2 Else, the first request in list_in is a position request
+        - If first req in list_in pos != current pos
+          - seek to that position
+    1.3 Add hooks and call before request for all list_in members
+      1.3.1 If !servicing
+          - begin request hooks called
+          - servicing = TRUE
+      1.3.2 call before chunk
+      1.3.3 events hooks added
+  2. Else, list_in is not empty, we continue a read
+    2.0 For each req of list_in
+      - Call before chunk
+      - events hooks added
+    2.1 For each req of list_out
+    - if req.start time == current context time
+              or req.start position == current position
+      - Add to list_in, remove from list_out
+      - If !servicing
+        - Call before request
+        - servicing = TRUE
+      - Call before chunk
+      - events hooks added
+
+  3. Find end criterions
+    3.1 End time
+      3.1.1 Find lowest end time in list_in
+      3.1.2 Find lowest start time in list_out (>= than current time*)
+                                * To eliminate lower prio requests (not used)
+      3.1.3 Use lowest of both as end time
+    3.2 Number of events
+      3.2.1 Find lowest number of events in list_in
+      3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as num_events
+    3.3 End position
+      3.3.1 Find lowest end position in list_in
+      3.3.2 Find lowest start position in list_out (>= than current
+                                                    position *not used)
+      3.3.3 Use lowest of both as end position
+
+  4. Call process traceset middle
+    4.1 Call process traceset middle (Use end criterion found in 3)
+      * note : end criterion can also be viewer's hook returning TRUE
+  5. After process traceset middle
+    - if current context time > traceset.end time
+      - For each req in list_in
+        - Remove events hooks for req
+        - Call end chunk for req
+        - Call end request for req
+        - remove req from list_in
+    5.1 For each req in list_in
+          - Call end chunk for req
+          - Remove events hooks for req
+          - req.num -= count
+          - if   req.num == 0
+               or
+                 current context time >= req.end time
+               or
+                 req.end pos == current pos
+               or
+                 req.stop_flag == TRUE
+            - Call end request for req
+            - remove req from list_in
+  If GTK Event pending : break A loop
+
+B. When interrupted between chunks
+  1. for each request in list_in
+    1.1. Use current postition as start position
+    1.2. Remove start time
+    1.3. Move from list_in to list_out
+
+C. Unlock the traces
+
+
+
+Notes :
+End criterions for process traceset middle :
+If the criterion is reached, event is out of boundaries and we return.
+Current time >= End time
+Event count > Number of events
+Current position >= End position
+Last hook list called returned TRUE
+
+The >= for position is necessary to make ensure consistency between start time
+requests and positions requests that happens to be at the exact same start time
+and position.
+
+
+
+
+Weaknesses
+
+- ?
+
+Strengths
+
+- Removes the need for filtering of information supplied to the viewers.
+
+- Viewers have a better control on their data input.
+
+- Solves all the weaknesses idenfied in the actual boundaryless traceset
+reading.
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/process_traceset_strict_boundaries.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/process_traceset_strict_boundaries.txt
new file mode 100644 (file)
index 0000000..858ee57
--- /dev/null
@@ -0,0 +1,184 @@
+Linux Trace Toolkit
+
+Mathieu Desnoyers 17-05-2004
+
+
+1. Read Requests Cases Study
+
+The goal of this document is to describe the typical behavior of viewers when
+they request data to a process traceset. After the implementation of three
+viewers, with different needs, the idea of their need for a trace processing API
+is getting clearer. We then describe a new API for process traceset that would
+better suits the needs of those viewers.
+
+They are splitted in two different categories : the first one is the one where
+the viewers select the events they need by specifying a time interval in the
+traceset and the second one is where the viewers specify a start event by its
+position in the traceset and a certain amount of events it needs.
+
+This is a simplified case study : we look at the direct interaction between
+graphical viewers and process traceset, without the main window as a negociator.
+
+Control Flow Viewer
+
+This viewer, consisting in a two dimensions graph, shows the different processes
+as its y axis and the time as x axis. It's clear that it needs to get the events
+by specifying a start time and an end time, constituing a time interval.
+
+
+Detailed Events List
+
+This list has nothing to do with time : it shows the events one by one. It cares
+about the quantity of events, not their time.
+
+It would be simple to get the events one by one if we were reading only one
+tracefile (one cpu), but the way events are read through each trace
+(monothically increasing time) makes it a little bit more difficult to specify
+how to increment event position. We will determine how it could be done simply.
+
+Let's define an event position. It's a pointer to a position into each
+tracefile. It's only meaningful when associated with a context. Comparisons
+between positions are done by looking comparing saved positions for each
+tracefile, until a difference is found.
+
+A viewer could use a start time as a start event. It would specify a number of
+events it needs. As a first call, it could ask for the start time of the
+traceset. Afterward, it can save the position of the context after the last
+event has been delivered in its after traceset function.
+
+Now, let's see how process traceset could handle it. It would seek in the
+traceset, searching the position number.
+(need a new lttv_process_traceset_seek_position)
+
+Then, the viewer could simply call a process traceset middle function
+specifying a number of events to get.
+
+The whole concept of numbering events would be hidden in the order in which the
+process traceset gets the events in a monothically increasing time.
+
+
+
+2. Architecture
+
+API to seek/read traceset will be extended to fully support both start time,
+start position, end time, end position and number of events as possible
+boundaries for reading.
+
+lttv_process_traceset_seek_time
+lttv_process_traceset_seek_position
+
+lttv_process_traceset_middle
+
+It must be modified to end when it encounters the first criterion : number of
+events to read reached, end time reached, end position reached.
+
+lttv_traceset_context_position_save
+
+The position_save saves a position that can be used later to seek back to this
+exact same position, with event granularity. This implies that the
+process_traceset must deliver events with the same timestamp in a deterministic
+manner. This is actually done by using tracefile and trace numbers in the
+context in the comparison function.
+
+
+
+Description of new context API useage
+
+1. seek
+2. begin  -> add middle hooks
+          -> call begin hooks by id
+3. middle -> call middle hooks by id
+4. end    -> call end hooks by id
+          -> remove middle hooks
+
+3. Impact on State
+
+From now on, the state computation will be done in the middle hook call, with a
+priority higher than default. We will define this priority as PRIO_STATE,
+defined to 25.
+
+If state has to be computed, lttv_process_traceset_begin has to be  called in
+a first time. It adds the state hooks to the context. Then, the state
+seek_closest will have to be used to restore the nearest state, plus a
+process_traceset with no hooks present other than the state hooks will have to
+be called to go from the closest state to the real time seeked.
+
+The lttv_process_traceset_end will only need to be called if no further state
+computation is needed.
+
+
+4. Implementation in tracecontext.c
+
+
+- Type LttvTracesetContextPosition
+
+struct _LttvTraceContextPosition {
+  LttEventPosition *tf_pos;          /* Position in each trace           */
+  guint nb_tracefile;                /* Number of tracefiles (check)     */
+}
+
+struct _LttvTracesetContextPosition {
+  LttTraceContextPosition *t_pos;    /* Position in each trace           */
+  guint nb_trace;                    /* Number of traces (check)         */
+}
+
+with interfaces :
+
+lttv_traceset_context_position_save
+(const LttvTracesetContext *context,
+ LttvTracesetContextPosition *pos);
+
+
+Dependencies :
+
+- lttv_process_traceset_seek_position(LttvTracesetContext *self,
+                                const LttvTracesetContextPosition *position);
+    - ltt_tracefile_seek_position : already implemented
+
+lttv_process_traceset_seek_position will seek each tracefile to the right
+position. We keep information about number of tracefiles for extra integrity
+checking when reloading the position in the context. It also loads the pqueue.
+
+
+
+- lttv_process_traceset_middle
+We modify lttv_process_traceset_middle so that it takes as arguments :
+(LttvTracesetContext *self,
+LttTime end,
+unsigned nb_events,
+const LttvTracesetContextPosition *end_position)
+
+This new version of process traceset middle will call the event hooks for
+events until the first criterion is fulfilled : either the end time is reached,
+the number of events requested is passed, the end position is reached or the
+last event hook list called returned TRUE. When this function ends, the end
+position can be extracted from the context, the end event is set as described
+below and the number of events read is returned.
+
+The end event is a pointer to the last event the hooks has been called for.
+
+- lttv_process_traceset_seek_time : already implemented
+  - now loads the pqueue.
+
+- lttv_process_traceset_begin(LttvTracesetContext *self,
+                              LttvHooks       *before_traceset,
+                              LttvHooks       *before_trace,
+                              LttvHooks       *before_tracefile,
+                              LttvHooks       *event,
+                              LttvHooksById   *event_by_id)
+
+
+- lttv_process_traceset_end(LttvTracesetContext *self,
+                            LttvHooks           *after_traceset,
+                            LttvHooks           *after_trace,
+                            LttvHooks           *after_tracefile,
+                            LttvHooks           *event,
+                            LttvHooksById       *event_by_id)
+
+- lttv_traceset_context_add_hooks and lttv_traceset_context_remove_hooks
+
+These functions now become internal to tracecontext.c
+
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/program-header.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/program-header.txt
new file mode 100644 (file)
index 0000000..ccf9969
--- /dev/null
@@ -0,0 +1,17 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Your Name
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/requests_servicing_schedulers.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/requests_servicing_schedulers.txt
new file mode 100644 (file)
index 0000000..beaca69
--- /dev/null
@@ -0,0 +1,324 @@
+Linux Trace Toolkit
+
+Requests Servicing Schedulers
+
+
+Mathieu Desnoyers, 07/06/2004
+
+
+In the LTT graphical interface, two main types of events requests may occur :
+
+- events requests made by a viewer concerning a traceset for a ad hoc
+  computation.
+- events requests made by a viewer concerning a trace for a precomputation.
+
+
+Ad Hoc Computation
+
+The ad hoc computation must be serviced immediately : they are directly
+responding to events requests that must be serviced to complete the graphical
+widgets'data. This kind of computation may lead to incomplete result as long as
+precomputation are not finished. Once precomputation is over, the widgets will
+be redrawn if they needed such information. A ad hoc computation is done on a
+traceset : the workspace of a tab.
+
+Precomputation 
+
+Traces are global objects. Only one instance of a trace is opened for all the
+program. Precomputation will append data to the traces attributes (states,
+statistics). It must inform the widgets which asked for such states or
+statistics of their availability. Only one precomputation must be launched for
+each trace and no duplication of precomputation must be done.
+
+
+Schedulers
+
+There is one tracesetcontext per traceset. Each reference to a trace by a
+traceset also has its own tracecontext. Each trace, by itself, has its own
+tracecontext.
+
+Let's define a scheduler as a g_idle events request servicing function.
+
+There is one scheduler per traceset context (registered when there are requests
+to answer). There is also one scheduler per autonomous trace context (not
+related to any traceset context).
+
+A scheduler processes requests for a specific traceset or trace by combining
+time intervals of the requests. It is interruptible by any GTK event. A
+precomputation scheduler has a lower priority than a ad hoc computation
+scheduler. That means that no precomputation will be performed until there is
+no more ad hoc compuation pending. When a scheduler is interrupted, it makes no
+assumption about the presence or absence of the current requests in its pool
+when it starts back.
+
+
+Foreground Scheduler
+
+There can be one foreground scheduler per traceset (one traceset per tab). It
+simply calls the hooks given by the events requests of the viewers for the
+specified time intervals.
+
+
+Background Scheduler
+
+Right now, to simplify the problem of the background scheduler, we assume that
+the module that loads the extended statistics hooks has been loaded before the
+data is requested and that it is not unloaded until the program stops. We will
+eventually have to deal with the requests removal based on module load/unload,
+but it complicates the problem quite a bit.
+
+A background scheduler adds hooks located under a global attributes path
+(specified by the viewer who makes the request) to the trace's traceset
+context (the trace is specified by the viewer). Then, it processes the whole
+trace with this context (and hooks).
+
+Typically, a module that extends statistics will register hooks in the global
+attributes tree under /computation/modulename/hook_name . A viewer
+that needs these statistics for a set of traces does a background computation
+request through a call to the main window API function. It must specify all
+types of hooks that must be called for the specified trace.
+
+The background computation requests for a trace are queued. When the idle
+function kicks in to answer these requests, it add the hooks of all the requests
+toghether in the context and starts the read. It also keeps a list of the
+background requests currently serviced.
+
+The read is done from start to end of the trace, calling all the hooks present
+in the context. Only when the read is over, the after_request hooks of the
+currently serviced requests are called and the requests are destroyed.
+
+If there are requests in the waiting queue, they are all added to the current
+pool and processed. It is important to understand that, while a processing is in
+being done, no requests are added to the pool : they wait for their turn in the
+queue.
+
+Every hook that are added to the context by the scheduler comes from global
+attributes, i.e.
+/traces/#
+    in LttvTrace attributes : modulename/hook_name
+
+They come with a flag telling either in_progress or ready. If the flag
+ready is set, a viewer knows that the data it needs is already ready and he
+doesn't have to make a request.
+
+If the flag in_progress is set, that means that the data it needs is currently
+being serviced, and it must wait for the current servicing to be finished. It
+tells the lttvwindow API to call a hook when the actual servicing is over (there
+is a special function for this, as it requires to modify the pool of requests
+actually being serviced : we must make sure that no new reading hooks are
+added!).
+
+
+
+
+
+New Global Attributes
+
+/traces/#
+    in LttvTrace attributes :
+
+When a processing is fired, a variable
+                              computation/modulename/in_progress is set.
+
+When a processing finished, a variable
+                              computation/modulename/in_progress is unset
+                              computation/modulename/ready is set
+
+
+
+
+
+Typical Use For a Viewer
+
+When a viewer wants extended information, it must first check if it is ready.
+if not :
+Before a viewer makes a request, it must check the in_progress status of the
+hooks.
+
+If the in_progress is unset, it makes the request.
+
+If the in_progress is set, it makes a special request for being informed of the
+end of request.
+
+
+
+
+Hooks Lists
+
+In order to answer the problems of background processing, we need to add a
+reference counter for each hook of a hook list. If the same hook is added twice,
+it will be called only once, but it will need two "remove" to be really removed
+from the list. Two hooks are identical if they have the same function pointer
+and hook_data.
+
+
+
+
+
+
+Implementation
+
+Ad Hoc Computation
+
+see lttvwindow_events_delivery.txt
+
+
+Hooks Lists
+
+need new ref_count field with each hook
+lttv_hook_add and lttv_hook_add_list must compare addition with present and
+increment ref counter if already present.
+
+lttv_hook_remove and remove_with_data must decrement ref_count is >1, or remove
+the element otherwise (==1).
+
+
+
+Background Scheduler
+
+Global traces
+
+Two global attributes per trace : 
+traces/#
+  It is a pointer to the LttvTrace structure.
+  In the LttvTrace attributes :
+    state/
+      saved_states/
+    statistics/
+      modes/
+      cpu/
+      processes/
+      modulename1/
+      modulename2/
+      ...
+    computation/  /* Trace specific background computation hooks status */
+      state/
+        in_progress
+        ready
+      stats/
+        in_progress
+        ready
+      modulename1/
+        in_progress
+        ready
+    requests_queue/     /* Background computation requests */
+    requests_current/   /* Type : BackgroundRequest */
+    notify_queue/
+    notify_current/
+    computation_traceset/
+    computation_traceset_context/
+
+
+computation/      /* Global background computation hooks */
+  state/
+    before_chunk_traceset
+    before_chunk_trace
+    before_chunk_tracefile
+    after_...
+    before_request
+    after_request
+    event_hook
+    event_hook_by_id
+    hook_adder
+    hook_remover
+  stats/
+    ...
+  modulename1/
+    ...
+
+Hook Adder and Hook remover
+
+Hook functions that takes a trace context as call data. They simply 
+add / remove the computation related hooks from the trace context.
+
+
+
+Modify Traceset
+Points to the global traces. Main window must open a new one only when no
+instance of the pathname exists.
+
+Modify trace opening / close to make them create and destroy
+LttvBackgroundComputation (and call end requests hooks for servicing requests)
+and global trace info when references to the trace is zero.
+
+
+
+EventsRequest Structure
+
+This structure is the element of the events requests pools. The owner field is
+used as an ownership identifier. The viewer field is a pointer to the data
+structure upon which the action applies. Typically, both will be pointers to
+the viewer's data structure.
+
+In a ad hoc events request, a pointer to the EventsRequest structure is used as
+hook_data in the hook lists : it must have been added by the viewers.
+
+
+Modify module load/unload
+
+A module that registers global computation hooks in the global attributes upon
+load should unregister them when unloaded. Also, it must remove every background
+computation request for each trace that has its own module_name as GQuark.
+
+
+Give an API for calculation modules
+
+Must have an API for module which register calculation hooks. Unregistration
+must also remove all requests made for these hooks.
+
+
+Background Requests Servicing Algorithm (v1)
+
+
+list_in : currently serviced requests
+list_out : queue of requests waiting for processing
+
+notification lists :
+notify_in : currently checked notifications
+notify_out : queue of notifications that comes along with next processing.
+
+
+0.1 Lock traces
+0.2 Sync tracefiles
+
+1. Before processing
+  - if list_in is empty
+    - Add all requests in list_out to list_in, empty list_out
+    - for each request in list_in
+      - set hooks'in_progress flag to TRUE
+      - call before request hook
+    - seek trace to start
+    - Move all notifications from notify_out to notify_in.
+  - for each request in list_in
+    - Call before chunk hooks for list_in
+    - add hooks to context *note only one hook of each type added.
+
+2. call process traceset middle for a chunk
+  (assert list_in is not empty! : should not even be called in that case)
+
+3. After the chunk
+  3.1 call after_chunk hooks for list_in
+    - for each request in list_in
+      - Call after chunk hooks for list_in
+      - remove hooks from context *note : only one hook of each type
+  3.2 for each notify_in
+    - if current time >= notify time, call notify and remove from notify_in
+    - if current position >= notify position, call notify and remove from
+      notify_in
+  3.3 if end of trace reached
+    - for each request in list_in
+      - set hooks'in_progress flag to FALSE
+      - set hooks'ready flag to TRUE
+      - call after request hook
+      - remove request
+    - for each notifications in notify_in
+      - call notify and remove from notify_in
+    - reset the context
+    - if list_out is empty
+      return FALSE (scheduler stopped)
+    - else
+      return TRUE (scheduler still registered)
+  3.4 else
+    - return TRUE (scheduler still registered)
+
+4. Unlock traces
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/status.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/status.html
new file mode 100644 (file)
index 0000000..9fc1e4d
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Current status</title>
+</head>
+  <body>
+        
+<h1>Current status</h1>
+        
+<p>
+As of january 28 2004, the Linux Trace Toolkit viewer is nearing feature
+completeness for the first release. A few features need some additional work.
+Thereafter, polishing, stabilizing, and documentation will take place before
+adding new features. It can be considered pre alpha but usable for displaying
+detailed event lists. Furthermore, it may be used to plan the development of
+new modules for the viewer.
+
+The underlying libltt library is fairly stable and mature. It may be considered
+alpha.
+<P>
+
+</body>
+</html>
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/todo.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/developer/todo.html
new file mode 100644 (file)
index 0000000..dca65c4
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Roadmap</title>
+</head>
+  <body>
+        
+<h1>Roadmap</h1>
+        
+<p>
+As of january 28 2004, the short term development plans include the following
+items.
+
+<UL>
+<LI> Add the copyright notices in each program file.
+<LI> Insure that the coding practices are being implemented.
+<LI> Polish the visual appearance: icons for the tabs and buttons,
+     background, lines and labels in the control flow viewer...
+<LI> When a trace is opened, start a background thread to precompute 
+     the system state and memorize it after each ~100 000 events. 
+     Have the option to save the precomputed state when a trace is closed. 
+     Use the precomputed state if available when opening a trace or 
+     seeking in a trace. Use the same thread for computing statistics.
+<LI> Update module.c to ease changing a module into a builtin feature.
+<LI> Split processTrace into tracecontext and processtrace.
+<LI> Insure that g_info logging is generally available but off by default.
+<LI> Document each header file such that developer documentation can
+     be extracted automatically using 
+     <A href="http://www.doxygen.org">Doxygen</A>.
+<LI> Complete the user and developer documentation.
+<LI> Test the viewer on large SMP traces. Insure that 2GB files do not cause
+     crashes. Note and fix unduly long delays. 
+<LI> Add C99 test (declaration of variable inside a function) to configure.in
+
+
+</body>
+</html>
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/Makefile.am
new file mode 100644 (file)
index 0000000..b4d5aab
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = user_guide
+
+EXTRA_DIST = guiEvents.html
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/guiEvents.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/guiEvents.html
new file mode 100644 (file)
index 0000000..4e4af88
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Graphical Event Viewer Plugin User Manual</title>
+</head>
+  <body>
+<h1>Graphical Event Viewer Plugin User Manual</h1>
+
+<P>
+This viewers shows a list of the events that are included in the currently
+viewed time interval. This is a detailed manner of seeing each event's
+information.
+
+<P>
+Showing this viewer is as simple as adding it to the current tab by selecting
+the Insert Event Viewer menu item from the Tools menu or by clicking on
+this viewer's Insertion Button. You can then use up/down arrows buttons and
+delete button when the viewer is selected to change it's position in the
+tab or remove it.
+
+<P>
+It them appears in the current tab. If there are events to display in the
+current time frame selected by the tab, you should already see them in the
+list. You can move the scrollbar on the right side up and down to display
+the different events in the list. As you can see, this list is limited to
+the currently viewed time interval. In order to see more events in this
+list, you can use a Zoom Extended of the main window (this will show all
+the trace's events). You can also specify the laps of time you want to see
+using the main window's Show Time Frame.
+
+<P>
+One important feature of this plugin is the ability to inform the tab in
+which it resides of the currently selected event. By clicking on an event,
+it will appear highlighted in the list and this event will then become the
+current event.
+
+<P>
+The events shown are selected by the filters applied on them. Hence, you can
+configure the viewer's associated filter using various criterias in order
+to select the events you want to show.
+
+<P>
+By clicking on the viewer with the right mouse button, a popup menu appears,
+giving the opportunity to configure the viewer's filter or to configure
+the viewer itself. Configuration of the filter will be explained in another
+document, but event viewer's configuration follows.
+
+<P>
+The viewer's configuration window permits a selection of the fields that
+must be displayed in the event viewer. There are fields which can always be
+selected, as, for example, event type or time of the event, while there are
+fields that are specific to the event types present in the trace. A browse
+list, following the nested architecture of the description of events, will
+show all the available fields on the left. A list at the right side will
+list all the currently selectied fields. Two arrows in the middle of the
+two lists can be used to add or remove a field from the shown fields list.
+
+</BODY>
+</HTML>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/Makefile.am
new file mode 100644 (file)
index 0000000..2f3c623
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = docbook html
+
+EXTRA_DIST = user_guide.dvi
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/Makefile.am
new file mode 100644 (file)
index 0000000..b9df791
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST = lttv-color-list.eps lttv-color-list.png lttv-numbered-5.eps lttv-numbered-5.png user_guide.docbook
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.eps b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.eps
new file mode 100644 (file)
index 0000000..61d480e
--- /dev/null
@@ -0,0 +1,1319 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner
+%%Title: lttv-color-list.ps
+%%CreationDate: Tue Nov 30 21:49:24 2004
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%Pages: 1
+%%BoundingBox: 14 14 468 217
+%%EndComments
+%%BeginProlog
+% Use own dictionary to avoid conflicts
+10 dict begin
+%%EndProlog
+%%Page: 1 1
+% Translate for offset
+14.173228346456693 14.173228346456693 translate
+% Translate to begin of first scanline
+0 201.85508571428571 translate
+452.88 -201.85508571428571 scale
+% Image geometry
+525 234 8
+% Transformation matrix
+[ 525 0 0 234 0 0 ]
+% Strings to hold RGB-samples per scanline
+/rstr 525 string def
+/gstr 525 string def
+/bstr 525 string def
+{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
+true 3
+%%BeginData:        63285 ASCII Bytes
+colorimage
+:rU;g_8*k$^:q:o]Xtee]",>\\$rfR[C!<IZa-j@Yct=6Y-"h-XK/D%WMuhpVl-DhV59u`USFQX
+TqS-PT:_^HSXl:@S"#k8R@0G0Q^@];s-<VKs-*GFs,m;Bs,[/>s,I#:repf6re^W1rJ1B,re:<(
+rIb'#rIOlsqg\HkpjM+KpjN!fqg\NorIOp!rIb'%re:?+reLH.s,$`4repc7s,I#<s,[/@s,m>E
+rfdAHs-<VMrg3YPs-`nUs-s%Ys.01]s.B=as.TIes.fUi!i;ckrhh!>WMuntX/i>'Xfeh1YHY79
+ZEggC['d<M[^WcV\[f;`]=c49s5F!.~>
+:rU;g_8*k$^:q:o]Xtee]",>\\$rfR[C!<IZa-j@Yct=6Y-"h-XK/D%WMuhpVl-DhV59u`USFQX
+TqS-PT:_^HSXl:@S"#k8R@0G0Q^@];s-<VKs-*GFs,m;Bs,[/>s,I#:repf6re^W1rJ1B,re:<(
+rIb'#rIOlsqg\HkpjM+KpjN!fqg\NorIOp!rIb'%re:?+reLH.s,$`4repc7s,I#<s,[/@s,m>E
+rfdAHs-<VMrg3YPs-`nUs-s%Ys.01]s.B=as.TIes.fUi!i;ckrhh!>WMuntX/i>'Xfeh1YHY79
+ZEggC['d<M[^WcV\[f;`]=c49s5F!.~>
+:rU;g_8*k$^:q:o]Xtee]",>\\$rfR[C!<IZa-j@Yct=6Y-"h-XK/D%WMuhpVl-DhV59u`USFQX
+TqS-PT:_^HSXl:@S"#k8R@0G0Q^@];s-<VKs-*GFs,m;Bs,[/>s,I#:repf6re^W1rJ1B,re:<(
+rIb'#rIOlsqg\HkpjM+KpjN!fqg\NorIOp!rIb'%re:?+reLH.s,$`4repc7s,I#<s,[/@s,m>E
+rfdAHs-<VMrg3YPs-`nUs-s%Ys.01]s.B=as.TIes.fUi!i;ckrhh!>WMuntX/i>'Xfeh1YHY79
+ZEggC['d<M[^WcV\[f;`]=c49s5F!.~>
+;STlV]=PSa\@B#V[^EKLZa6sBZ*:I9Y-+n.XK/D%WMuhpVl-DhV50o^US=KVTV.pLSt;LCS=?":
+R[KS2R$X/*Q'ISuPEV/mOcb`eO,o<]rf-r:s,6o7s,$`2s+gW/re:B*re(6&rdk'!s*t#srdF`m
+rd4WjrH\?drHJ0_qfVdXpN,G:pN-4RqfVg[rHJ3brH\Bgrd4TkrdFcps*t#urdk*$re(6(re:B,
+s+gT0s,$c5s,6o9s,I&=rf@)@s,m>E4d2+pQ'IZ$Q^=),R@0M4S"-">SXuFFT:hmOU8"EXUnsob
+VPg>jWMuntX/rD)Xfek2YctC<ZEppF[C*o's5F!.~>
+;STlV]=PSa\@B#V[^EKLZa6sBZ*:I9Y-+n.XK/D%WMuhpVl-DhV50o^US=KVTV.pLSt;LCS=?":
+R[KS2R$X/*Q'ISuPEV/mOcb`eO,o<]rf-r:s,6o7s,$`2s+gW/re:B*re(6&rdk'!s*t#srdF`m
+rd4WjrH\?drHJ0_qfVdXpN,G:pN-4RqfVg[rHJ3brH\Bgrd4TkrdFcps*t#urdk*$re(6(re:B,
+s+gT0s,$c5s,6o9s,I&=rf@)@s,m>E4d2+pQ'IZ$Q^=),R@0M4S"-">SXuFFT:hmOU8"EXUnsob
+VPg>jWMuntX/rD)Xfek2YctC<ZEppF[C*o's5F!.~>
+;STlV]=PSa\@B#V[^EKLZa6sBZ*:I9Y-+n.XK/D%WMuhpVl-DhV50o^US=KVTV.pLSt;LCS=?":
+R[KS2R$X/*Q'ISuPEV/mOcb`eO,o<]rf-r:s,6o7s,$`2s+gW/re:B*re(6&rdk'!s*t#srdF`m
+rd4WjrH\?drHJ0_qfVdXpN,G:pN-4RqfVg[rHJ3brH\Bgrd4TkrdFcps*t#urdk*$re(6(re:B,
+s+gT0s,$c5s,6o9s,I&=rf@)@s,m>E4d2+pQ'IZ$Q^=),R@0M4S"-">SXuFFT:hmOU8"EXUnsob
+VPg>jWMuntX/rD)Xfek2YctC<ZEppF[C*o's5F!.~>
+@C`hT[C!<IZEga>Yck75Xf\\*X/`.uW2HPjVPU,bUSFQWTqJ'NSt;LDS=?":R[KP1Q^=#'Q'@Ms
+PEM&jOH>NaNfK*XN/NUOMM[1GLkgb?L4t>7KS+o/Jq8K'J:E(JIfFirI/eQmHN/9iGlN!eG5cXa
+FT-@\ErC"WE;a_SDZ"AMD#8#FCA2H+B_Z<<CA_lFD#J5LDZ4SQE;jkVErL.[FT-F^G5ldcGlN'g
+HN/?lI/eWoIfFotJH(3#K)^K'K`?c+LB!&/M#W>3MZ8SsN/`gWNfT6_OHG]hPEV5qQ'R`&Q^F2/
+R[T_9S=Q4BT:_dLTq\9VUnji`VPg>jW2ZesX/rD)Y-+t3^OcFDs*t~>
+@C`hT[C!<IZEga>Yck75Xf\\*X/`.uW2HPjVPU,bUSFQWTqJ'NSt;LDS=?":R[KP1Q^=#'Q'@Ms
+PEM&jOH>NaNfK*XN/NUOMM[1GLkgb?L4t>7KS+o/Jq8K'J:E(JIfFirI/eQmHN/9iGlN!eG5cXa
+FT-@\ErC"WE;a_SDZ"AMD#8#FCA2H+B_Z<<CA_lFD#J5LDZ4SQE;jkVErL.[FT-F^G5ldcGlN'g
+HN/?lI/eWoIfFotJH(3#K)^K'K`?c+LB!&/M#W>3MZ8SsN/`gWNfT6_OHG]hPEV5qQ'R`&Q^F2/
+R[T_9S=Q4BT:_dLTq\9VUnji`VPg>jW2ZesX/rD)Y-+t3^OcFDs*t~>
+@C`hT[C!<IZEga>Yck75Xf\\*X/`.uW2HPjVPU,bUSFQWTqJ'NSt;LDS=?":R[KP1Q^=#'Q'@Ms
+PEM&jOH>NaNfK*XN/NUOMM[1GLkgb?L4t>7KS+o/Jq8K'J:E(JIfFirI/eQmHN/9iGlN!eG5cXa
+FT-@\ErC"WE;a_SDZ"AMD#8#FCA2H+B_Z<<CA_lFD#J5LDZ4SQE;jkVErL.[FT-F^G5ldcGlN'g
+HN/?lI/eWoIfFotJH(3#K)^K'K`?c+LB!&/M#W>3MZ8SsN/`gWNfT6_OHG]hPEV5qQ'R`&Q^F2/
+R[T_9S=Q4BT:_dLTq\9VUnji`VPg>jW2ZesX/rD)Y-+t3^OcFDs*t~>
+A$iMFYck44XfSV)WiE%sW2HMiV50o^U8"?TTV%jJSXl:?S!ob5R$X/*QBd]!PEM)kOcYWbNfK*X
+N/NUOM2@%ELPCP;KnP,3K7\Z*J:N-!IXZ]nI!^3dH?jd\G^"@TG5cXaFT6F^ErU.YE;skVDZ4MQ
+D#S5LCB&#IB`;ZCB)ZB?AGp$:@f0[2@/+*p?M@h(@/OI3@f9g8AGp*=B)ZHBB`;`GCAr#KD#S;O
+DZ4SSE;sqXErU4[FT6L`G5lddGlN'hHN/=cI!pElIXcitJ:W9'K7ei1KnY8:LPUbCM2I4LN/WaV
+NfT6_OcbfjPE_;sQBml)R$jD3S"#q=SXuIGTV8'RUSFW]V5C/gW2Zbr\q0n?s*t~>
+A$iMFYck44XfSV)WiE%sW2HMiV50o^U8"?TTV%jJSXl:?S!ob5R$X/*QBd]!PEM)kOcYWbNfK*X
+N/NUOM2@%ELPCP;KnP,3K7\Z*J:N-!IXZ]nI!^3dH?jd\G^"@TG5cXaFT6F^ErU.YE;skVDZ4MQ
+D#S5LCB&#IB`;ZCB)ZB?AGp$:@f0[2@/+*p?M@h(@/OI3@f9g8AGp*=B)ZHBB`;`GCAr#KD#S;O
+DZ4SSE;sqXErU4[FT6L`G5lddGlN'hHN/=cI!pElIXcitJ:W9'K7ei1KnY8:LPUbCM2I4LN/WaV
+NfT6_OcbfjPE_;sQBml)R$jD3S"#q=SXuIGTV8'RUSFW]V5C/gW2Zbr\q0n?s*t~>
+A$iMFYck44XfSV)WiE%sW2HMiV50o^U8"?TTV%jJSXl:?S!ob5R$X/*QBd]!PEM)kOcYWbNfK*X
+N/NUOM2@%ELPCP;KnP,3K7\Z*J:N-!IXZ]nI!^3dH?jd\G^"@TG5cXaFT6F^ErU.YE;skVDZ4MQ
+D#S5LCB&#IB`;ZCB)ZB?AGp$:@f0[2@/+*p?M@h(@/OI3@f9g8AGp*=B)ZHBB`;`GCAr#KD#S;O
+DZ4SSE;sqXErU4[FT6L`G5lddGlN'hHN/=cI!pElIXcitJ:W9'K7ei1KnY8:LPUbCM2I4LN/WaV
+NfT6_OcbfjPE_;sQBml)R$jD3S"#q=SXuIGTV8'RUSFW]V5C/gW2Zbr\q0n?s*t~>
+FK_dHX/`.uW2HPjV59u_US=HTTV%gISXc4>R[TY3R$X,)Q'@MsP*1rhOH5E^NJrgSMMd7ILkgb?
+KnY25K7\]+J:N-!IXQWlI!^0cH$OXZGBS.PF`__HF)l8?E,]`6DJj<.Ci!m&C2.HsBP;$kAnM$R
+s().>raPn9ra>_4s'G\1r`oD+r`]8'rE/u!qH!Akmo9$]qc<VrrE0#$rEB2)r`oG.ra,V3ra>b7
+raPn;rac%?s(;:Ds(MFHs(_RLs(q^Ps).jTs)A!Xs)LnVFEDYJG'8(SG^4R\H@($eI=6QoIt3'#
+JqAW.KS>,7LPL\BM2I4LN/WaVNfT9`OcklkPa%H!QC!u+R@9V7S=Q4BT:_dMTq\<XUntMNs5F!.~>
+FK_dHX/`.uW2HPjV59u_US=HTTV%gISXc4>R[TY3R$X,)Q'@MsP*1rhOH5E^NJrgSMMd7ILkgb?
+KnY25K7\]+J:N-!IXQWlI!^0cH$OXZGBS.PF`__HF)l8?E,]`6DJj<.Ci!m&C2.HsBP;$kAnM$R
+s().>raPn9ra>_4s'G\1r`oD+r`]8'rE/u!qH!Akmo9$]qc<VrrE0#$rEB2)r`oG.ra,V3ra>b7
+raPn;rac%?s(;:Ds(MFHs(_RLs(q^Ps).jTs)A!Xs)LnVFEDYJG'8(SG^4R\H@($eI=6QoIt3'#
+JqAW.KS>,7LPL\BM2I4LN/WaVNfT9`OcklkPa%H!QC!u+R@9V7S=Q4BT:_dMTq\<XUntMNs5F!.~>
+FK_dHX/`.uW2HPjV59u_US=HTTV%gISXc4>R[TY3R$X,)Q'@MsP*1rhOH5E^NJrgSMMd7ILkgb?
+KnY25K7\]+J:N-!IXQWlI!^0cH$OXZGBS.PF`__HF)l8?E,]`6DJj<.Ci!m&C2.HsBP;$kAnM$R
+s().>raPn9ra>_4s'G\1r`oD+r`]8'rE/u!qH!Akmo9$]qc<VrrE0#$rEB2)r`oG.ra,V3ra>b7
+raPn;rac%?s(;:Ds(MFHs(_RLs(q^Ps).jTs)A!Xs)LnVFEDYJG'8(SG^4R\H@($eI=6QoIt3'#
+JqAW.KS>,7LPL\BM2I4LN/WaVNfT9`OcklkPa%H!QC!u+R@9V7S=Q4BT:_dMTq\<XUntMNs5F!.~>
+FK2:;VP^2cUnaZXTqJ$MSt2CAS!oe6R$X/*Q'IStP*1rhOH5E^NJrgSMM[1GLPLV<KnP)2Jq8K'
+It)oqI=-EhH?sj]G^"=SF`heIF)l8?E,]`5DJa6,CMR["Bk_6nB4baeARo=]@q&nU?sm>K?=*V:
+s'5S.s'#G*r`K2%s&T,!r`&kqr_i_mrD<Jhr(d/aqb6$CqFpf]rD*;er_WSkr_i_or`&kss&T,#
+s&f;(r`]>+s'5S0s'G_4s'Yk8s'l"<?"@MXAnG[gBP;*pC27U$D/F0.DfBZ8EH6,AFEDYKG'A1U
+H$Xd`I!g?jIXcitJUrE*K7nr4L51S@M2I1KN/WaVNfT9aOckolPa.N"Q^F/.R[T_9SXl@ET:iK@
+s5F!.~>
+FK2:;VP^2cUnaZXTqJ$MSt2CAS!oe6R$X/*Q'IStP*1rhOH5E^NJrgSMM[1GLPLV<KnP)2Jq8K'
+It)oqI=-EhH?sj]G^"=SF`heIF)l8?E,]`5DJa6,CMR["Bk_6nB4baeARo=]@q&nU?sm>K?=*V:
+s'5S.s'#G*r`K2%s&T,!r`&kqr_i_mrD<Jhr(d/aqb6$CqFpf]rD*;er_WSkr_i_or`&kss&T,#
+s&f;(r`]>+s'5S0s'G_4s'Yk8s'l"<?"@MXAnG[gBP;*pC27U$D/F0.DfBZ8EH6,AFEDYKG'A1U
+H$Xd`I!g?jIXcitJUrE*K7nr4L51S@M2I1KN/WaVNfT9aOckolPa.N"Q^F/.R[T_9SXl@ET:iK@
+s5F!.~>
+FK2:;VP^2cUnaZXTqJ$MSt2CAS!oe6R$X/*Q'IStP*1rhOH5E^NJrgSMM[1GLPLV<KnP)2Jq8K'
+It)oqI=-EhH?sj]G^"=SF`heIF)l8?E,]`5DJa6,CMR["Bk_6nB4baeARo=]@q&nU?sm>K?=*V:
+s'5S.s'#G*r`K2%s&T,!r`&kqr_i_mrD<Jhr(d/aqb6$CqFpf]rD*;er_WSkr_i_or`&kss&T,#
+s&f;(r`]>+s'5S0s'G_4s'Yk8s'l"<?"@MXAnG[gBP;*pC27U$D/F0.DfBZ8EH6,AFEDYKG'A1U
+H$Xd`I!g?jIXcitJUrE*K7nr4L51S@M2I1KN/WaVNfT9aOckolPa.N"Q^F/.R[T_9SXl@ET:iK@
+s5F!.~>
+IA`m9U8"?ST:_^GS=H(;R[KP0Q^3o$P`q8mOcYWbNfB!VMi*CKLkgb?KnY24JqAQ(J:E#sI=-Bg
+H?jd\GB\4QF`_\GEcH)<Df9N1D/=!'C2%BqB4kggARo=]@U`bS?sd8I?<piA>?b97=]nj.=&r@%
+<E)pr;c6Nm;?'Jm:]F2i:&[id9E%Q`8cD9[8,c!V7K#XP6i04462O"H6iBFP7K,dU8,c'Y8cME^
+9E.]c:&[of:]F8k;?'Po;u]hs<W?,"=8uD&=^kQ=>?kE=?=$uG?smDP@UiqZAS#IdB4u!nC27U$
+D/F0.DfBZ8EcQ5CF`hkOGBeCYH@(!dI=6QoJ:N3&JqJ`1KnbA<Ll%"HMi<USNfT6_OcklkPa.N"
+Q^F/.R[T_9YCZ`4s*t~>
+IA`m9U8"?ST:_^GS=H(;R[KP0Q^3o$P`q8mOcYWbNfB!VMi*CKLkgb?KnY24JqAQ(J:E#sI=-Bg
+H?jd\GB\4QF`_\GEcH)<Df9N1D/=!'C2%BqB4kggARo=]@U`bS?sd8I?<piA>?b97=]nj.=&r@%
+<E)pr;c6Nm;?'Jm:]F2i:&[id9E%Q`8cD9[8,c!V7K#XP6i04462O"H6iBFP7K,dU8,c'Y8cME^
+9E.]c:&[of:]F8k;?'Po;u]hs<W?,"=8uD&=^kQ=>?kE=?=$uG?smDP@UiqZAS#IdB4u!nC27U$
+D/F0.DfBZ8EcQ5CF`hkOGBeCYH@(!dI=6QoJ:N3&JqJ`1KnbA<Ll%"HMi<USNfT6_OcklkPa.N"
+Q^F/.R[T_9YCZ`4s*t~>
+IA`m9U8"?ST:_^GS=H(;R[KP0Q^3o$P`q8mOcYWbNfB!VMi*CKLkgb?KnY24JqAQ(J:E#sI=-Bg
+H?jd\GB\4QF`_\GEcH)<Df9N1D/=!'C2%BqB4kggARo=]@U`bS?sd8I?<piA>?b97=]nj.=&r@%
+<E)pr;c6Nm;?'Jm:]F2i:&[id9E%Q`8cD9[8,c!V7K#XP6i04462O"H6iBFP7K,dU8,c'Y8cME^
+9E.]c:&[of:]F8k;?'Po;u]hs<W?,"=8uD&=^kQ=>?kE=?=$uG?smDP@UiqZAS#IdB4u!nC27U$
+D/F0.DfBZ8EcQ5CF`hkOGBeCYH@(!dI=6QoJ:N3&JqJ`1KnbA<Ll%"HMi<USNfT6_OcklkPa.N"
+Q^F/.R[T_9YCZ`4s*t~>
+I\`X0T:VUES=>t9R@'>-QBd]!PEM&jOH5E^NJrdRMM[.FLPCM:KS+l.JUi6"IXQTkH[:!`G^"@T
+F`heIEcQ/=E,TW2D/=!'C2%BqB4baeA7T1Z@UWYP?X@&E>[1K:>$5!1='&F&<E)pr;c6Ii:f'q_
+:/+GV9M7uMs%35]s%!)Ys$crUs$QfQr^$QLr]gEHr]U6Cr]C'>r&O[7kr8K!r&Oa;rB(!@s#p?F
+s$-KJs$?ZOs$QcRs$crWGXk:q8P)NH91qrP9hnGZ:Jakb;GpFm<)lq!<``C*=^#!5>[1Q@?=.)J
+@:E\UA7T7`AnPdjBkhBuCi+$,Df9T7EcQ5CFEMbNGBeCZH@($eI=?ZqJ:W<(K7nr4L51S@M2I4L
+N/`jXO-#KdP*;,pQ'Rc(R&kl=iW"E~>
+I\`X0T:VUES=>t9R@'>-QBd]!PEM&jOH5E^NJrdRMM[.FLPCM:KS+l.JUi6"IXQTkH[:!`G^"@T
+F`heIEcQ/=E,TW2D/=!'C2%BqB4baeA7T1Z@UWYP?X@&E>[1K:>$5!1='&F&<E)pr;c6Ii:f'q_
+:/+GV9M7uMs%35]s%!)Ys$crUs$QfQr^$QLr]gEHr]U6Cr]C'>r&O[7kr8K!r&Oa;rB(!@s#p?F
+s$-KJs$?ZOs$QcRs$crWGXk:q8P)NH91qrP9hnGZ:Jakb;GpFm<)lq!<``C*=^#!5>[1Q@?=.)J
+@:E\UA7T7`AnPdjBkhBuCi+$,Df9T7EcQ5CFEMbNGBeCZH@($eI=?ZqJ:W<(K7nr4L51S@M2I4L
+N/`jXO-#KdP*;,pQ'Rc(R&kl=iW"E~>
+I\`X0T:VUES=>t9R@'>-QBd]!PEM&jOH5E^NJrdRMM[.FLPCM:KS+l.JUi6"IXQTkH[:!`G^"@T
+F`heIEcQ/=E,TW2D/=!'C2%BqB4baeA7T1Z@UWYP?X@&E>[1K:>$5!1='&F&<E)pr;c6Ii:f'q_
+:/+GV9M7uMs%35]s%!)Ys$crUs$QfQr^$QLr]gEHr]U6Cr]C'>r&O[7kr8K!r&Oa;rB(!@s#p?F
+s$-KJs$?ZOs$QcRs$crWGXk:q8P)NH91qrP9hnGZ:Jakb;GpFm<)lq!<``C*=^#!5>[1Q@?=.)J
+@:E\UA7T7`AnPdjBkhBuCi+$,Df9T7EcQ5CFEMbNGBeCZH@($eI=?ZqJ:W<(K7nr4L51S@M2I4L
+N/`jXO-#KdP*;,pQ'Rc(R&kl=iW"E~>
+I\E@(S=?":R@'>-QBd]!PEM&iOH5E]NJrdQM2@%DL5(D8K7ec,J:N,uI=-EhH?jd\GBS.PFE;MD
+EH#l8DJa6,CMITuBP;$jAS#C^@U`bR?sd5G?!LT<>$4s0=&r@%<)cdo;Gg7e:JOYZ9MA)P8kDTF
+7n6$;779O2s$H`O(-k)K5!D+m4?P\e3]]8]3&iiU2E!EMr\XX2r\FI-r@n1'r%@=fr%@q$r@n4*
+s"aR0s"s^4s#0m9s#C$=s#U0As#g<EHTjYY5X7V$6:4+.6q'R77n?0B8kM`L9MJ5V:JXea;,U=l
+<)lq!='&L,>$>-8>[:ZC?XR;O@UiqZAS,RfBPD3rCM[j)DJsK5EH6,AFEMbMGBeCYH@($eI=?Zr
+J:W<)K7nr5L51SAMMd=NNK&sZOHGZgPE_;sWIb*.s*t~>
+I\E@(S=?":R@'>-QBd]!PEM&iOH5E]NJrdQM2@%DL5(D8K7ec,J:N,uI=-EhH?jd\GBS.PFE;MD
+EH#l8DJa6,CMITuBP;$jAS#C^@U`bR?sd5G?!LT<>$4s0=&r@%<)cdo;Gg7e:JOYZ9MA)P8kDTF
+7n6$;779O2s$H`O(-k)K5!D+m4?P\e3]]8]3&iiU2E!EMr\XX2r\FI-r@n1'r%@=fr%@q$r@n4*
+s"aR0s"s^4s#0m9s#C$=s#U0As#g<EHTjYY5X7V$6:4+.6q'R77n?0B8kM`L9MJ5V:JXea;,U=l
+<)lq!='&L,>$>-8>[:ZC?XR;O@UiqZAS,RfBPD3rCM[j)DJsK5EH6,AFEMbMGBeCYH@($eI=?Zr
+J:W<)K7nr5L51SAMMd=NNK&sZOHGZgPE_;sWIb*.s*t~>
+I\E@(S=?":R@'>-QBd]!PEM&iOH5E]NJrdQM2@%DL5(D8K7ec,J:N,uI=-EhH?jd\GBS.PFE;MD
+EH#l8DJa6,CMITuBP;$jAS#C^@U`bR?sd5G?!LT<>$4s0=&r@%<)cdo;Gg7e:JOYZ9MA)P8kDTF
+7n6$;779O2s$H`O(-k)K5!D+m4?P\e3]]8]3&iiU2E!EMr\XX2r\FI-r@n1'r%@=fr%@q$r@n4*
+s"aR0s"s^4s#0m9s#C$=s#U0As#g<EHTjYY5X7V$6:4+.6q'R77n?0B8kM`L9MJ5V:JXea;,U=l
+<)lq!='&L,>$>-8>[:ZC?XR;O@UiqZAS,RfBPD3rCM[j)DJsK5EH6,AFEMbMGBeCYH@($eI=?Zr
+J:W<)K7nr5L51SAMMd=NNK&sZOHGZgPE_;sWIb*.s*t~>
+&tbYlWi;qpVl$;eUnjc[TqS-Prgk!uS=H(<R[KP0Q^3r&Q'@GpOcb`eO,o<\N;eb8M>rA3L]3&.
+K`?](Jc:-$IXQWlrd4Zjs*+NfrcS9arc80^EH#mrDZF\SD#\;NC&VcGBDlEAA,p-=@K'X7?N+71
+>QS,5>5hY+=BAT%<<Q9";c-Ei;#a>k:&Rc`9E.W`8GYj=7f#XS8H2<[9DqQa:&e#e;#aAo;cH`o
+<<?6(=T2J'=ohi4ra#P1ra>_6!Fo[<AH6BBBE2cGC]A5NDZ4P_E,fl<F)uJHG'8(RGlE!gHiJHo
+I=D0FrIG$&KS9>Z"G_ehM2D4i)2sQ8NfT9`OcbfiPa.N"QC!u+R@9V7S=H/LT)YJ`T`_$[PGnK\
+$J,7Wlf.sEh"e&Lrr3#c\DI5dlFuZc!R9?&rrB!J~>
+&tbYlWi;qpVl$;eUnjc[TqS-Prgk!uS=H(<R[KP0Q^3r&Q'@GpOcb`eO,o<\N;eb8M>rA3L]3&.
+K`?](Jc:-$IXQWlrd4Zjs*+NfrcS9arc80^EH#mrDZF\SD#\;NC&VcGBDlEAA,p-=@K'X7?N+71
+>QS,5>5hY+=BAT%<<Q9";c-Ei;#a>k:&Rc`9E.W`8GYj=7f#XS8H2<[9DqQa:&e#e;#aAo;cH`o
+<<?6(=T2J'=ohi4ra#P1ra>_6!Fo[<AH6BBBE2cGC]A5NDZ4P_E,fl<F)uJHG'8(RGlE!gHiJHo
+I=D0FrIG$&KS9>Z"G_ehM2D4i)2sQ8NfT9`OcbfiPa.N"QC!u+R@9V7S=H/LT)YJ`T`_$[PGnK\
+$J,7Wlf.sEh"e&Lrr3#c\DI5dlFuZc!R9?&rrB!J~>
+&tbYlWi;qpVl$;eUnjc[TqS-Prgk!uS=H(<R[KP0Q^3r&Q'@GpOcb`eO,o<\N;eb8M>rA3L]3&.
+K`?](Jc:-$IXQWlrd4Zjs*+NfrcS9arc80^EH#mrDZF\SD#\;NC&VcGBDlEAA,p-=@K'X7?N+71
+>QS,5>5hY+=BAT%<<Q9";c-Ei;#a>k:&Rc`9E.W`8GYj=7f#XS8H2<[9DqQa:&e#e;#aAo;cH`o
+<<?6(=T2J'=ohi4ra#P1ra>_6!Fo[<AH6BBBE2cGC]A5NDZ4P_E,fl<F)uJHG'8(RGlE!gHiJHo
+I=D0FrIG$&KS9>Z"G_ehM2D4i)2sQ8NfT9`OcbfiPa.N"QC!u+R@9V7S=H/LT)YJ`T`_$[PGnK\
+$J,7Wlf.sEh"e&Lrr3#c\DI5dlFuZc!R9?&rrB!J~>
+!hPkHJcC<$Rf<HBOf&-X$9I>LC-qt#-i-+&rr3,eZi<VhiVrr'C@2$%N2s2_!'#K~>
+!hPkHJcC<$Rf<HBOf&-X$9I>LC-qt#-i-+&rr3,eZi<VhiVrr'C@2$%N2s2_!'#K~>
+!hPkHJcC<$Rf<HBOf&-X$9I>LC-qt#-i-+&rr3,eZi<VhiVrr'C@2$%N2s2_!'#K~>
+!hGbFJcC<$Rf<HAOJVsV(k8=\8QkN59`IA:<-\H$MUEGRQ2ZY??/tn`!LWc`rtiY.?rtrl:##]o
+?<jQ2oP.reCB)gc;kEsf-ACabXh=LHE)*J6N2ui&bJ&^;:u;5r?!OQ4GkToks2q1jIUl*prVn[k
+>[4i>WJY0's8VA<s8Qj6W/=b[m/LpO:mD"8?<)+Fs(m$[[Y[kOs8.7EAF0>p=aVrS~>
+!hGbFJcC<$Rf<HAOJVsV(k8=\8QkN59`IA:<-\H$MUEGRQ2ZY??/tn`!LWc`rtiY.?rtrl:##]o
+?<jQ2oP.reCB)gc;kEsf-ACabXh=LHE)*J6N2ui&bJ&^;:u;5r?!OQ4GkToks2q1jIUl*prVn[k
+>[4i>WJY0's8VA<s8Qj6W/=b[m/LpO:mD"8?<)+Fs(m$[[Y[kOs8.7EAF0>p=aVrS~>
+!hGbFJcC<$Rf<HAOJVsV(k8=\8QkN59`IA:<-\H$MUEGRQ2ZY??/tn`!LWc`rtiY.?rtrl:##]o
+?<jQ2oP.reCB)gc;kEsf-ACabXh=LHE)*J6N2ui&bJ&^;:u;5r?!OQ4GkToks2q1jIUl*prVn[k
+>[4i>WJY0's8VA<s8Qj6W/=b[m/LpO:mD"8?<)+Fs(m$[[Y[kOs8.7EAF0>p=aVrS~>
+!hGbFJcC<$Rf<HAOJVsV(r]h?AXKW_P5deIs%Utl>Q7(_s/0l9a]SNA!K-aQrtqn.qjTA8]4M!q
+kkdO"JYN0uCB$!Or(5]Cs!Cb*s,EcJ$0_+3s,<CH\GrBsqlt&=/aE0mid\D!44/5da=Hu69E+qr
+pau%01@Bp9rVn;*<WE(Ps+P(aP)]J[d/5Hgq#9l$WrEagoFAb9./]3^s0HV*62]gOJ,~>
+!hGbFJcC<$Rf<HAOJVsV(r]h?AXKW_P5deIs%Utl>Q7(_s/0l9a]SNA!K-aQrtqn.qjTA8]4M!q
+kkdO"JYN0uCB$!Or(5]Cs!Cb*s,EcJ$0_+3s,<CH\GrBsqlt&=/aE0mid\D!44/5da=Hu69E+qr
+pau%01@Bp9rVn;*<WE(Ps+P(aP)]J[d/5Hgq#9l$WrEagoFAb9./]3^s0HV*62]gOJ,~>
+!hGbFJcC<$Rf<HAOJVsV(r]h?AXKW_P5deIs%Utl>Q7(_s/0l9a]SNA!K-aQrtqn.qjTA8]4M!q
+kkdO"JYN0uCB$!Or(5]Cs!Cb*s,EcJ$0_+3s,<CH\GrBsqlt&=/aE0mid\D!44/5da=Hu69E+qr
+pau%01@Bp9rVn;*<WE(Ps+P(aP)]J[d/5Hgq#9l$WrEagoFAb9./]3^s0HV*62]gOJ,~>
+!hGbFJcC<$Rf<HBOJVsV(&TPOW7u&]f`+50s*2<.>Q7(_s)D!:Dts>LY)!%sDu\rsp,N*PG-b6)
+s2Aa>*H,k(b5VDf<T=%:UA-kNs#9t:,)uX&V3(`5>4FfVs)>NgD-"E/3r6p7s8P(Xrs.IXs8QHJ
+LTUOT.,n8,s"=>*YQ):^s#'iV;<G__E);Jm2?3\6s8PXY>?l)aI_]t's"Js~>
+!hGbFJcC<$Rf<HBOJVsV(&TPOW7u&]f`+50s*2<.>Q7(_s)D!:Dts>LY)!%sDu\rsp,N*PG-b6)
+s2Aa>*H,k(b5VDf<T=%:UA-kNs#9t:,)uX&V3(`5>4FfVs)>NgD-"E/3r6p7s8P(Xrs.IXs8QHJ
+LTUOT.,n8,s"=>*YQ):^s#'iV;<G__E);Jm2?3\6s8PXY>?l)aI_]t's"Js~>
+!hGbFJcC<$Rf<HBOJVsV(&TPOW7u&]f`+50s*2<.>Q7(_s)D!:Dts>LY)!%sDu\rsp,N*PG-b6)
+s2Aa>*H,k(b5VDf<T=%:UA-kNs#9t:,)uX&V3(`5>4FfVs)>NgD-"E/3r6p7s8P(Xrs.IXs8QHJ
+LTUOT.,n8,s"=>*YQ):^s#'iV;<G__E);Jm2?3\6s8PXY>?l)aI_]t's"Js~>
+)kNM"YHG%1XK8J&Wi;trW2HMiV50l]U8"?ST`1P_Sc>2\S!s>Es-NbOs-3VLPQ$^HOcYY'NW>(<
+N;nb8M>i;4LPCN]KDgB$J,ausI/eQnHN/9jG5ugcFT?O^EWC+XDZFYQC]J5LB`Vm[ral.ArF5h:
+rEoV4rE]G.!*]>(!*K2#s&B%trDNYmrD*Ji9hkOYs%38_qFCNSoL8aKqF:TY8kT"Ss%NJgrD3Gj
+rDE\q<E8uu!*K2&!a8i6ra#P2ra>b8rF6.FAnG[gBPD0qCAr&LD>nJREW1"YFT6I`G5c[cH2`*i
+Hi8<nIXckGJc13*KnbA<LkpoeMZ8V8NW+q>O-#M'Op.&6Q'IZ$rg3YQ"e(pNS=Q5MT)YGaTq_O]
+$)FDpVPgAkTou;OrteNel2O%#s8P@Ys*2<.>Q7CUs.4Z=s7cKl!Qb6=rtqnqs2K'Yk#).2mJTB,
+IAm1)CAosSs82]ms!D?erCE[X5QCaBs,<jfQN*eEs4plY/b&[%i;>?4r&ddTaD_+Y2u`g^pFc18
+2=-+&rVn;9/cO06s+RcY]mB];s8PsYE3fLXMZ5X8s#9uX8FM@us8ViS7/c?ZJ,~>
+)kNM"YHG%1XK8J&Wi;trW2HMiV50l]U8"?ST`1P_Sc>2\S!s>Es-NbOs-3VLPQ$^HOcYY'NW>(<
+N;nb8M>i;4LPCN]KDgB$J,ausI/eQnHN/9jG5ugcFT?O^EWC+XDZFYQC]J5LB`Vm[ral.ArF5h:
+rEoV4rE]G.!*]>(!*K2#s&B%trDNYmrD*Ji9hkOYs%38_qFCNSoL8aKqF:TY8kT"Ss%NJgrD3Gj
+rDE\q<E8uu!*K2&!a8i6ra#P2ra>b8rF6.FAnG[gBPD0qCAr&LD>nJREW1"YFT6I`G5c[cH2`*i
+Hi8<nIXckGJc13*KnbA<LkpoeMZ8V8NW+q>O-#M'Op.&6Q'IZ$rg3YQ"e(pNS=Q5MT)YGaTq_O]
+$)FDpVPgAkTou;OrteNel2O%#s8P@Ys*2<.>Q7CUs.4Z=s7cKl!Qb6=rtqnqs2K'Yk#).2mJTB,
+IAm1)CAosSs82]ms!D?erCE[X5QCaBs,<jfQN*eEs4plY/b&[%i;>?4r&ddTaD_+Y2u`g^pFc18
+2=-+&rVn;9/cO06s+RcY]mB];s8PsYE3fLXMZ5X8s#9uX8FM@us8ViS7/c?ZJ,~>
+)kNM"YHG%1XK8J&Wi;trW2HMiV50l]U8"?ST`1P_Sc>2\S!s>Es-NbOs-3VLPQ$^HOcYY'NW>(<
+N;nb8M>i;4LPCN]KDgB$J,ausI/eQnHN/9jG5ugcFT?O^EWC+XDZFYQC]J5LB`Vm[ral.ArF5h:
+rEoV4rE]G.!*]>(!*K2#s&B%trDNYmrD*Ji9hkOYs%38_qFCNSoL8aKqF:TY8kT"Ss%NJgrD3Gj
+rDE\q<E8uu!*K2&!a8i6ra#P2ra>b8rF6.FAnG[gBPD0qCAr&LD>nJREW1"YFT6I`G5c[cH2`*i
+Hi8<nIXckGJc13*KnbA<LkpoeMZ8V8NW+q>O-#M'Op.&6Q'IZ$rg3YQ"e(pNS=Q5MT)YGaTq_O]
+$)FDpVPgAkTou;OrteNel2O%#s8P@Ys*2<.>Q7CUs.4Z=s7cKl!Qb6=rtqnqs2K'Yk#).2mJTB,
+IAm1)CAosSs82]ms!D?erCE[X5QCaBs,<jfQN*eEs4plY/b&[%i;>?4r&ddTaD_+Y2u`g^pFc18
+2=-+&rVn;9/cO06s+RcY]mB];s8PsYE3fLXMZ5X8s#9uX8FM@us8ViS7/c?ZJ,~>
+J"W=$S!ob4Q^=#'P`q;oOcYWbNfB!UMi*@ILPLV<KS+o/JUi6"IXQTjH[9s^GB\4QFE;MDEH#i7
+DJa3*CMIQsB4kgfA7T1Z@:3JM?<pf@>?Y04=BAO'<E)mq;Gg7e:JOVX9M7uL8Ou?@7R]^46UF((
+5X.Fq4Zkee3[m'K3&``Q2)I*F1,1L;0/"q0/M&D&.Ocep-mp>g,paf^,9nBV+X%sNrZD+\r>kAI
+r>kkYrZD._ruqCds!.Ohs!@[lIjZWm.4Qet.kE8(/h\k30ekF>1c.'J2E*TU3BB5`4?Ykl5<qM#
+6:4./77Kd;84cEH92&&T:/=\`;,U=l<)lt#='/U/>?b?<?=.&I@:E_VA7]@cB4u!oC27X&DJjB3
+EH6)@FEMbMGBeCZH[C-gIXcitJV&N,KS>/9LC]2tMMmCONK0'\OHG]iPc4Q\(TUg@s+5t)s)@f6
+Ra9lEs1MNqrI/$\Rf36e=nr!r(rN6NeWg+$I/h/b<h99[>[`/Ds3+VR@.!sn-JCjiICf8ns8Qg5
+WPJOd[_&^Bjb3ZN<)oXls*:UDH)^hpPQ1YsrVm)3;cKn!V8W<3-]:N@@K3.Bs3@,6C&e3]m*eL<
+I]*3[s8Qg5s*"#/F'i=Rs-cl,?[r~>
+J"W=$S!ob4Q^=#'P`q;oOcYWbNfB!UMi*@ILPLV<KS+o/JUi6"IXQTjH[9s^GB\4QFE;MDEH#i7
+DJa3*CMIQsB4kgfA7T1Z@:3JM?<pf@>?Y04=BAO'<E)mq;Gg7e:JOVX9M7uL8Ou?@7R]^46UF((
+5X.Fq4Zkee3[m'K3&``Q2)I*F1,1L;0/"q0/M&D&.Ocep-mp>g,paf^,9nBV+X%sNrZD+\r>kAI
+r>kkYrZD._ruqCds!.Ohs!@[lIjZWm.4Qet.kE8(/h\k30ekF>1c.'J2E*TU3BB5`4?Ykl5<qM#
+6:4./77Kd;84cEH92&&T:/=\`;,U=l<)lt#='/U/>?b?<?=.&I@:E_VA7]@cB4u!oC27X&DJjB3
+EH6)@FEMbMGBeCZH[C-gIXcitJV&N,KS>/9LC]2tMMmCONK0'\OHG]iPc4Q\(TUg@s+5t)s)@f6
+Ra9lEs1MNqrI/$\Rf36e=nr!r(rN6NeWg+$I/h/b<h99[>[`/Ds3+VR@.!sn-JCjiICf8ns8Qg5
+WPJOd[_&^Bjb3ZN<)oXls*:UDH)^hpPQ1YsrVm)3;cKn!V8W<3-]:N@@K3.Bs3@,6C&e3]m*eL<
+I]*3[s8Qg5s*"#/F'i=Rs-cl,?[r~>
+J"W=$S!ob4Q^=#'P`q;oOcYWbNfB!UMi*@ILPLV<KS+o/JUi6"IXQTjH[9s^GB\4QFE;MDEH#i7
+DJa3*CMIQsB4kgfA7T1Z@:3JM?<pf@>?Y04=BAO'<E)mq;Gg7e:JOVX9M7uL8Ou?@7R]^46UF((
+5X.Fq4Zkee3[m'K3&``Q2)I*F1,1L;0/"q0/M&D&.Ocep-mp>g,paf^,9nBV+X%sNrZD+\r>kAI
+r>kkYrZD._ruqCds!.Ohs!@[lIjZWm.4Qet.kE8(/h\k30ekF>1c.'J2E*TU3BB5`4?Ykl5<qM#
+6:4./77Kd;84cEH92&&T:/=\`;,U=l<)lt#='/U/>?b?<?=.&I@:E_VA7]@cB4u!oC27X&DJjB3
+EH6)@FEMbMGBeCZH[C-gIXcitJV&N,KS>/9LC]2tMMmCONK0'\OHG]iPc4Q\(TUg@s+5t)s)@f6
+Ra9lEs1MNqrI/$\Rf36e=nr!r(rN6NeWg+$I/h/b<h99[>[`/Ds3+VR@.!sn-JCjiICf8ns8Qg5
+WPJOd[_&^Bjb3ZN<)oXls*:UDH)^hpPQ1YsrVm)3;cKn!V8W<3-]:N@@K3.Bs3@,6C&e3]m*eL<
+I]*3[s8Qg5s*"#/F'i=Rs-cl,?[r~>
+J"rX-SXc4>R[KP1Q^3o$P`q8mOcYWaNK&mTMM[1GLPCM:KS+l.JUi6!IXQTjH[9s^GB\4QFEDSE
+EH#l8DJa6,CMITuBP1phARo:\@UWYP?X@#D>[(B8=]ea,<`N.!;c?Rk:f'q_:/+DT91hcI84Q-=
+779O26:*t'5TW-R5!;"j4$,J`3B/rV2E!EM1c$pC1,1L;0J>(30)dI&/H.1!.fLmq./>7e-Mf+f
+./k[p.fLsu/H7=$0)mU)0`NkV1,C^C1c7-K2E*TT3BB2_4$5Yh5!M7s5s[h)6UX@37Ros>8P2TJ
+9MA/U:JXea;GpFm<)lt"='/U.>$G6:?!^lF?t!MR@q9._AnPdkBkhF"Ci+'.E,]f;F)uGGG'A.T
+H$XgaI!pHmIt3*%JqJ`1L5(J>M2@+JN/`f)NfT9aOckomQ'IZ8JcF^/J,~>
+J"rX-SXc4>R[KP1Q^3o$P`q8mOcYWaNK&mTMM[1GLPCM:KS+l.JUi6!IXQTjH[9s^GB\4QFEDSE
+EH#l8DJa6,CMITuBP1phARo:\@UWYP?X@#D>[(B8=]ea,<`N.!;c?Rk:f'q_:/+DT91hcI84Q-=
+779O26:*t'5TW-R5!;"j4$,J`3B/rV2E!EM1c$pC1,1L;0J>(30)dI&/H.1!.fLmq./>7e-Mf+f
+./k[p.fLsu/H7=$0)mU)0`NkV1,C^C1c7-K2E*TT3BB2_4$5Yh5!M7s5s[h)6UX@37Ros>8P2TJ
+9MA/U:JXea;GpFm<)lt"='/U.>$G6:?!^lF?t!MR@q9._AnPdkBkhF"Ci+'.E,]f;F)uGGG'A.T
+H$XgaI!pHmIt3*%JqJ`1L5(J>M2@+JN/`f)NfT9aOckomQ'IZ8JcF^/J,~>
+J"rX-SXc4>R[KP1Q^3o$P`q8mOcYWaNK&mTMM[1GLPCM:KS+l.JUi6!IXQTjH[9s^GB\4QFEDSE
+EH#l8DJa6,CMITuBP1phARo:\@UWYP?X@#D>[(B8=]ea,<`N.!;c?Rk:f'q_:/+DT91hcI84Q-=
+779O26:*t'5TW-R5!;"j4$,J`3B/rV2E!EM1c$pC1,1L;0J>(30)dI&/H.1!.fLmq./>7e-Mf+f
+./k[p.fLsu/H7=$0)mU)0`NkV1,C^C1c7-K2E*TT3BB2_4$5Yh5!M7s5s[h)6UX@37Ros>8P2TJ
+9MA/U:JXea;GpFm<)lt"='/U.>$G6:?!^lF?t!MR@q9._AnPdkBkhF"Ci+'.E,]f;F)uGGG'A.T
+H$XgaI!pHmIt3*%JqJ`1L5(J>M2@+JN/`f)NfT9aOckomQ'IZ8JcF^/J,~>
+J#8s6TV.pKSXc4>R[KS2Q^3r&P`q8nOcYWbNfB!UMi*@ILkg_=KnP)1Jq8H%IsufnI!^0bG^+FU
+F`heIF)l8>E,TW2D/=!&C2%?pB4b^dA7K(X@:3JM?=$oB>?b96=]ea,<`N.!;c?Rl;,C(b:/4MW
+9M7uM8P)HC8,l$h779O26UF+*5sRY!5!D+mr]L3Bs#U0?r]'m9r\ja5rA=I/q(hXuq(hn)rA=L2
+r\ja7s#C!<s#U0As#g<Es$$HIs$6TMs$D$!6psI47Rfm=84cEG91qrQ9hnJ[:f1(f;c?Xp<E<.%
+=BJ^0>$G6;?!^lF?t!MR@q9+]AnPaiBkhBuCi!s+Df9T7EcQ5CF`hkOG^+L[H[C-gIXcitJV&K+
+KS>,7LPUbCMMmFPNK0'\OHG]iPE_>uQC!u,R]V/@iW"E~>
+J#8s6TV.pKSXc4>R[KS2Q^3r&P`q8nOcYWbNfB!UMi*@ILkg_=KnP)1Jq8H%IsufnI!^0bG^+FU
+F`heIF)l8>E,TW2D/=!&C2%?pB4b^dA7K(X@:3JM?=$oB>?b96=]ea,<`N.!;c?Rl;,C(b:/4MW
+9M7uM8P)HC8,l$h779O26UF+*5sRY!5!D+mr]L3Bs#U0?r]'m9r\ja5rA=I/q(hXuq(hn)rA=L2
+r\ja7s#C!<s#U0As#g<Es$$HIs$6TMs$D$!6psI47Rfm=84cEG91qrQ9hnJ[:f1(f;c?Xp<E<.%
+=BJ^0>$G6;?!^lF?t!MR@q9+]AnPaiBkhBuCi!s+Df9T7EcQ5CF`hkOG^+L[H[C-gIXcitJV&K+
+KS>,7LPUbCMMmFPNK0'\OHG]iPE_>uQC!u,R]V/@iW"E~>
+J#8s6TV.pKSXc4>R[KS2Q^3r&P`q8nOcYWbNfB!UMi*@ILkg_=KnP)1Jq8H%IsufnI!^0bG^+FU
+F`heIF)l8>E,TW2D/=!&C2%?pB4b^dA7K(X@:3JM?=$oB>?b96=]ea,<`N.!;c?Rl;,C(b:/4MW
+9M7uM8P)HC8,l$h779O26UF+*5sRY!5!D+mr]L3Bs#U0?r]'m9r\ja5rA=I/q(hXuq(hn)rA=L2
+r\ja7s#C!<s#U0As#g<Es$$HIs$6TMs$D$!6psI47Rfm=84cEG91qrQ9hnJ[:f1(f;c?Xp<E<.%
+=BJ^0>$G6;?!^lF?t!MR@q9+]AnPaiBkhBuCi!s+Df9T7EcQ5CF`hkOG^+L[H[C-gIXcitJV&K+
+KS>,7LPUbCMMmFPNK0'\OHG]iPE_>uQC!u,R]V/@iW"E~>
+J#T<AUna]ZTqJ'NSt2FBS!oe6R$X/*Q'@MsP*(lgO,f6[N/NUOM26tCL4t>7K7ec,J:N,uI=6Ki
+H[9s^G^"=SF`_\GEcH)<Df9N1Ci!m%C2%?pB4baeA7T1Z@UWYP?XI,F?!LT<>$5!1=BAO(<E3!t
+;c?Rk;,C(b:]F2i:&doe9E.Wa8cM?]8,c!X7K,^T6iKFN62j.J5Q!_A4n1Z14o@MB5Q3qI62j4M
+6iTRR7K5jW8,c'Z8cME_9E.]c9aOQj:Jakb;,U:jr`!Q2<`W:'=BSd1>?b?;?!^iE?smDP@UiqZ
+AS,OeBP;*pC27X%D/O60E,fl<F)uGGF`qtRG^4U^H[L6iIXcluJV&N,KS>/8LPUbCMMmCONK0$[
+OHGZgPE_;sQC!u+R@9V7S=Q7UJcF^/J,~>
+J#T<AUna]ZTqJ'NSt2FBS!oe6R$X/*Q'@MsP*(lgO,f6[N/NUOM26tCL4t>7K7ec,J:N,uI=6Ki
+H[9s^G^"=SF`_\GEcH)<Df9N1Ci!m%C2%?pB4baeA7T1Z@UWYP?XI,F?!LT<>$5!1=BAO(<E3!t
+;c?Rk;,C(b:]F2i:&doe9E.Wa8cM?]8,c!X7K,^T6iKFN62j.J5Q!_A4n1Z14o@MB5Q3qI62j4M
+6iTRR7K5jW8,c'Z8cME_9E.]c9aOQj:Jakb;,U:jr`!Q2<`W:'=BSd1>?b?;?!^iE?smDP@UiqZ
+AS,OeBP;*pC27X%D/O60E,fl<F)uGGF`qtRG^4U^H[L6iIXcluJV&N,KS>/8LPUbCMMmCONK0$[
+OHGZgPE_;sQC!u+R@9V7S=Q7UJcF^/J,~>
+J#T<AUna]ZTqJ'NSt2FBS!oe6R$X/*Q'@MsP*(lgO,f6[N/NUOM26tCL4t>7K7ec,J:N,uI=6Ki
+H[9s^G^"=SF`_\GEcH)<Df9N1Ci!m%C2%?pB4baeA7T1Z@UWYP?XI,F?!LT<>$5!1=BAO(<E3!t
+;c?Rk;,C(b:]F2i:&doe9E.Wa8cM?]8,c!X7K,^T6iKFN62j.J5Q!_A4n1Z14o@MB5Q3qI62j4M
+6iTRR7K5jW8,c'Z8cME_9E.]c9aOQj:Jakb;,U:jr`!Q2<`W:'=BSd1>?b?;?!^iE?smDP@UiqZ
+AS,OeBP;*pC27X%D/O60E,fl<F)uGGF`qtRG^4U^H[L6iIXcluJV&N,KS>/8LPUbCMMmCONK0$[
+OHGZgPE_;sQC!u+R@9V7S=Q7UJcF^/J,~>
+I]]WLW2QVkVPU)`US=HTTV%gISXc1=R[KP1Q^3r&P`q;oOcYZcNfK*XMi3ILM26qBL4t;6K7\]+
+J:N,uIXQTkH[:!`G^+FUG'.nKF)l;@E,]`5DJa6,CMR[!BkV0mAnGUcA7K+Y@UW\Q?XI,G?!U]?
+>?b97=]nj/s&]5$s&K%ts&8qqr_`Yks%iVhr_<>br_*/]r(6`Um76tCr(6iZrCd,`r_<Aer_NPj
+r_`\nr_rhrr`/u!s&]5&s&oA*s''5C?!UcC?XI2K@:E\U@q9+]AnG[gBPD0qCMRa&D/O60E,]f;
+EcZ;DF`hkOGBeCYH@($eI=?WpJ:N3&JqJ`0KnbA<Ll$tGMi<USNfK0^OcbfjPa%H!QC!u,R@9V8
+S=Q7DT:hmOU9oLOiW"E~>
+I]]WLW2QVkVPU)`US=HTTV%gISXc1=R[KP1Q^3r&P`q;oOcYZcNfK*XMi3ILM26qBL4t;6K7\]+
+J:N,uIXQTkH[:!`G^+FUG'.nKF)l;@E,]`5DJa6,CMR[!BkV0mAnGUcA7K+Y@UW\Q?XI,G?!U]?
+>?b97=]nj/s&]5$s&K%ts&8qqr_`Yks%iVhr_<>br_*/]r(6`Um76tCr(6iZrCd,`r_<Aer_NPj
+r_`\nr_rhrr`/u!s&]5&s&oA*s''5C?!UcC?XI2K@:E\U@q9+]AnG[gBPD0qCMRa&D/O60E,]f;
+EcZ;DF`hkOGBeCYH@($eI=?WpJ:N3&JqJ`0KnbA<Ll$tGMi<USNfK0^OcbfjPa%H!QC!u,R@9V8
+S=Q7DT:hmOU9oLOiW"E~>
+I]]WLW2QVkVPU)`US=HTTV%gISXc1=R[KP1Q^3r&P`q;oOcYZcNfK*XMi3ILM26qBL4t;6K7\]+
+J:N,uIXQTkH[:!`G^+FUG'.nKF)l;@E,]`5DJa6,CMR[!BkV0mAnGUcA7K+Y@UW\Q?XI,G?!U]?
+>?b97=]nj/s&]5$s&K%ts&8qqr_`Yks%iVhr_<>br_*/]r(6`Um76tCr(6iZrCd,`r_<Aer_NPj
+r_`\nr_rhrr`/u!s&]5&s&oA*s''5C?!UcC?XI2K@:E\U@q9+]AnG[gBPD0qCMRa&D/O60E,]f;
+EcZ;DF`hkOGBeCYH@($eI=?WpJ:N3&JqJ`0KnbA<Ll$tGMi<USNfK0^OcbfjPa%H!QC!u,R@9V8
+S=Q7DT:hmOU9oLOiW"E~>
+Ha9iXXf\\*WiE%sW2HMiV50o^U7n9RT:_^GS=H(;R[KP1Q^3o%P`q;oOcb`dO,f3ZN/NUOM2@%D
+LPCM:KS+o/JUr?%IsuipI!g9fH?jd\GB\4RF`__HF)l;@E,]`6DJj<.Chmg$C2%BqBP1siAn>Oa
+A7K+Y@fBg9@/jU5?N4=1>lS%->5h\(=T)>"<rH%p<;KPW;Yj>h<;]bq<rH,!=T2J&>5hb+>lJ%/
+?N4C3@/j[8@fKs<AH-6@B)cNDB`DfHCB&)LCg([nDJsH4E,fo=F)uGFF`qqPGBeCYH@(!dI!pHm
+It3'#JV&N,KS>,7LPL\BM2I4LN/`gWO,oBbP*2#nPa.Q#Q^F/.R[]e:SXl@ETV/!QU8+N\V5C/g
+\:O\=s*t~>
+Ha9iXXf\\*WiE%sW2HMiV50o^U7n9RT:_^GS=H(;R[KP1Q^3o%P`q;oOcb`dO,f3ZN/NUOM2@%D
+LPCM:KS+o/JUr?%IsuipI!g9fH?jd\GB\4RF`__HF)l;@E,]`6DJj<.Chmg$C2%BqBP1siAn>Oa
+A7K+Y@fBg9@/jU5?N4=1>lS%->5h\(=T)>"<rH%p<;KPW;Yj>h<;]bq<rH,!=T2J&>5hb+>lJ%/
+?N4C3@/j[8@fKs<AH-6@B)cNDB`DfHCB&)LCg([nDJsH4E,fo=F)uGFF`qqPGBeCYH@(!dI!pHm
+It3'#JV&N,KS>,7LPL\BM2I4LN/`gWO,oBbP*2#nPa.Q#Q^F/.R[]e:SXl@ETV/!QU8+N\V5C/g
+\:O\=s*t~>
+Ha9iXXf\\*WiE%sW2HMiV50o^U7n9RT:_^GS=H(;R[KP1Q^3o%P`q;oOcb`dO,f3ZN/NUOM2@%D
+LPCM:KS+o/JUr?%IsuipI!g9fH?jd\GB\4RF`__HF)l;@E,]`6DJj<.Chmg$C2%BqBP1siAn>Oa
+A7K+Y@fBg9@/jU5?N4=1>lS%->5h\(=T)>"<rH%p<;KPW;Yj>h<;]bq<rH,!=T2J&>5hb+>lJ%/
+?N4C3@/j[8@fKs<AH-6@B)cNDB`DfHCB&)LCg([nDJsH4E,fo=F)uGFF`qqPGBeCYH@(!dI!pHm
+It3'#JV&N,KS>,7LPL\BM2I4LN/`gWO,oBbP*2#nPa.Q#Q^F/.R[]e:SXl@ETV/!QU8+N\V5C/g
+\:O\=s*t~>
+DR[![Za-j@Yck75Xf\\*WiE%sW2HPjV59u_U8"?STV%gISXc4>R[TY3R$X,)Q'IStPEM&jOH5H_
+NfB!VMi*CKM26qBL5(D8KS+o/JUr?%It)oqI=-EhH[:!`H$FOWG'8"NFEDSFEcQ/>rc%mUs).jR
+rbVUMs(_OIrb2=Erau.@rabt;raPh7r*]G0qHif"qcr_uqd0/,rF#S4rF5b9rac">rau.Bs(MCG
+s(_OKs(q^Ps).gSs)A!Xs)S-\s)e9`s*"Ed<Hre7H?spbI!g?jIXcitJ:W9'K7ei1Knb>;LPUeD
+MMmCON/`jXO-#HcOckolPa.N"Q^=)-R@9V7S=Q4BT:_dMTq\<WUnsobVl-JmWN*#"XKB0es5F!.~>
+DR[![Za-j@Yck75Xf\\*WiE%sW2HPjV59u_U8"?STV%gISXc4>R[TY3R$X,)Q'IStPEM&jOH5H_
+NfB!VMi*CKM26qBL5(D8KS+o/JUr?%It)oqI=-EhH[:!`H$FOWG'8"NFEDSFEcQ/>rc%mUs).jR
+rbVUMs(_OIrb2=Erau.@rabt;raPh7r*]G0qHif"qcr_uqd0/,rF#S4rF5b9rac">rau.Bs(MCG
+s(_OKs(q^Ps).gSs)A!Xs)S-\s)e9`s*"Ed<Hre7H?spbI!g?jIXcitJ:W9'K7ei1Knb>;LPUeD
+MMmCON/`jXO-#HcOckolPa.N"Q^=)-R@9V7S=Q4BT:_dMTq\<WUnsobVl-JmWN*#"XKB0es5F!.~>
+DR[![Za-j@Yck75Xf\\*WiE%sW2HPjV59u_U8"?STV%gISXc4>R[TY3R$X,)Q'IStPEM&jOH5H_
+NfB!VMi*CKM26qBL5(D8KS+o/JUr?%It)oqI=-EhH[:!`H$FOWG'8"NFEDSFEcQ/>rc%mUs).jR
+rbVUMs(_OIrb2=Erau.@rabt;raPh7r*]G0qHif"qcr_uqd0/,rF#S4rF5b9rac">rau.Bs(MCG
+s(_OKs(q^Ps).gSs)A!Xs)S-\s)e9`s*"Ed<Hre7H?spbI!g?jIXcitJ:W9'K7ei1Knb>;LPUeD
+MMmCON/`jXO-#HcOckolPa.N"Q^=)-R@9V7S=Q4BT:_dMTq\<WUnsobVl-JmWN*#"XKB0es5F!.~>
+Cq[Ej\[],X[^ENMZa6sBZ*:F8Y-"h-X/i8"WMl_mVP^2cUnaZYTqS-OT:VUES=H(;R[KS2Q^=#'
+Q'@MsPEM&jOH>N`NfB$WN/NUOM2@%ELPLV=KnY25K7ec-JUr?%It)orI=6KjH[Ga<s*=WhrceBc
+rcS6_rcA'Zrc.pVrbqaQrGDLLrG2:Fqe>_:o4R`0qJ#kBrG2=Irb_UOrbqdTrc.pXrcA*]rcS6a
+rceBes*=Tis*Ocns*aors*t'!s+13%s+C?)s+UK-s+gW17>ZnZMi3OQNK&sZO-#HcOckolPa%H!
+QC!r*R@0M5S"-">St;RITV8'RUSFW]V5C/gW2Q\qWiN5&Xfeh1YctC<ZEqE!s5F!.~>
+Cq[Ej\[],X[^ENMZa6sBZ*:F8Y-"h-X/i8"WMl_mVP^2cUnaZYTqS-OT:VUES=H(;R[KS2Q^=#'
+Q'@MsPEM&jOH>N`NfB$WN/NUOM2@%ELPLV=KnY25K7ec-JUr?%It)orI=6KjH[Ga<s*=WhrceBc
+rcS6_rcA'Zrc.pVrbqaQrGDLLrG2:Fqe>_:o4R`0qJ#kBrG2=Irb_UOrbqdTrc.pXrcA*]rcS6a
+rceBes*=Tis*Ocns*aors*t'!s+13%s+C?)s+UK-s+gW17>ZnZMi3OQNK&sZO-#HcOckolPa%H!
+QC!r*R@0M5S"-">St;RITV8'RUSFW]V5C/gW2Q\qWiN5&Xfeh1YctC<ZEqE!s5F!.~>
+Cq[Ej\[],X[^ENMZa6sBZ*:F8Y-"h-X/i8"WMl_mVP^2cUnaZYTqS-OT:VUES=H(;R[KS2Q^=#'
+Q'@MsPEM&jOH>N`NfB$WN/NUOM2@%ELPLV=KnY25K7ec-JUr?%It)orI=6KjH[Ga<s*=WhrceBc
+rcS6_rcA'Zrc.pVrbqaQrGDLLrG2:Fqe>_:o4R`0qJ#kBrG2=Irb_UOrbqdTrc.pXrcA*]rcS6a
+rceBes*=Tis*Ocns*aors*t'!s+13%s+C?)s+UK-s+gW17>ZnZMi3OQNK&sZO-#HcOckolPa%H!
+QC!r*R@0M5S"-">St;RITV8'RUSFW]V5C/gW2Q\qWiN5&Xfeh1YctC<ZEqE!s5F!.~>
+?c0[p^V7Fq]Y(kg]",A]\$rfR[C!9HZE^[=Yck44XfSV)X/`.uW2QVlVPU,bUnaZYTqS-PT:VXF
+SXc4>R[TY4R$a5,QBd`"P`q;oP*(lgOH5H_NfB$WN/NUOMZ/J4M#W81LAlo,K`6W(K)U?$JGt&t
+If=cpI/\KlHMr-fGl;jaG5HFZFS9eCEqXSNFSp:ZG5ZX`Gl;peHN&9jI/\QnIf=isJGt-"K)UE&
+K`6]*LB!&/M#W>2MZ8V7N;nn;NrP1?OT1ICP5g_2Pa.N"QC!r*R$jA2S"#q<SXl@ET:hjNTq\<W
+UnjiaVPg>jW2ZesX/rD)Xfek2Yd(I=ZEppF[C3NQ\@B)\a+=9Ls*t~>
+?c0[p^V7Fq]Y(kg]",A]\$rfR[C!9HZE^[=Yck44XfSV)X/`.uW2QVlVPU,bUnaZYTqS-PT:VXF
+SXc4>R[TY4R$a5,QBd`"P`q;oP*(lgOH5H_NfB$WN/NUOMZ/J4M#W81LAlo,K`6W(K)U?$JGt&t
+If=cpI/\KlHMr-fGl;jaG5HFZFS9eCEqXSNFSp:ZG5ZX`Gl;peHN&9jI/\QnIf=isJGt-"K)UE&
+K`6]*LB!&/M#W>2MZ8V7N;nn;NrP1?OT1ICP5g_2Pa.N"QC!r*R$jA2S"#q<SXl@ET:hjNTq\<W
+UnjiaVPg>jW2ZesX/rD)Xfek2Yd(I=ZEppF[C3NQ\@B)\a+=9Ls*t~>
+?c0[p^V7Fq]Y(kg]",A]\$rfR[C!9HZE^[=Yck44XfSV)X/`.uW2QVlVPU,bUnaZYTqS-PT:VXF
+SXc4>R[TY4R$a5,QBd`"P`q;oP*(lgOH5H_NfB$WN/NUOMZ/J4M#W81LAlo,K`6W(K)U?$JGt&t
+If=cpI/\KlHMr-fGl;jaG5HFZFS9eCEqXSNFSp:ZG5ZX`Gl;peHN&9jI/\QnIf=isJGt-"K)UE&
+K`6]*LB!&/M#W>2MZ8V7N;nn;NrP1?OT1ICP5g_2Pa.N"QC!r*R$jA2S"#q<SXl@ET:hjNTq\<W
+UnjiaVPg>jW2ZesX/rD)Xfek2Yd(I=ZEppF[C3NQ\@B)\a+=9Ls*t~>
+43PaeaN)?@`Pod5_ns7+^qd_!^:h4m]=YYb\[]/Y[^NTO['R*EZE^[=YHP+3Xf\\*X/`2!WMlbn
+Vu<LmV>m>"US=KVTqJ'NT:VXFSc5/ZS,\rWRK&ZSQi<<NQ2d*JPQ-gFOoLOBO8b1=NW+n9MuJV5
+M>`80L])u*L&?VsKD0u\JbOchKD^E#L&Hc*L]*&.M>iD3MuJ\7NW+t<O8b7?OoLUEPQ$gHQ2d0L
+QiEHQRK&`US,]#YSc>;]TDtSaU&UkeU]7.iV>[:kVZ<[pW@FpKX/rD)Xfek2YctC;ZEpmE['d?N
+\$rlX\[oAa]Y(ql^;%Fu_84"+c@Q#Ss*t~>
+43PaeaN)?@`Pod5_ns7+^qd_!^:h4m]=YYb\[]/Y[^NTO['R*EZE^[=YHP+3Xf\\*X/`2!WMlbn
+Vu<LmV>m>"US=KVTqJ'NT:VXFSc5/ZS,\rWRK&ZSQi<<NQ2d*JPQ-gFOoLOBO8b1=NW+n9MuJV5
+M>`80L])u*L&?VsKD0u\JbOchKD^E#L&Hc*L]*&.M>iD3MuJ\7NW+t<O8b7?OoLUEPQ$gHQ2d0L
+QiEHQRK&`US,]#YSc>;]TDtSaU&UkeU]7.iV>[:kVZ<[pW@FpKX/rD)Xfek2YctC;ZEpmE['d?N
+\$rlX\[oAa]Y(ql^;%Fu_84"+c@Q#Ss*t~>
+43PaeaN)?@`Pod5_ns7+^qd_!^:h4m]=YYb\[]/Y[^NTO['R*EZE^[=YHP+3Xf\\*X/`2!WMlbn
+Vu<LmV>m>"US=KVTqJ'NT:VXFSc5/ZS,\rWRK&ZSQi<<NQ2d*JPQ-gFOoLOBO8b1=NW+n9MuJV5
+M>`80L])u*L&?VsKD0u\JbOchKD^E#L&Hc*L]*&.M>iD3MuJ\7NW+t<O8b7?OoLUEPQ$gHQ2d0L
+QiEHQRK&`US,]#YSc>;]TDtSaU&UkeU]7.iV>[:kVZ<[pW@FpKX/rD)Xfek2YctC;ZEpmE['d?N
+\$rlX\[oAa]Y(ql^;%Fu_84"+c@Q#Ss*t~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+s8N)iJa\0YRdU7Lqu6cqcFW&^rrMhro)A`qo?mR<W8IW*~>
+JcC<$OT,F[cFW&^rrMhro)A`qo?mR<W8IW*~>
+s8N)iJa\0YRdU7Lqu6cqcFW&^rrMhro)A`qo?mR<W8IW*~>
+s8N'PJH16$RK*=hr;QrW4b8i*T[<]>or.H]!Nbk>rr>"8s*t~>
+JcC<$OoGUA4b8i*T[<]>or.H]!Nbk>rr>"8s*t~>
+s8N'PJH16$RK*=hr;QrW4b8i*T[<]>or.H]!Nbk>rr>"8s*t~>
+s8N'PJH16$RK*=hr;Qds]`.pFr;U\q>l&hIAaTN1;H(4-Q&JgQpAP!kPPtM(YDH`&E<#rmjO8Wh
+9[<ZlNE0inn9Y+jNE0cks,pZAD>jJ=J*YF3@SG2Jrt9;Ns*=.c=^Qd\hHNs@s29V&X8`,8D15Eg
+N`)5Dpig+coDb^kI5(]tHW4VFjo9i~>
+JcC<$OoGG]]`.pFr;U\q>l&hIAaTN1;H(4-Q&JgQpAP!kPPtM(YDH`&E<#rmjO8Wh9[<ZlNE0in
+n9Y+jNE0cks,pZAD>jJ=J*YF3@SG2Jrt9;Ns*=.c=^Qd\hHNs@s29V&X8`,8D15EgN`)5Dpig+c
+oDb^kI5(]tHW4VFjo9i~>
+s8N'PJH16$RK*=hr;Qds]`.pFr;U\q>l&hIAaTN1;H(4-Q&JgQpAP!kPPtM(YDH`&E<#rmjO8Wh
+9[<ZlNE0inn9Y+jNE0cks,pZAD>jJ=J*YF3@SG2Jrt9;Ns*=.c=^Qd\hHNs@s29V&X8`,8D15Eg
+N`)5Dpig+coDb^kI5(]tHW4VFjo9i~>
+s8N'PJH16$RK*=hr;RWUqu=a8`r@X4s,Ds:YB&nep@^3:CjuD/Vu?VqK`1onO(\Lm2uinYftoH;
+c;FUBPlG4+ksk\UOoK"(buXkq*W?!B:#`fCprHP8rt.3is$Z0pZ2a\#45Bg<b,e;8rVmZNfCooi
+r%%N!NW5Ppj[/n+$ic-Es/gD)s*t~>
+JcC<$OoH:?qu=a8`r@X4s,Ds:YB&nep@^3:CjuD/Vu?VqK`1onO(\Lm2uinYftoH;c;FUBPlG4+
+ksk\UOoK"(buXkq*W?!B:#`fCprHP8rt.3is$Z0pZ2a\#45Bg<b,e;8rVmZNfCooir%%N!NW5Pp
+j[/n+$ic-Es/gD)s*t~>
+s8N'PJH16$RK*=hr;RWUqu=a8`r@X4s,Ds:YB&nep@^3:CjuD/Vu?VqK`1onO(\Lm2uinYftoH;
+c;FUBPlG4+ksk\UOoK"(buXkq*W?!B:#`fCprHP8rt.3is$Z0pZ2a\#45Bg<b,e;8rVmZNfCooi
+r%%N!NW5Ppj[/n+$ic-Es/gD)s*t~>
+s8N'PJH16$RK*=hr;RWdmJkFe>5pJ[s&WNFD1TDUDf8hDCru^PPkb8$O/;mV2uinXftqh1qE=jZ
+huA\8ksk\Uh#EM6V2bNT0E(nT:#`g1s7A\Wrt%-hs$H&0@7dX#(N45$]r[%frtdQms#0oW:Zu34
+s5-G`F8u7ns&EEED1^mLJ,~>
+JcC<$OoH:NmJkFe>5pJ[s&WNFD1TDUDf8hDCru^PPkb8$O/;mV2uinXftqh1qE=jZhuA\8ksk\U
+h#EM6V2bNT0E(nT:#`g1s7A\Wrt%-hs$H&0@7dX#(N45$]r[%frtdQms#0oW:Zu34s5-G`F8u7n
+s&EEED1^mLJ,~>
+s8N'PJH16$RK*=hr;RWdmJkFe>5pJ[s&WNFD1TDUDf8hDCru^PPkb8$O/;mV2uinXftqh1qE=jZ
+huA\8ksk\Uh#EM6V2bNT0E(nT:#`g1s7A\Wrt%-hs$H&0@7dX#(N45$]r[%frtdQms#0oW:Zu34
+s5-G`F8u7ns&EEED1^mLJ,~>
+s8N)<J[^3>R^W:Dr;RXnDZ0UP>5pP]s+Hd>s7bV<qZ$<iCs2jSPPtL]`VofZO/W*Y1[=WNftqn3
+qE=jZiW"q;ksk\UhZ&_8dSKhc*<#mA:#`g4s7A\Wrt$UOmge[Xs7n&B3TL/<q5fMPrtdWos#9uX
+:[!P!s/'qu7K)EZs+6^>s7bXTJ,~>
+JcC<$OoH;XDZ0UP>5pP]s+Hd>s7bV<qZ$<iCs2jSPPtL]`VofZO/W*Y1[=WNftqn3qE=jZiW"q;
+ksk\UhZ&_8dSKhc*<#mA:#`g4s7A\Wrt$UOmge[Xs7n&B3TL/<q5fMPrtdWos#9uX:[!P!s/'qu
+7K)EZs+6^>s7bXTJ,~>
+s8N)<J[^3>R^W:Dr;RXnDZ0UP>5pP]s+Hd>s7bV<qZ$<iCs2jSPPtL]`VofZO/W*Y1[=WNftqn3
+qE=jZiW"q;ksk\UhZ&_8dSKhc*<#mA:#`g4s7A\Wrt$UOmge[Xs7n&B3TL/<q5fMPrtdWos#9uX
+:[!P!s/'qu7K)EZs+6^>s7bXTJ,~>
+JcC<$OoH<tPuV$taT#uSs7^M?@&s=5=(#eCOkB]GY5SA#;>pM;X1nW6\3XVBimF.nqelFal2Rcu
+mr\S^k5VQrs.Ne[3W8s^H0WYEs7^R4rt)4uBP-as?<!6jeluNhik_SkrtfDLs(VN5Hg^N?>\*='
+R8\-5s7^M?@'&JiJ,~>
+JcC<$OoH<tPuV$taT#uSs7^M?@&s=5=(#eCOkB]GY5SA#;>pM;X1nW6\3XVBimF.nqelFal2Rcu
+mr\S^k5VQrs.Ne[3W8s^H0WYEs7^R4rt)4uBP-as?<!6jeluNhik_SkrtfDLs(VN5Hg^N?>\*='
+R8\-5s7^M?@'&JiJ,~>
+JcC<$OoH<tPuV$taT#uSs7^M?@&s=5=(#eCOkB]GY5SA#;>pM;X1nW6\3XVBimF.nqelFal2Rcu
+mr\S^k5VQrs.Ne[3W8s^H0WYEs7^R4rt)4uBP-as?<!6jeluNhik_SkrtfDLs(VN5Hg^N?>\*='
+R8\-5s7^M?@'&JiJ,~>
+JcC<$JcF-t"1?I4EN&nf~>
+JcC<$JcF-t"1?I4EN&nf~>
+JcC<$JcF-t"1?I4EN&nf~>
+JcC<$JcF-t"2C/.ri#jI~>
+JcC<$JcF-t"2C/.ri#jI~>
+JcC<$JcF-t"2C/.ri#jI~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$L]7D3qYC-lr8%>O!U0%+rrMoQo)AaFrPSX;f`1+)rVqB~>
+JcC<$L]7D3qYC-lr8%>O!U0%+rrMoQo)AaFrPSX;f`1+)rVqB~>
+JcC<$L]7D3qYC-lr8%>O!U0%+rrMoQo)AaFrPSX;f`1+)rVqB~>
+s8N'QJH:<&RK3Cjr;QjF=$D*1rrGdRq>UK`8cAYiK!!`+!TSt+rrI08ir9%d]B&to0E67+rVqB~>
+s8N)'JY%FaR[sMor;QjF=$D*1rrGdRq>UK`8cAYiK!!`+!TSt+rrI08ir9%d]B&to0E67+rVqB~>
+JcC<$OoGM0=$D*1rrGdRq>UK`8cAYiK!!`+!TSt+rrI08ir9%d]B&to0E67+rVqB~>
+s8N'QJH:<&RK3Cjr;R<Us8F4uR!,"ss%DGQaaKTQrr3Su8>:Xns+7BDYlF`ps8T?MXo88#r6YEB
++Mu'LfV8EGW:nrYNJR-)VoO4ms6[)kWQ0Fms8Tr`^nUf-#,D%I^Pn'ArVltuG*)@pruT1*J`=!"
+s88JgWcj<p;cSVNl%k#Qs1QC&ZK[+7rr)j+d=?i5l%sYps8ObPGI[VOJ,~>
+s8N)'JY%FaR[sMor;R<Us8F4uR!,"ss%DGQaaKTQrr3Su8>:Xns+7BDYlF`ps8T?MXo88#r6YEB
++Mu'LfV8EGW:nrYNJR-)VoO4ms6[)kWQ0Fms8Tr`^nUf-#,D%I^Pn'ArVltuG*)@pruT1*J`=!"
+s88JgWcj<p;cSVNl%k#Qs1QC&ZK[+7rr)j+d=?i5l%sYps8ObPGI[VOJ,~>
+JcC<$OoGt?s8F4uR!,"ss%DGQaaKTQrr3Su8>:Xns+7BDYlF`ps8T?MXo88#r6YEB+Mu'LfV8EG
+W:nrYNJR-)VoO4ms6[)kWQ0Fms8Tr`^nUf-#,D%I^Pn'ArVltuG*)@pruT1*J`=!"s88JgWcj<p
+;cSVNl%k#Qs1QC&ZK[+7rr)j+d=?i5l%sYps8ObPGI[VOJ,~>
+s8N'QJH:<&RK3Cjr;R<Tn&Q@3_rH*!s%DFp8C`l@rr3W!%`H^Mq1>a.<WE(Ps-IQTB;>J+!VBCj
+ruc_jh=<N)s$Z1W/Bj#os$V+`2rE4hs$q4`3S`(Pj-D=rrrtRWW\D\PHN!jG`9!@srr4)9/`5@F
+Xa^;OIE5@Kd.W-OhtK%Ea#3g8>Ll)Ke5s$VrsmOBgt1`Ne([F8s"FCr\GcGX~>
+s8N)'JY%FaR[sMor;R<Tn&Q@3_rH*!s%DFp8C`l@rr3W!%`H^Mq1>a.<WE(Ps-IQTB;>J+!VBCj
+ruc_jh=<N)s$Z1W/Bj#os$V+`2rE4hs$q4`3S`(Pj-D=rrrtRWW\D\PHN!jG`9!@srr4)9/`5@F
+Xa^;OIE5@Kd.W-OhtK%Ea#3g8>Ll)Ke5s$VrsmOBgt1`Ne([F8s"FCr\GcGX~>
+JcC<$OoGt>n&Q@3_rH*!s%DFp8C`l@rr3W!%`H^Mq1>a.<WE(Ps-IQTB;>J+!VBCjruc_jh=<N)
+s$Z1W/Bj#os$V+`2rE4hs$q4`3S`(Pj-D=rrrtRWW\D\PHN!jG`9!@srr4)9/`5@FXa^;OIE5@K
+d.W-OhtK%Ea#3g8>Ll)Ke5s$VrsmOBgt1`Ne([F8s"FCr\GcGX~>
+s8N'QJH:<&RK3Cjr;R<F?uaBbEaE-Qs%DEu8oJT0rr3W!56(Xee:Og^<WE(Ps$U=7>\s38+FUQq
+s#9uX7-h(*s5[#V7-X_r^"6Bd8*9hu\Wrcdr@n3M#!;IWK)a\.rr3-#K3N4KrVmpT<i,Zk3r)2+
+oMAu/s-BAYa=(tF/`:W]s+R9KV2tWU!K3`Prs@OiA4)^`0E67+rVqB~>
+s8N)'JY%FaR[sMor;R<F?uaBbEaE-Qs%DEu8oJT0rr3W!56(Xee:Og^<WE(Ps$U=7>\s38+FUQq
+s#9uX7-h(*s5[#V7-X_r^"6Bd8*9hu\Wrcdr@n3M#!;IWK)a\.rr3-#K3N4KrVmpT<i,Zk3r)2+
+oMAu/s-BAYa=(tF/`:W]s+R9KV2tWU!K3`Prs@OiA4)^`0E67+rVqB~>
+JcC<$OoGt0?uaBbEaE-Qs%DEu8oJT0rr3W!56(Xee:Og^<WE(Ps$U=7>\s38+FUQqs#9uX7-h(*
+s5[#V7-X_r^"6Bd8*9hu\Wrcdr@n3M#!;IWK)a\.rr3-#K3N4KrVmpT<i,Zk3r)2+oMAu/s-BAY
+a=(tF/`:W]s+R9KV2tWU!K3`Prs@OiA4)^`0E67+rVqB~>
+s8N)(JY.LcR\'Sqr;QaErr3;,F8s$Ps%DF3S,<3rmO%u66f`j$l9>77)uj!dp&?._])Vd[rr*r(
+Y_W8B:]EiSs*VH1=T:n\s*qP[J,eCWrVm'`oW!oNi`6!X"OL!Fi[t*.#4H_us,qJ/rr35_9?N]k
+s4U0Frs*P`s,!oYWK-uX!M>)Frs<GKs*U%10E67+rVqB~>
+s8N)XJ_G\/Rb@c)r;QaErr3;,F8s$Ps%DF3S,<3rmO%u66f`j$l9>77)uj!dp&?._])Vd[rr*r(
+Y_W8B:]EiSs*VH1=T:n\s*qP[J,eCWrVm'`oW!oNi`6!X"OL!Fi[t*.#4H_us,qJ/rr35_9?N]k
+s4U0Frs*P`s,!oYWK-uX!M>)Frs<GKs*U%10E67+rVqB~>
+JcC<$OoGD/rr3;,F8s$Ps%DF3S,<3rmO%u66f`j$l9>77)uj!dp&?._])Vd[rr*r(Y_W8B:]EiS
+s*VH1=T:n\s*qP[J,eCWrVm'`oW!oNi`6!X"OL!Fi[t*.#4H_us,qJ/rr35_9?N]ks4U0Frs*P`
+s,!oYWK-uX!M>)Frs<GKs*U%10E67+rVqB~>
+JcC<$OoGD/rr3D_1icu#s%DGE9l4j1rr3W!-=g>#s+7BQ;-@9Rs4B_^BsI[;!V%N8ruca$s8R:9
+>:/[?L]?R6s$ZJYI(S!4s$uSYJ%5A[?Z\7*rrtRWWf@&<<W<"$n2G<(0E1tnku`*o_>j-=bQ#Ce
+F$8^94^\)8=Ee-PEQ8$8Y5bJ]rr3K';.s^lW]tGmPQ*<9GI[VOJ,~>
+JcC<$OoGD/rr3D_1icu#s%DGE9l4j1rr3W!-=g>#s+7BQ;-@9Rs4B_^BsI[;!V%N8ruca$s8R:9
+>:/[?L]?R6s$ZJYI(S!4s$uSYJ%5A[?Z\7*rrtRWWf@&<<W<"$n2G<(0E1tnku`*o_>j-=bQ#Ce
+F$8^94^\)8=Ee-PEQ8$8Y5bJ]rr3K';.s^lW]tGmPQ*<9GI[VOJ,~>
+JcC<$OoGD/rr3D_1icu#s%DGE9l4j1rr3W!-=g>#s+7BQ;-@9Rs4B_^BsI[;!V%N8ruca$s8R:9
+>:/[?L]?R6s$ZJYI(S!4s$uSYJ%5A[?Z\7*rrtRWWf@&<<W<"$n2G<(0E1tnku`*o_>j-=bQ#Ce
+F$8^94^\)8=Ee-PEQ8$8Y5bJ]rr3K';.s^lW]tGmPQ*<9GI[VOJ,~>
+JcC<$JcE[g"6oisA**^khFl>tJ,~>
+JcC<$JcE[g"6oisA**^khFl>tJ,~>
+JcC<$JcE[g"6oisA**^khFl>tJ,~>
+JcC<$JcE[g"+Om-nE0`PcY2(^s*t~>
+JcC<$JcE[g"+Om-nE0`PcY2(^s*t~>
+JcC<$JcE[g"+Om-nE0`PcY2(^s*t~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$L]7J>nbh1orrMoQo)AaEric?P~>
+JcC<$L]7J>nbh1orrMoQo)AaEric?P~>
+JcC<$L]7J>nbh1orrMoQo)AaEric?P~>
+JcC<$OoGT#[/]tmh>R?UI'`0,fDbm1M":QHEV],(!-#dSJ,~>
+JcC<$OoGT#[/]tmh>R?UI'`0,fDbm1M":QHEV],(!-#dSJ,~>
+s8N'^JImADRLfI/r;Qq9[/]tmh>R?UI'`0,fDbm1M":QHEV],(!-#dSJ,~>
+JcC<$OoH?j3TYLTm>?MQs*V0>6iZqJIaJ,$mehq<nZ`#m!W:=Cruf1sKA!"!s/5VE^5\!?s/3nc
+[K#U!s/<tdZiC'AI)2QUrs#4pf>!6$oDS[kVfn3prr3S]*J^oP^Q#tIH@k)TftE9&p<inj~>
+JcC<$OoH?j3TYLTm>?MQs*V0>6iZqJIaJ,$mehq<nZ`#m!W:=Cruf1sKA!"!s/5VE^5\!?s/3nc
+[K#U!s/<tdZiC'AI)2QUrs#4pf>!6$oDS[kVfn3prr3S]*J^oP^Q#tIH@k)TftE9&p<inj~>
+s8N'QJH:<&RK3Cjr;R]+3TYLTm>?MQs*V0>6iZqJIaJ,$mehq<nZ`#m!W:=Cruf1sKA!"!s/5VE
+^5\!?s/3nc[K#U!s/<tdZiC'AI)2QUrs#4pf>!6$oDS[kVfn3prr3S]*J^oP^Q#tIH@k)TftE9&
+p<inj~>
+JcC<$OT-3C1KXH5]ZN),I'`0,s')2R389Ok`ZN!tMZ3VVo2knj+F@2Ho/H^L6LCp.c&$WD6@.3@
+i72$27<d?Ch9ndQPVE(9#!)CU1!YH"rVlu<jd'NXrt4oYhs.7#f'UcC__D+m1#/[1dJn^~>
+JcC<$OT-3C1KXH5]ZN),I'`0,s')2R389Ok`ZN!tMZ3VVo2knj+F@2Ho/H^L6LCp.c&$WD6@.3@
+i72$27<d?Ch9ndQPVE(9#!)CU1!YH"rVlu<jd'NXrt4oYhs.7#f'UcC__D+m1#/[1dJn^~>
+s8N'QJH:<&RK3Cjqu7PY1KXH5]ZN),I'`0,s')2R389Ok`ZN!tMZ3VVo2knj+F@2Ho/H^L6LCp.
+c&$WD6@.3@i72$27<d?Ch9ndQPVE(9#!)CU1!YH"rVlu<jd'NXrt4oYhs.7#f'UcC__D+m1#/[1
+dJn^~>
+JcC<$O8g%lc-mnUD_]gjZg:'Z0E;'7R+PYnVKl\!q#;I`[/^.bs8PFQY(-K2;ZB)Ls)u0->5q%T
+s*;5?TE"gDrVm'^p8EZEh,s[V"TF!WDDV7k&30^iX+gTRX&s-VnZ@<@s"De"J,~>
+JcC<$O8g%lc-mnUD_]gjZg:'Z0E;'7R+PYnVKl\!q#;I`[/^.bs8PFQY(-K2;ZB)Ls)u0->5q%T
+s*;5?TE"gDrVm'^p8EZEh,s[V"TF!WDDV7k&30^iX+gTRX&s-VnZ@<@s"De"J,~>
+s8N'QJH:<&RK3CjqYqC-c-mnUD_]gjZg:'Z0E;'7R+PYnVKl\!q#;I`[/^.bs8PFQY(-K2;ZB)L
+s)u0->5q%Ts*;5?TE"gDrVm'^p8EZEh,s[V"TF!WDDV7k&30^iX+gTRX&s-VnZ@<@s"De"J,~>
+JcC<$O8f;Ycf@FkrssL`lpLe.o`'-:s#!XP:c.qH+FCd$s!n$H*:9ncs5m2Y6M:A)^"$<d7IpJ,
+\uL>]h(J[+#!)CUO8n->rr3,H;ZGZ.rVmEjq#@CRs8ODArZgj5BE.W[dJn^~>
+JcC<$O8f;Ycf@FkrssL`lpLe.o`'-:s#!XP:c.qH+FCd$s!n$H*:9ncs5m2Y6M:A)^"$<d7IpJ,
+\uL>]h(J[+#!)CUO8n->rr3,H;ZGZ.rVmEjq#@CRs8ODArZgj5BE.W[dJn^~>
+s8N(pJWGACRZ@HWqYpXocf@FkrssL`lpLe.o`'-:s#!XP:c.qH+FCd$s!n$H*:9ncs5m2Y6M:A)
+^"$<d7IpJ,\uL>]h(J[+#!)CUO8n->rr3,H;ZGZ.rVmEjq#@CRs8ODArZgj5BE.W[dJn^~>
+JcC<$O8g"mci8c#G?k&nZg:'ZY!m)$qYt29s(>a<rrMR:rVn!e]`8"S9Nrk2Y)32@;?&uUs*DB/
+>5q%^s*_KU>$uJ4rVm'^p8F&Pi)fpX"Re6fDD1tg&;a,IX,R)Y<Foehm]ATg6`\W7J,~>
+JcC<$O8g"mci8c#G?k&nZg:'ZY!m)$qYt29s(>a<rrMR:rVn!e]`8"S9Nrk2Y)32@;?&uUs*DB/
+>5q%^s*_KU>$uJ4rVm'^p8F&Pi)fpX"Re6fDD1tg&;a,IX,R)Y<Foehm]ATg6`\W7J,~>
+JcC<$O8g"mci8c#G?k&nZg:'ZY!m)$qYt29s(>a<rrMR:rVn!e]`8"S9Nrk2Y)32@;?&uUs*DB/
+>5q%^s*_KU>$uJ4rVm'^p8F&Pi)fpX"Re6fDD1tg&;a,IX,R)Y<Foehm]ATg6`\W7J,~>
+JcC<$MuNkSkl1GY!W)6LrrMQeli.(Os0uY2rrN#`oD]'\rr<##MY?bjs*t~>
+JcC<$MuNkSkl1GY!W)6LrrMQeli.(Os0uY2rrN#`oD]'\rr<##MY?bjs*t~>
+JcC<$MuNkSkl1GY!W)6LrrMQeli.(Os0uY2rrN#`oD]'\rr<##MY?bjs*t~>
+JcC<$JcF*s"+Fg-n_X9Ha03egJ,~>
+JcC<$JcF*s"+Fg-n_X9Ha03egJ,~>
+JcC<$JcF*s"+Fg-n_X9Ha03egJ,~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$O8f7Zr5ns>gA_$M!U'",s8W&Gs*t~>
+JcC<$O8f7Zr5ns>gA_$M!U'",s8W&Gs*t~>
+JcC<$O8f7Zr5ns>gA_$M!U'",s8W&Gs*t~>
+JcC<$OoGUV?rpK8n&t_3E;BG3!Md]srslVes&Vof;"FYV?<C<8n^RSh~>
+s8N(]JTlZhRWeb/r;Qrl?rpK8n&t_3E;BG3!Md]srslVes&Vof;"FYV?<C<8n^RSh~>
+s8N'qJL?!rRO8)Ur;Qrl?rpK8n&t_3E;BG3!Md]srslVes&Vof;"FYV?<C<8n^RSh~>
+JcC<$OoHJ>QiI)YBE+sOI.N_KSGW>da*k2ls205uUAt7lHFEeP!Vk1Cs!HHKHd;ZRKnedj\Aj',
+d/X->q4dfe_0_%4_qOjbV1%+ur0`2R`r>uEr0MSur;W_9IC&nP%^g?W9\]STUAnnts8SR)eGk%~>
+s8N(HJR3n6RU,uZr;RgTQiI)YBE+sOI.N_KSGW>da*k2ls205uUAt7lHFEeP!Vk1Cs!HHKHd;ZR
+Knedj\Aj',d/X->q4dfe_0_%4_qOjbV1%+ur0`2R`r>uEr0MSur;W_9IC&nP%^g?W9\]STUAnnt
+s8SR)eGk%~>
+s8N'PJH16$RK*=hr;RgTQiI)YBE+sOI.N_KSGW>da*k2ls205uUAt7lHFEeP!Vk1Cs!HHKHd;ZR
+Knedj\Aj',d/X->q4dfe_0_%4_qOjbV1%+ur0`2R`r>uEr0MSur;W_9IC&nP%^g?W9\]STUAnnt
+s8SR)eGk%~>
+JcC<$OoHLJp](9i*</Q]htY+LH\_VnF4WJ+ejJGa/H:?LfiY`_rrM4mrVn3'dH'$Q2T3Kls(6!&
+d89l)6iT.?ZrH)2o7+"4$ami2s*fpe9SNKG$Mq^$GDuPjGLnh1rr3J9ErSh=]J\.;+T)3=p)qlb
+J,~>
+s8N(HJR3n6RU,uZr;Ri`p](9i*</Q]htY+LH\_VnF4WJ+ejJGa/H:?LfiY`_rrM4mrVn3'dH'$Q
+2T3Kls(6!&d89l)6iT.?ZrH)2o7+"4$ami2s*fpe9SNKG$Mq^$GDuPjGLnh1rr3J9ErSh=]J\.;
++T)3=p)qlbJ,~>
+s8N'PJH16$RK*=hr;Ri`p](9i*</Q]htY+LH\_VnF4WJ+ejJGa/H:?LfiY`_rrM4mrVn3'dH'$Q
+2T3Kls(6!&d89l)6iT.?ZrH)2o7+"4$ami2s*fpe9SNKG$Mq^$GDuPjGLnh1rr3J9ErSh=]J\.;
++T)3=p)qlbJ,~>
+JcC<$OoHLHq>^Kl)ZN@ls7gS??r[.uj8XS:R%+-T0E3b@DcD2\rt^VjP4?4;Df7)jB$1/R7HK0"
+s#BaaaSu2JJ$A?)s8OtV4SJfRL&V)ZpMXAE=oUqSs*;6UrslGWs%I9A8c8T0r;Zfl(tAS9~>
+s8N(HJR3n6RU,uZr;Ri^q>^Kl)ZN@ls7gS??r[.uj8XS:R%+-T0E3b@DcD2\rt^VjP4?4;Df7)j
+B$1/R7HK0"s#BaaaSu2JJ$A?)s8OtV4SJfRL&V)ZpMXAE=oUqSs*;6UrslGWs%I9A8c8T0r;Zfl
+(tAS9~>
+s8N'PJH16$RK*=hr;Ri^q>^Kl)ZN@ls7gS??r[.uj8XS:R%+-T0E3b@DcD2\rt^VjP4?4;Df7)j
+B$1/R7HK0"s#BaaaSu2JJ$A?)s8OtV4SJfRL&V)ZpMXAE=oUqSs*;6UrslGWs%I9A8c8T0r;Zfl
+(tAS9~>
+JcC<$OoHD2U]:@p?2mIas/^;A^JOr&mJhdGYC-B0.fVoso`#'gSRTrIrVm:<dJs6GJ2R0&3;7]u
+rr3CVYjP*_s#9sVf`-\[rr3>'GlP?Ts$cMYICfFX%^g?W9\]SuN;m1^s8Ss'eGk%~>
+s8N)4JZaR,R]ZY5r;RaHU]:@p?2mIas/^;A^JOr&mJhdGYC-B0.fVoso`#'gSRTrIrVm:<dJs6G
+J2R0&3;7]urr3CVYjP*_s#9sVf`-\[rr3>'GlP?Ts$cMYICfFX%^g?W9\]SuN;m1^s8Ss'eGk%~>
+s8N(cJU`6#RXY=<r;RaHU]:@p?2mIas/^;A^JOr&mJhdGYC-B0.fVoso`#'gSRTrIrVm:<dJs6G
+J2R0&3;7]urr3CVYjP*_s#9sVf`-\[rr3>'GlP?Ts$cMYICfFX%^g?W9\]SuN;m1^s8Ss'eGk%~>
+JcC<$OoHNk;dWs/lMjEDs4fGO?r6kqmJhdGr*3TM2ZLuhGA"YhrrLq:rVn3NF\A5(F^'$$s(9[Y
+s8!g\s8P(QksTK%l@6&+8cSfLs3sPO</U\T$J@7W?<."oo)F-Lrr3J9ErShfs7Ru2lqq.s8FG"-
+J,~>
+JcC<$OoHNk;dWs/lMjEDs4fGO?r6kqmJhdGr*3TM2ZLuhGA"YhrrLq:rVn3NF\A5(F^'$$s(9[Y
+s8!g\s8P(QksTK%l@6&+8cSfLs3sPO</U\T$J@7W?<."oo)F-Lrr3J9ErShfs7Ru2lqq.s8FG"-
+J,~>
+JcC<$OoHNk;dWs/lMjEDs4fGO?r6kqmJhdGr*3TM2ZLuhGA"YhrrLq:rVn3NF\A5(F^'$$s(9[Y
+s8!g\s8P(QksTK%l@6&+8cSfLs3sPO</U\T$J@7W?<."oo)F-Lrr3J9ErShfs7Ru2lqq.s8FG"-
+J,~>
+JcC<$O8f7Ro_SRgq!\"X"6oj!@/g0,l1k#Q!rhHWrr3#nl14iTlhL8T"S;?cA%_d?!Vl-Lrr_ns
+7eP:2J,~>
+JcC<$O8f7Ro_SRgq!\"X"6oj!@/g0,l1k#Q!rhHWrr3#nl14iTlhL8T"S;?cA%_d?!Vl-Lrr_ns
+7eP:2J,~>
+JcC<$O8f7Ro_SRgq!\"X"6oj!@/g0,l1k#Q!rhHWrr3#nl14iTlhL8T"S;?cA%_d?!Vl-Lrr_ns
+7eP:2J,~>
+JcC<$JcGWI"+b$.n'M(:iFlbpir9&OqUGOq~>
+JcC<$JcGWI"+b$.n'M(:iFlbpir9&OqUGOq~>
+JcC<$JcGWI"+b$.n'M(:iFlbpir9&OqUGOq~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$OoGNLOJC1rrrL`Dn,EF0Xm>ukG5CRgs8R'/rrVt;EqTG>^u>=nZ24I"H^siVs*t~>
+JcC<$OoGNLOJC1rrrL`Dn,EF0Xm>ukG5CRgs8R'/rrVt;EqTG>^u>=nZ24I"H^siVs*t~>
+JcC<$OoGNLOJC1rrrL`Dn,EF0Xm>ukG5CRgs8R'/rrVt;EqTG>^u>=nZ24I"H^siVs*t~>
+JcC<$OoG\2a16.jrr;ulr;Qin`,kbS"TJ5srqlZo!rK0Wn,EC]rr32PrhkkXs3goH!W;rrrrDrn
+rrK<Trr2upr;Qclrr3@D\c;Oqs&=p2UcSA!s*t~>
+JcC<$OoG\2a16.jrr;ulr;Qin`,kbS"TJ5srqlZo!rK0Wn,EC]rr32PrhkkXs3goH!W;rrrrDrn
+rrK<Trr2upr;Qclrr3@D\c;Oqs&=p2UcSA!s*t~>
+JcC<$OoG\2a16.jrr;ulr;Qin`,kbS"TJ5srqlZo!rK0Wn,EC]rr32PrhkkXs3goH!W;rrrrDrn
+rrK<Trr2upr;Qclrr3@D\c;Oqs&=p2UcSA!s*t~>
+s8N(jJVSf3RYLmIr;QaErr3L)^>`F+5ihr)D.pk/pLC*"rsc&%A[@[n;0i2e6#0>RrVlk#rVnKS
+iR/8/\qBBT@QrKF4nql8BC[t\NDj+=df4_rAhr]Ps6E$6O5!0:9'>duAV^9b#&_!O\;A=!rr3":
+V9o6m~>
+s8N()JN&-=RPt4or;QaErr3L)^>`F+5ihr)D.pk/pLC*"rsc&%A[@[n;0i2e6#0>RrVlk#rVnKS
+iR/8/\qBBT@QrKF4nql8BC[t\NDj+=df4_rAhr]Ps6E$6O5!0:9'>duAV^9b#&_!O\;A=!rr3":
+V9o6m~>
+s8N()JN&-=RPt4or;QaErr3L)^>`F+5ihr)D.pk/pLC*"rsc&%A[@[n;0i2e6#0>RrVlk#rVnKS
+iR/8/\qBBT@QrKF4nql8BC[t\NDj+=df4_rAhr]Ps6E$6O5!0:9'>duAV^9b#&_!O\;A=!rr3":
+V9o6m~>
+s8N(NJS'IFRUuPgr;QaErr3IVS,_?QC52a:mJk+.:WEA5%B41DlR^rN4QB2ns+Z@.rrBe3ru[c!
+MdEc/`W+u,G'*aCpns5Rs"FD/K)_j#kX>IM.I-p4$Dipc@_r)DGOm*ZrVm(>\c63sVK2\9!L8)[
+s*t~>
+s8N'PJH16$RK*=hr;QaErr3IVS,_?QC52a:mJk+.:WEA5%B41DlR^rN4QB2ns+Z@.rrBe3ru[c!
+MdEc/`W+u,G'*aCpns5Rs"FD/K)_j#kX>IM.I-p4$Dipc@_r)DGOm*ZrVm(>\c63sVK2\9!L8)[
+s*t~>
+s8N'PJH16$RK*=hr;QaErr3IVS,_?QC52a:mJk+.:WEA5%B41DlR^rN4QB2ns+Z@.rrBe3ru[c!
+MdEc/`W+u,G'*aCpns5Rs"FD/K)_j#kX>IM.I-p4$Dipc@_r)DGOm*ZrVm(>\c63sVK2\9!L8)[
+s*t~>
+s8N(NJS'IFRUuPgr;QaErr3I.]<b)1Km!DSs8U"s9_//^"K@F]dkUi_"m7oAs.tPHru^8t<8MLO
+r51h"P%4MNpns5Rs"FD/Y5c=]fNS=T6L+RM$)Ngb:#Z,p@.Qears!AOqaph*:]C@pF.UbYJ,~>
+s8N'PJH16$RK*=hr;QaErr3I.]<b)1Km!DSs8U"s9_//^"K@F]dkUi_"m7oAs.tPHru^8t<8MLO
+r51h"P%4MNpns5Rs"FD/Y5c=]fNS=T6L+RM$)Ngb:#Z,p@.Qears!AOqaph*:]C@pF.UbYJ,~>
+s8N'PJH16$RK*=hr;QaErr3I.]<b)1Km!DSs8U"s9_//^"K@F]dkUi_"m7oAs.tPHru^8t<8MLO
+r51h"P%4MNpns5Rs"FD/Y5c=]fNS=T6L+RM$)Ngb:#Z,p@.Qears!AOqaph*:]C@pF.UbYJ,~>
+s8N(NJS'IFRUuPgr;REUf>W)/rJZC!=`sa's8U#Yb"(Xorsbrfs7nY!pW<>YPjV/"rVlkUr;Rft
+>lR#gs.4<&BOh'$pps\cr@e2-Y5c=]q`2L"&aKAq$)NgbNI(,+V"7"PrsN_T\r6Uf8"8hO1\T2q
+J,~>
+s8N'PJH16$RK*=hr;REUf>W)/rJZC!=`sa's8U#Yb"(Xorsbrfs7nY!pW<>YPjV/"rVlkUr;Rft
+>lR#gs.4<&BOh'$pps\cr@e2-Y5c=]q`2L"&aKAq$)NgbNI(,+V"7"PrsN_T\r6Uf8"8hO1\T2q
+J,~>
+s8N'PJH16$RK*=hr;REUf>W)/rJZC!=`sa's8U#Yb"(Xorsbrfs7nY!pW<>YPjV/"rVlkUr;Rft
+>lR#gs.4<&BOh'$pps\cr@e2-Y5c=]q`2L"&aKAq$)NgbNI(,+V"7"PrsN_T\r6Uf8"8hO1\T2q
+J,~>
+s8N),JY[jmR\Tr%r;RFcJ<ReKs7Lk`]=S$3s8V)hs4X1GrsdJus8V83BT`8hLig2GrVlkUr;RhB
+`W*0]s8%Fi]WqL+r;E=?oU#TrfDjd@s6,NJ4Sf!V$.?rqrL@Z$s7rDersH6jB&WdiqO22Yn^%5c~>
+s8N(PJS0OHRV)Vjr;RFcJ<ReKs7Lk`]=S$3s8V)hs4X1GrsdJus8V83BT`8hLig2GrVlkUr;RhB
+`W*0]s8%Fi]WqL+r;E=?oU#TrfDjd@s6,NJ4Sf!V$.?rqrL@Z$s7rDersH6jB&WdiqO22Yn^%5c~>
+s8N(PJS0OHRV)Vjr;RFcJ<ReKs7Lk`]=S$3s8V)hs4X1GrsdJus8V83BT`8hLig2GrVlkUr;RhB
+`W*0]s8%Fi]WqL+r;E=?oU#TrfDjd@s6,NJ4Sf!V$.?rqrL@Z$s7rDersH6jB&WdiqO22Yn^%5c~>
+JcC<$JcEgk".>-_G3o5/dDu9;~>
+JcC<$JcEgk".>-_G3o5/dDu9;~>
+JcC<$JcEgk".>-_G3o5/dDu9;~>
+JcC<$JcEgk!r:L2YlB4~>
+JcC<$JcEgk!r:L2YlB4~>
+JcC<$JcEgk!r:L2YlB4~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+s8N)'JXq@_R[jGnr;Qn(=CdN`p\t98I.7.<:[PZFhu<r9B`G(,s1j6WrrT&uXS)T)n9.T)V#PI:
+>GV:^e,TH7cK"qT~>
+s8N)'JXq@_R[jGnr;Qn(=CdN`p\t98I.7.<:[PZFhu<r9B`G(,s1j6WrrT&uXS)T)n9.T)V#PI:
+>GV:^e,TH7cK"qT~>
+s8N(6JOb8]RR[@5r;Qn(=CdN`p\t98I.7.<:[PZFhu<r9B`G(,s1j6WrrT&uXS)T)n9.T)V#PI:
+>GV:^e,TH7cK"qT~>
+s8N(\JTlZhRWeb.r;REXs7icMo`!1Gj8]//m(L>Ys74Y<ru9Acs8(=HpqY2Ts$Z1ZI/j2d`Vohd
+s7Fe?n)aBF+8=Rjk2H@!o(Tr4o`+[?n2J#3nDXDsm(D`cs5q#^f`(mnj#X[8s3&:Vs6/agj8]/W
+3jSe^YQ$BNkpt"d^]4=I\)[L=~>
+s8N(\JTlZhRWeb.r;REXs7icMo`!1Gj8]//m(L>Ys74Y<ru9Acs8(=HpqY2Ts$Z1ZI/j2d`Vohd
+s7Fe?n)aBF+8=Rjk2H@!o(Tr4o`+[?n2J#3nDXDsm(D`cs5q#^f`(mnj#X[8s3&:Vs6/agj8]/W
+3jSe^YQ$BNkpt"d^]4=I\)[L=~>
+s8N'PJH16$RK*=hr;REXs7icMo`!1Gj8]//m(L>Ys74Y<ru9Acs8(=HpqY2Ts$Z1ZI/j2d`Vohd
+s7Fe?n)aBF+8=Rjk2H@!o(Tr4o`+[?n2J#3nDXDsm(D`cs5q#^f`(mnj#X[8s3&:Vs6/agj8]/W
+3jSe^YQ$BNkpt"d^]4=I\)[L=~>
+s8N(\JTlZhRWeb.r;QaErr3L?Z/^e94j!^UFJHcqge6)pru5ags.Y8?6]Q).s$Z1ZI/d0$Mbj@E
+m@P<oL9U[W!P)e@ru_)"s'eq,8aX$XOZ<*e=QD$!]=N.b0PQb)q:7d,A4lk$&C2knggY_q7Jr?5
+S(Rc@b=MR2$8V;Q4MY@>s8QcAj8XW~>
+s8N(\JTlZhRWeb.r;QaErr3L?Z/^e94j!^UFJHcqge6)pru5ags.Y8?6]Q).s$Z1ZI/d0$Mbj@E
+m@P<oL9U[W!P)e@ru_)"s'eq,8aX$XOZ<*e=QD$!]=N.b0PQb)q:7d,A4lk$&C2knggY_q7Jr?5
+S(Rc@b=MR2$8V;Q4MY@>s8QcAj8XW~>
+s8N'PJH16$RK*=hr;QaErr3L?Z/^e94j!^UFJHcqge6)pru5ags.Y8?6]Q).s$Z1ZI/d0$Mbj@E
+m@P<oL9U[W!P)e@ru_)"s'eq,8aX$XOZ<*e=QD$!]=N.b0PQb)q:7d,A4lk$&C2knggY_q7Jr?5
+S(Rc@b=MR2$8V;Q4MY@>s8QcAj8XW~>
+s8N(\JTlZhRWeb.r;QaErr3ITSc#.'8Ug[jqu=St:[J&[)r"?l54#(;T:[;,7-h1,j@0+K9\GE'
+?%'UWo)AXirVQQn*`(lo=7/<Ql&0O/c.?(t8+?PiFoO)`s&Rj%[/\iPrVm0mo(4g>s'<a1Pl:U_
+\R,46$8P:AI/dThs8Q`@j8XW~>
+s8N(\JTlZhRWeb.r;QaErr3ITSc#.'8Ug[jqu=St:[J&[)r"?l54#(;T:[;,7-h1,j@0+K9\GE'
+?%'UWo)AXirVQQn*`(lo=7/<Ql&0O/c.?(t8+?PiFoO)`s&Rj%[/\iPrVm0mo(4g>s'<a1Pl:U_
+\R,46$8P:AI/dThs8Q`@j8XW~>
+s8N'PJH16$RK*=hr;QaErr3ITSc#.'8Ug[jqu=St:[J&[)r"?l54#(;T:[;,7-h1,j@0+K9\GE'
+?%'UWo)AXirVQQn*`(lo=7/<Ql&0O/c.?(t8+?PiFoO)`s&Rj%[/\iPrVm0mo(4g>s'<a1Pl:U_
+\R,46$8P:AI/dThs8Q`@j8XW~>
+s8N)-JYdpoR\^#&r;RBWs8W'[cB`V>X*+G$s8U#:7+D/7),mJGs.=8Vcd;\[la)!!8cSfef@=,)
+e8.PIruRJFI[+l%s%0`p?,P8rs$uPX\on$3s8QNYJ?]()9)\br7Ip%1s8QNJPGJ0W!okd.rVlmR
+p&=spEi]6?<6F8$J,~>
+s8N)-JYdpoR\^#&r;RBWs8W'[cB`V>X*+G$s8U#:7+D/7),mJGs.=8Vcd;\[la)!!8cSfef@=,)
+e8.PIruRJFI[+l%s%0`p?,P8rs$uPX\on$3s8QNYJ?]()9)\br7Ip%1s8QNJPGJ0W!okd.rVlmR
+p&=spEi]6?<6F8$J,~>
+s8N(CJQID(RTBKOr;RBWs8W'[cB`V>X*+G$s8U#:7+D/7),mJGs.=8Vcd;\[la)!!8cSfef@=,)
+e8.PIruRJFI[+l%s%0`p?,P8rs$uPX\on$3s8QNYJ?]()9)\br7Ip%1s8QNJPGJ0W!okd.rVlmR
+p&=spEi]6?<6F8$J,~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4nru&Z[eGnu!UpQNh7-h1,s%8KA7fNE4L]8QRrVlo?
+M#I>ph$(gS"igRANh.N6f3&&jF1]#+s#9uX@Fj6tQ!m>ars;-bs&Y,M55UP>r;R"c;lH*os"a9H
+rrp_,VN3t=j8XW~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4nru&Z[eGnu!UpQNh7-h1,s%8KA7fNE4L]8QRrVlo?
+M#I>ph$(gS"igRANh.N6f3&&jF1]#+s#9uX@Fj6tQ!m>ars;-bs&Y,M55UP>r;R"c;lH*os"a9H
+rrp_,VN3t=j8XW~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4nru&Z[eGnu!UpQNh7-h1,s%8KA7fNE4L]8QRrVlo?
+M#I>ph$(gS"igRANh.N6f3&&jF1]#+s#9uX@Fj6tQ!m>ars;-bs&Y,M55UP>r;R"c;lH*os"a9H
+rrp_,VN3t=j8XW~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM3rrM"Lrr3])[&i9edJE4es80:5qZ$TDmJkW%rVloc
+f_kai_YjGNr;ZJlaP64Wf)PZmddGrkc2[grp&FO+]P@EF$.8\NrO]B0s5`GArs%Gb](l<LrVc`u
+kH2;kir=N~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM3rrM"Lrr3])[&i9edJE4es80:5qZ$TDmJkW%rVloc
+f_kai_YjGNr;ZJlaP64Wf)PZmddGrkc2[grp&FO+]P@EF$.8\NrO]B0s5`GArs%Gb](l<LrVc`u
+kH2;kir=N~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM3rrM"Lrr3])[&i9edJE4es80:5qZ$TDmJkW%rVloc
+f_kai_YjGNr;ZJlaP64Wf)PZmddGrkc2[grp&FO+]P@EF$.8\NrO]B0s5`GArs%Gb](l<LrVc`u
+kH2;kir=N~>
+JcC<$JcGTH!kD(U`W$)?=_1Uo^]/f~>
+JcC<$JcGTH!kD(U`W$)?=_1Uo^]/f~>
+JcC<$JcGTH!kD(U`W$)?=_1Uo^]/f~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+s8N)'JY%FaR[sMor;Qn(=CdN`p\t98I-1G/4Q-5?pe:Yd!LBk!s*t~>
+s8N(IJR<t8RU6&\r;Qn(=CdN`p\t98I-1G/4Q-5?pe:Yd!LBk!s*t~>
+s8N)#JXM(WR[F/gr;Qn(=CdN`p\t98I-1G/4Q-5?pe:Yd!LBk!s*t~>
+s8N(MJRj=BRUcDdr;REXs7icMo`!1Gj8]//m(L>Ys74Y<ru1:eaj:"eeGoR*o_%(ndGXB,huE^0
+s8V)il1b3!c,[lPs80[Ws8UsC^utU6h#I+6hnT!ek3W-G`Q.tms*t~>
+s8N'PJH16$RK*=hr;REXs7icMo`!1Gj8]//m(L>Ys74Y<ru1:eaj:"eeGoR*o_%(ndGXB,huE^0
+s8V)il1b3!c,[lPs80[Ws8UsC^utU6h#I+6hnT!ek3W-G`Q.tms*t~>
+s8N(GJR*h4RU#oXr;REXs7icMo`!1Gj8]//m(L>Ys74Y<ru1:eaj:"eeGoR*o_%(ndGXB,huE^0
+s8V)il1b3!c,[lPs80[Ws8UsC^utU6h#I+6hnT!ek3W-G`Q.tms*t~>
+s8N(MJRj=BRUcDdr;QaErr3L?Z/^e94j!^UFJHcqge6)pru7pnSS*l\2uinhb0VGn_J`8I8\Y3X
+s0,7d5L]W3!T--?ruS24BhnRoPC-sAB2b*OE0W?2pD/IH8,eFBrCqus=hjue~>
+s8N'PJH16$RK*=hr;QaErr3L?Z/^e94j!^UFJHcqge6)pru7pnSS*l\2uinhb0VGn_J`8I8\Y3X
+s0,7d5L]W3!T--?ruS24BhnRoPC-sAB2b*OE0W?2pD/IH8,eFBrCqus=hjue~>
+s8N(GJR*h4RU#oXr;QaErr3L?Z/^e94j!^UFJHcqge6)pru7pnSS*l\2uinhb0VGn_J`8I8\Y3X
+s0,7d5L]W3!T--?ruS24BhnRoPC-sAB2b*OE0W?2pD/IH8,eFBrCqus=hjue~>
+s8N(MJRj=BRUcDdr;QaErr3ITSc#.'8Ug[jqu=St:[J&[)l\,_r%J(/s8QZQcrU2HDmKDj>5p8U
+3fK\HI/a-HrqZKl*nEdMa^G/K1@o.is)Xk5PF_Fts8Q6MMkn3KT:[:u_#Jo~>
+s8N'PJH16$RK*=hr;QaErr3ITSc#.'8Ug[jqu=St:[J&[)l\,_r%J(/s8QZQcrU2HDmKDj>5p8U
+3fK\HI/a-HrqZKl*nEdMa^G/K1@o.is)Xk5PF_Fts8Q6MMkn3KT:[:u_#Jo~>
+s8N(GJR*h4RU#oXr;QaErr3ITSc#.'8Ug[jqu=St:[J&[)l\,_r%J(/s8QZQcrU2HDmKDj>5p8U
+3fK\HI/a-HrqZKl*nEdMa^G/K1@o.is)Xk5PF_Fts8Q6MMkn3KT:[:u_#Jo~>
+s8N(pJWGACRZ@HWr;RBWs8W'[cB`V>X*+G$s8U#:7+D28)l\5br@e1/qYs@6ctECYDmfVp=T:&S
+2oO%gjS8`oiBuo1aCP>N2Y(M-s*qQYT:#@)s8Q?NMkn$frm(T@_#Jo~>
+s8N(6JOb8]RR[@5r;RBWs8W'[cB`V>X*+G$s8U#:7+D28)l\5br@e1/qYs@6ctECYDmfVp=T:&S
+2oO%gjS8`oiBuo1aCP>N2Y(M-s*qQYT:#@)s8Q?NMkn$frm(T@_#Jo~>
+s8N(lJVo#9RYh*Or;RBWs8W'[cB`V>X*+G$s8U#:7+D28)l\5br@e1/qYs@6ctECYDmfVp=T:&S
+2oO%gjS8`oiBuo1aCP>N2Y(M-s*qQYT:#@)s8Q?NMkn$frm(T@_#Jo~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4oru7piWGd=eC3,7Ub0Xf$s)1W:9=FjRs.rc*U;m34
+!U"4sru_1gMPmr[4J.I6s(B^YJ%5NNR.h5PSj*+2V#!HH[Z/'%J,~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4oru7piWGd=eC3,7Ub0Xf$s)1W:9=FjRs.rc*U;m34
+!U"4sru_1gMPmr[4J.I6s(B^YJ%5NNR.h5PSj*+2V#!HH[Z/'%J,~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4oru7piWGd=eC3,7Ub0Xf$s)1W:9=FjRs.rc*U;m34
+!U"4sru_1gMPmr[4J.I6s(B^YJ%5NNR.h5PSj*+2V#!HH[Z/'%J,~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM4ru7qr\\J1Er3FT#o(:W8s)5NRe,THks8UfP^%_O+
+!Van=rrE&t^DkArp9M@1s4R&EhsUO-k5EZTYOqkSl2UUjWnG/eJ,~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM4ru7qr\\J1Er3FT#o(:W8s)5NRe,THks8UfP^%_O+
+!Van=rrE&t^DkArp9M@1s4R&EhsUO-k5EZTYOqkSl2UUjWnG/eJ,~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM4ru7qr\\J1Er3FT#o(:W8s)5NRe,THks8UfP^%_O+
+!Van=rrE&t^DkArp9M@1s4R&EhsUO-k5EZTYOqkSl2UUjWnG/eJ,~>
+JcC<$JcGTH!Nq^[rrIAfN;nD~>
+JcC<$JcGTH!Nq^[rrIAfN;nD~>
+JcC<$JcGTH!Nq^[rrIAfN;nD~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+s8N(YJTHB`RWAJ)r;Qn(=CdN`p\t98I*DTp7fCi]s8PIWrrV:WFnPb9d8,SnrrI>gh>`!~>
+s8N)/JZ"'sR\p/*r;Qn(=CdN`p\t98I*DTp7fCi]s8PIWrrV:WFnPb9d8,SnrrI>gh>`!~>
+s8N(VJT$*XRVr2"r;Qn(=CdN`p\t98I*DTp7fCi]s8PIWrrV:WFnPb9d8,SnrrI>gh>`!~>
+s8N'VJHp`2RKigtr;REXs7icMo`!1Gj8]//m(L>Ys74Y;rsRf#m+hWkn%8Sf]\NMd#Kjp\s5NC^
+f_>D4eGoBis7P7Kd^J*6s3q"#FN=:,s5iRbec5[F^YRN>s8VhEE7b-M]B]Fof\ajOs6s`YhZ)?C
+nc/:=f@"QYs52tss*t~>
+s8N(MJRj=BRUcDdr;REXs7icMo`!1Gj8]//m(L>Ys74Y;rsRf#m+hWkn%8Sf]\NMd#Kjp\s5NC^
+f_>D4eGoBis7P7Kd^J*6s3q"#FN=:,s5iRbec5[F^YRN>s8VhEE7b-M]B]Fof\ajOs6s`YhZ)?C
+nc/:=f@"QYs52tss*t~>
+s8N'PJH16$RK*=hr;REXs7icMo`!1Gj8]//m(L>Ys74Y;rsRf#m+hWkn%8Sf]\NMd#Kjp\s5NC^
+f_>D4eGoBis7P7Kd^J*6s3q"#FN=:,s5iRbec5[F^YRN>s8VhEE7b-M]B]Fof\ajOs6s`YhZ)?C
+nc/:=f@"QYs52tss*t~>
+s8N'VJHp`2RKigtr;QaErr3L?Z/^e94j!^UFJHcqge6)prtrdGV-%((4`6kC6'kNGs''o/9)a0,
+Q9<%_rr=/>s$C2E]+42%Pj=1"6GEITrG5c3pb2Z$6BjaGr^i</)".G(nRPt;[S*G]d-_g*\,ZKi
+:iaRG>,""<cR+UfDTSb^p#,k#~>
+s8N(MJRj=BRUcDdr;QaErr3L?Z/^e94j!^UFJHcqge6)prtrdGV-%((4`6kC6'kNGs''o/9)a0,
+Q9<%_rr=/>s$C2E]+42%Pj=1"6GEITrG5c3pb2Z$6BjaGr^i</)".G(nRPt;[S*G]d-_g*\,ZKi
+:iaRG>,""<cR+UfDTSb^p#,k#~>
+s8N'PJH16$RK*=hr;QaErr3L?Z/^e94j!^UFJHcqge6)prtrdGV-%((4`6kC6'kNGs''o/9)a0,
+Q9<%_rr=/>s$C2E]+42%Pj=1"6GEITrG5c3pb2Z$6BjaGr^i</)".G(nRPt;[S*G]d-_g*\,ZKi
+:iaRG>,""<cR+UfDTSb^p#,k#~>
+s8N'VJHp`2RKigtr;QaErr3ITSc#.'8Ug[jqu=St:[J&[(hq(k`a8[.lMkp>T8l=o.%d+bgj>js
+VhtBP!;QNm+/t0@Ju;c,rhO^5EW7fmU6YcY0E6`ps07(,=TACYmf*4mTU5[Tg&JR!mPt.E%Y;(g
+2"gm:NR(]+s)(V`hZ&*~>
+s8N(MJRj=BRUcDdr;QaErr3ITSc#.'8Ug[jqu=St:[J&[(hq(k`a8[.lMkp>T8l=o.%d+bgj>js
+VhtBP!;QNm+/t0@Ju;c,rhO^5EW7fmU6YcY0E6`ps07(,=TACYmf*4mTU5[Tg&JR!mPt.E%Y;(g
+2"gm:NR(]+s)(V`hZ&*~>
+s8N'PJH16$RK*=hr;QaErr3ITSc#.'8Ug[jqu=St:[J&[(hq(k`a8[.lMkp>T8l=o.%d+bgj>js
+VhtBP!;QNm+/t0@Ju;c,rhO^5EW7fmU6YcY0E6`ps07(,=TACYmf*4mTU5[Tg&JR!mPt.E%Y;(g
+2"gm:NR(]+s)(V`hZ&*~>
+s8N('JMi!9RPb(lr;RBWs8W'[cB`V>X*+G$s8U#:7+D28%r9,`_I!7*qYtH#cd1:q7/kL9p3XIP
+Z\8,R+7;Qpm9hjPUMB)(B`BjdUQb`X0E6a3s1Na5<WE(Rmf*4mTU5[Sh>b-'mRd?V%tV1h1\h!@
+MpH):s))s\p>>n#~>
+s8N(dJUrB'RXkI?r;RBWs8W'[cB`V>X*+G$s8U#:7+D28%r9,`_I!7*qYtH#cd1:q7/kL9p3XIP
+Z\8,R+7;Qpm9hjPUMB)(B`BjdUQb`X0E6a3s1Na5<WE(Rmf*4mTU5[Sh>b-'mRd?V%tV1h1\h!@
+MpH):s))s\p>>n#~>
+s8N("JM2R-RP+Ybr;RBWs8W'[cB`V>X*+G$s8U#:7+D28%r9,`_I!7*qYtH#cd1:q7/kL9p3XIP
+Z\8,R+7;Qpm9hjPUMB)(B`BjdUQb`X0E6a3s1Na5<WE(Rmf*4mTU5[Sh>b-'mRd?V%tV1h1\h!@
+MpH):s))s\p>>n#~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4orts'JPu_;m4o53,5Hq8jr_JTaL])S4s0ICWrr>po
+ruO@>s#t5uY>2B"B`Bjda?6$g0E6a3s1NaY;M098nG`FoTU5\]:U*1,mRd?V&:q:iP%(RPi6Q*:
+s),ro9'tR:J,~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4orts'JPu_;m4o53,5Hq8jr_JTaL])S4s0ICWrr>po
+ruO@>s#t5uY>2B"B`Bjda?6$g0E6a3s1NaY;M098nG`FoTU5\]:U*1,mRd?V&:q:iP%(RPi6Q*:
+s),ro9'tR:J,~>
+JcC<$OoH(9Q\@tcs.WQ!89Oqks8U#Ym7P4orts'JPu_;m4o53,5Hq8jr_JTaL])S4s0ICWrr>po
+ruO@>s#t5uY>2B"B`Bjda?6$g0E6a3s1NaY;M098nG`FoTU5\]:U*1,mRd?V&:q:iP%(RPi6Q*:
+s),ro9'tR:J,~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM3rtk%JWdk&prr<#_Xg@EprP#5Ys5*5Em,@pC!6+m9
+*SKTTg#i>7`3SOZs31NChnf35s5E>En)"*CcfI"^rs@oNs8U]Oi;`]&r;R>dmJm42XQfcVgAh3-
+o)IY(i;\<~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM3rtk%JWdk&prr<#_Xg@EprP#5Ys5*5Em,@pC!6+m9
+*SKTTg#i>7`3SOZs31NChnf35s5E>En)"*CcfI"^rs@oNs8U]Oi;`]&r;R>dmJm42XQfcVgAh3-
+o)IY(i;\<~>
+JcC<$OoGO$^shuUrsZZLk2$'^s8VWEs7XM3rtk%JWdk&prr<#_Xg@EprP#5Ys5*5Em,@pC!6+m9
+*SKTTg#i>7`3SOZs31NChnf35s5E>En)"*CcfI"^rs@oNs8U]Oi;`]&r;R>dmJm42XQfcVgAh3-
+o)IY(i;\<~>
+JcC<$JcGTH"RfQ+=RF61"-@(lYIsmc~>
+JcC<$JcGTH"RfQ+=RF61"-@(lYIsmc~>
+JcC<$JcGTH"RfQ+=RF61"-@(lYIsmc~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+JcC<$JcC<$o`'F~>
+s8N)IJ]E>^R`>E_r;Qqdci=$gRd0nRjmLCn!NO?*rr\#@n`'<C!SX%(s*t~>
+s8N(jJVSf3RYLmJr;Qqdci=$gRd0nRjmLCn!NO?*rr\#@n`'<C!SX%(s*t~>
+s8N)GJ]32ZR`,9[r;Qqdci=$gRd0nRjmLCn!NO?*rr\#@n`'<C!SX%(s*t~>
+s8N(kJVer7RY_$Lr;R'H;#gPi,6.]Aq#13mqY^?nqY^?rqZ$SNYl=Y&p@J:aqu-QpquQior;Qck
+rVllorr3#tp\t0np\k'j",!uXrr2oup\t0l!W;cjrrN#rqYpZNq7_.QrrDoorrW)>DWLhJ~>
+s8N'PJH16$RK*=hr;R'H;#gPi,6.]Aq#13mqY^?nqY^?rqZ$SNYl=Y&p@J:aqu-QpquQior;Qck
+rVllorr3#tp\t0np\k'j",!uXrr2oup\t0l!W;cjrrN#rqYpZNq7_.QrrDoorrW)>DWLhJ~>
+s8N(gJV8T-RY1[Dr;R'H;#gPi,6.]Aq#13mqY^?nqY^?rqZ$SNYl=Y&p@J:aqu-QpquQior;Qck
+rVllorr3#tp\t0np\k'j",!uXrr2oup\t0l!W;cjrrN#rqYpZNq7_.QrrDoorrW)>DWLhJ~>
+s8N(kJVer7RY_$Lr;S#q@,B@O-i_+l=\ebl?XIM#s5HXS7,IPg>Y0>?2b.]a@UqU:rVlnYb5VDa
+mP&9RJH(=)B$+Uk8[&0+8nWJMU.&$us-QGmP5%[Z@+bJY%YIYb1Y2SKANm0pLeq`Urr3o9Bi@F!
+nj;B[;uTbTBea8]W^Kius4p"V>AiO%J,~>
+s8N'PJH16$RK*=hr;S#q@,B@O-i_+l=\ebl?XIM#s5HXS7,IPg>Y0>?2b.]a@UqU:rVlnYb5VDa
+mP&9RJH(=)B$+Uk8[&0+8nWJMU.&$us-QGmP5%[Z@+bJY%YIYb1Y2SKANm0pLeq`Urr3o9Bi@F!
+nj;B[;uTbTBea8]W^Kius4p"V>AiO%J,~>
+s8N(gJV8T-RY1[Dr;S#q@,B@O-i_+l=\ebl?XIM#s5HXS7,IPg>Y0>?2b.]a@UqU:rVlnYb5VDa
+mP&9RJH(=)B$+Uk8[&0+8nWJMU.&$us-QGmP5%[Z@+bJY%YIYb1Y2SKANm0pLeq`Urr3o9Bi@F!
+nj;B[;uTbTBea8]W^Kius4p"V>AiO%J,~>
+s8N(kJVer7RY_$Lr;S#qa*DIP-ia4qZ:hOCB`I`Fs(%k]Tl9N@rVe>ILTpgYm(&3QrVloIli-o+
+mN_c353IK]s1W(Eodg%snc/X^-/RNMeR#3Ks6Vhur;R4YM#X9)s73dr1]L.Yq>L=3Zs;MA/cXBf
+47)uCi4aL:r$0tR;T`[ks.F8js*t~>
+s8N'PJH16$RK*=hr;S#qa*DIP-ia4qZ:hOCB`I`Fs(%k]Tl9N@rVe>ILTpgYm(&3QrVloIli-o+
+mN_c353IK]s1W(Eodg%snc/X^-/RNMeR#3Ks6Vhur;R4YM#X9)s73dr1]L.Yq>L=3Zs;MA/cXBf
+47)uCi4aL:r$0tR;T`[ks.F8js*t~>
+s8N(gJV8T-RY1[Dr;S#qa*DIP-ia4qZ:hOCB`I`Fs(%k]Tl9N@rVe>ILTpgYm(&3QrVloIli-o+
+mN_c353IK]s1W(Eodg%snc/X^-/RNMeR#3Ks6Vhur;R4YM#X9)s73dr1]L.Yq>L=3Zs;MA/cXBf
+47)uCi4aL:r$0tR;T`[ks.F8js*t~>
+s8N)"JX:qSR[4#dr;S#qs$fc`-i\s3ZX]`9J,fO"s%%X#O0nLHs8P%XLTpg:1o%6;q#:lm5QCag
+e:G%-WeLKQ/H.=%rrM+.rf7BEn<-D-s35CMhZ!NbK=(ZjI.At_]dEdFMasN@rt1SrO,oJ(oep"R
+s%hReH2m7Urf76<;r@ViDWLhJ~>
+s8N'jJKKFbRNDNGr;S#qs$fc`-i\s3ZX]`9J,fO"s%%X#O0nLHs8P%XLTpg:1o%6;q#:lm5QCag
+e:G%-WeLKQ/H.=%rrM+.rf7BEn<-D-s35CMhZ!NbK=(ZjI.At_]dEdFMasN@rt1SrO,oJ(oep"R
+s%hReH2m7Urf76<;r@ViDWLhJ~>
+s8N(sJWkYKRZd`]r;S#qs$fc`-i\s3ZX]`9J,fO"s%%X#O0nLHs8P%XLTpg:1o%6;q#:lm5QCag
+e:G%-WeLKQ/H.=%rrM+.rf7BEn<-D-s35CMhZ!NbK=(ZjI.At_]dEdFMasN@rt1SrO,oJ(oep"R
+s%hReH2m7Urf76<;r@ViDWLhJ~>
+JcC<$OoH[[s3T?s-i[PVkr5@'2pIm1s,qNtkLfAos8P%XRW[Q,;XoZ.rVlo'gA_*qmL@Iq1&-=.
+s5>p"\4Zd%W:nmC43%'?pWE*X2sf)fFJ&R4%YM.g]6rNtm\D',aS!MBrr3nj5NMI[s')jVQiBk>
+dRi3i6,33Bo94Rl?Z+s)J,~>
+JcC<$OoH[[s3T?s-i[PVkr5@'2pIm1s,qNtkLfAos8P%XRW[Q,;XoZ.rVlo'gA_*qmL@Iq1&-=.
+s5>p"\4Zd%W:nmC43%'?pWE*X2sf)fFJ&R4%YM.g]6rNtm\D',aS!MBrr3nj5NMI[s')jVQiBk>
+dRi3i6,33Bo94Rl?Z+s)J,~>
+JcC<$OoH[[s3T?s-i[PVkr5@'2pIm1s,qNtkLfAos8P%XRW[Q,;XoZ.rVlo'gA_*qmL@Iq1&-=.
+s5>p"\4Zd%W:nmC43%'?pWE*X2sf)fFJ&R4%YM.g]6rNtm\D',aS!MBrr3nj5NMI[s')jVQiBk>
+dRi3i6,33Bo94Rl?Z+s)J,~>
+JcC<$OoGEJrVmt's6"EO\'b60NP7CPs/9[WeG5j=s-s&^R=tU,D7lJ=rrKCYrr4/08<RrEs1mCh
+s2f23n,N*>Br:psK4p;@WGH\0m"/l4r;Q^+_:nqF^Ak*H[?pocC3\_9ru'.(D6Miqs8A)UVss_d
+K';ZXB8cH]P]=:DjSs`~>
+JcC<$OoGEJrVmt's6"EO\'b60NP7CPs/9[WeG5j=s-s&^R=tU,D7lJ=rrKCYrr4/08<RrEs1mCh
+s2f23n,N*>Br:psK4p;@WGH\0m"/l4r;Q^+_:nqF^Ak*H[?pocC3\_9ru'.(D6Miqs8A)UVss_d
+K';ZXB8cH]P]=:DjSs`~>
+JcC<$OoGEJrVmt's6"EO\'b60NP7CPs/9[WeG5j=s-s&^R=tU,D7lJ=rrKCYrr4/08<RrEs1mCh
+s2f23n,N*>Br:psK4p;@WGH\0m"/l4r;Q^+_:nqF^Ak*H[?pocC3\_9ru'.(D6Miqs8A)UVss_d
+K';ZXB8cH]P]=:DjSs`~>
+JcC<$K`;./N`_\0rrMOZPlH7~>
+JcC<$K`;./N`_\0rrMOZPlH7~>
+JcC<$K`;./N`_\0rrMOZPlH7~>
+%%EndData
+showpage
+%%Trailer
+end
+%%EOF
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.png
new file mode 100644 (file)
index 0000000..2fc6651
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-color-list.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.eps b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.eps
new file mode 100644 (file)
index 0000000..37206e4
--- /dev/null
@@ -0,0 +1,8659 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner
+%%Title: lttv-numbered-5.ps
+%%CreationDate: Tue Nov 30 17:10:43 2004
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%Pages: 1
+%%BoundingBox: 14 14 467 364
+%%EndComments
+%%BeginProlog
+% Use own dictionary to avoid conflicts
+10 dict begin
+%%EndProlog
+%%Page: 1 1
+% Translate for offset
+14.173228346456693 14.173228346456693 translate
+% Translate to begin of first scanline
+0 349.80741818181815 translate
+452.15999999999997 -349.80741818181815 scale
+% Image geometry
+1100 851 8
+% Transformation matrix
+[ 1100 0 0 851 0 0 ]
+% Strings to hold RGB-samples per scanline
+/rstr 1100 string def
+/gstr 1100 string def
+/bstr 1100 string def
+{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
+true 3
+%%BeginData:       577335 ASCII Bytes
+colorimage
+Zi>SdJRa7@JRa7@JRa7@K4BE~>
+Zi>T!JTZNdJTZNdJTZNdK6;\~>
+Zi>U%J^/hlJ^/hlJ^/hlK?eu~>
+Zi>SdJRa7@JRa7@JRa7@K4BE~>
+Zi>StJTHB`JTHB`JTHB`K6)P~>
+Zi>U%J^/hlJ^/hlJ^/hlK?eu~>
+ZiC#2oh'dAJR3n6g0Oi5WIqfh"bWe,K;jM&?35bYKCW@KWI\B,?@cFT?@W~>
+ZiC#Eoi-K^JT66\g2R1VZB;b="d-*QOg:,KE<;9.On*MlZ@R"HEIi,%EI\~>
+ZiC$MopgTYJ^/hlg<KcPin1lg"k_hef](Q_c2uYXf^d>fidoC+c@O95c@>~>
+ZiC#.!$(u5rDNVq!$$PnJQdV.i*-/VrE9<!mug3/=oa'LV!2([U]>o;=q%4qP*59s7p9)lmufR*
+=pgXm@Tm6:Qs/tI21\q^>(KkM>(?~>
+ZiC#C!$_DVs(hRM!H005Dh2hXDr>R6ZMe\DZ1FGfmV`)eqm,I)qm$3`okt8Do:)6@RosZJZ1FGQ
+qelh?Z?L54ZDMR3o0e.JJT$*XTPo>~>
+ZiC$I!Bl\DR/`ZV4b:b,b(7^nb5^K"aogSr];4l;!7q&,l,rn_!7phc%,gll]D&q5b0&Z:]79_#
+$Jsdfb0K#'b4kX[J]`PdJ]aY.J,~>
+ZiC#.!!rR>rbhdXrc\>JJQdV.JQgu8s6fqFr`TDRP".Ct=pKP?\*rd8Il6Lp#GcjYn$ddM8+p*r
+V!ie_msd2u>(;]*&>Z-#=pht3DcVMZW'-r+&:n#9>(Kke>5G&l>5tDt>5tDs>(?~>
+ZiC#A"q6ldR[fn>rh':f%"W8HD1QQ^D?'2-6N1g(Ng`^0mVN2hR_87`KnVkYD$R;!]^rdiA68JA%
+^>PYL%C!bD/G<%:)L4>rG;n]o6Y,9o;kQgKc#AXJSfsT\8D)HqecA;rb_\>rG@&~>
+ZiC$E!t`/^_>M=QaoE!(`du-\`o+l:pAfR>`WOZ"@XIO_#L^0%p\0o:Hg8TUhNZ"R`KZ.Np;RU!
+pQUp:P^CEid^`gAhVS4N$Kh)b^"2qkLu+@NJ]<8\J]>4>qVM+hs5*aps5*^oJ,~>
+ZiC#.!!rJ0rODn6JQdV.JQgu8s6fq!r`TDRP$2]$U^`K'J#%RDUm@='EJp-%r`TLrP4.iN2)Y6+%%
+MBBAsfBi>%X.tQtH;#+Z5GOIj-aGJY&Ha@Uan[Sq1@HmsfiUJQRtNJ!*tmn*d(O=s&RhQpnFO;D
+"\o2.i5OQtDkaAses#UnE'BJ"E6]@"80O!.TQ'JQdV.d9?D8qca$g"Jf4sn*g3YJ,~>
+ZiC#?!Y!/krQ>,`!R;+)COp8PCZ'".o)KX,CD;bs@sG5^YF^0%Y`4XHTqRg&Q_Ap.CBde,oCEea
+5l.\nW./T,U9Lk;GG;=;GPu;#5ah4t/3mL$WiD)"EfR0"NcM>pKn],S@[hh+RU\VSo<A40+-Z;c
+;o&!*2R%m#GG;=;GGq`kUni:?XGLqUWN(qtNW--^NIbkrCOp9KC\mZ"C]Eu/Y\UK7oDNHT~>
+ZiC$@!"f.dqVhJdJ\coRJ\g9\s7ZLFrkS]`\V7'_h@8,Zd,*-rhUpK1b1,(crkSf/\+fVKGB`o?%
+,/k?b1b_/_91Kgg<0B1+a:EiP#?LsdbNX+`Pp9\gsX0spQC^6P_I]1d(+jSp\3PD_&q,"WL2iBB
+4B_^GKSXrg</.+b1bRlhV?DqdbNX+`R+V@!76;5J\coRdD>\Rqn`=,"Q$uOp\4X&J,~>
+ZiC#.!!r?!!!n-ZJQdV.i*-0L!"f-5'r:;]P4-<+g4c!aP*5:4T#J+[SlAMb=pUqmmgrZ+n*d(O
+Ih%S&Yth+SUjk7tih5;$;Z0c'V!idj>(OZl_ZG15`W!b7H_BhWJ+'D+RT>mGOu;^sIl1D5@c#[!
+hUWZ8n*`-0ih5;$`UA01hM:RLH#CO9_7t2en&^_r7tFip>(Kl*>5I^b=pCekn"fF@V#=JI~>
+ZiC#;!"AW!!"=EkJS0OHi+N)]!#Y]J's7(qRIePAhiOT(R@3ZMUrp9nV-R=)B*bX2o,)+QoCK!]
+KasC6[TforXG&pBjeh4<?i=V.Xn.62B8asRa2iphbK%ZEKW4QsL%DOATO+>`R6^B8Kg99`Dr]D?
+jkD%XoCG5Mjeh4<bk$_PiK!N^JU,AV`l<V0o?N\4;h8S4B7X^DBDV5sB*PI/o<.]VXSld^~>
+ZiC$<!"eo)!"a^pJ\?WJi4]0b!%Io\(#&Di[J/"nm_?g:[C,bB[G]j$[u73a]a3?dpF3ehp\1rl
+O:IrTg8Nm"\Wh0lo<n2<Z2M@,g@p\M^!5clf&X`hkgn>G_pnFBOS?5h]opA/[<)*:OE8+K_=-6%
+oAVcpp\/aco<n2<iqKkPn%JJRUp'"3eDe<opXGjeR";r%]n*lF^&%L#]a!3bpY,B9gAS^8~>
+ZiC#*!!r?!!!n-VJQ@>&i)]mH!"f-1'r(/HJ+&>Tm=g>aIt-p:<l+"/:+]-<<Z7_$mgrN#n*`+Z
+<dTqsi[s0Y2(:9>n"B.'2>pQ!U@3Rf<h/B:P3.X\k`V+kMN[FXJ+)<s<&'d/Ih;);&2F/b,I-]e
+n!"Yen*^hIn"B.'M!qb"cGAtU97c<Ia5i&>muf4O6\/9h<e4<"<WMUdTE+HW<WJflmf9$Y<e(~>
+ZiC#9!"AW!!"=EiJRsCDi+;r[!#Y]H's."\L%CIjnVrV$Kn],Q?H)6C=?'F^AK%ZAo,)%MoCG("
+@=OR6k;MMp5VbOdo;;-:55f%9XRh-0AZ"j]Qg'Klm?a1(NL06jL%F?1>s+eOKc'FQ(d@q1,J*E!
+o9^_1oCEg^o;;-:O7U$6cG9%\;i0ncbit.To9VBq;1W;0AV"F@AH;?"X8qkgAH8h2o)PliAUj~>
+ZiC$8!"eo)!"a^lJ[p?Bi48m^!%IoX("i8BOS>98oqJ8VOHB3uHf";7D.KIA\Jj,ppF3Y`p\.9`
+Iup>tmq21c;I4;5pU0bXGQ#&qf_:JI\^pGLV!tRooq\DQYI4+dOS@tXI;QmrO=Bqu.<#3r,Mr0^
+pS9sWp\--.pU0bXXnTfof$a<-D5-^Sf']`NpRkDpP_$Ar\Uh<>\H)C%ec>I@\H(4[pAieB\UX~>
+ZiC#&!!r?!!!n-RJPq%si)9UD!"f--'VOoEJ+%l:msfiUN/[4T=Ms4+>!`*b)PHQf&5lEpmgqq,
+l^7/0']SR98lF[;S:?#*rDFc2msd&iRcoclk'MO?NfN7KKC=;>n(=RJ6_Nmt&F]'%rDFh`n(-qn
+/Q2'+&E</KIt'fRl^442n!#\dkf&R39S;e`.SG=jJPq%shbjH"qOm^`!:Th`!:Tb^!20>[!206f
+J,~>
+ZiC#7!"AW!!"=EgJRa7@i+)fY!#Y]F's$q[L%C"Po7htiP*5Ek@`moEAl)t9@iDE>o,(tIoCEf#
+bjD"no,Qrb3`T\Oo:Uek+T5dmX7M$.A#8RXQ0EaLm?Nt$IYdTLL%F*&D,[M,Kc'FQ*;s@kL\'0g
+82t,No,-T\TS8(hoC&6An+2r4P3g;RKi3d!Kf<:g@tA-@A)CbrL\e+L@fZ,u@fZ,s@fWV0o)Pli
+@t4~>
+ZiC$4!"eo)!"a^hJ[L':i3iUZ!%IoT'\<#?OS=iupQC^6S=K>:KBDU>LQqbF)V4ZW.CHSXpF2ct
+pT=2a1%Y-/TXFCcW0!*$rO!d!pQ0=$eFfE)mZ<b-St>A3R.l](pYrlKQIbel.JNQgrO!ikpYPXF
+@^Yt).J*;4OH<Z?o<#+gpS)-)p!9.iA=3+QA?(3gJ[L':hmEI'qUYPO!;HE!!;H>t!7q/D!7q(U
+J,~>
+ZiC#&!!rQ'qtg@!JPq%sJPtE(s6geSTV-S'msfiUIt-p:D;<%Hn"Q8_PdRDurDFQ,n*^fc;Xa&c
+;U4`un*^g`g7Y*:T\>ocIkgn"+JA1Q0iEA7]t^sO?GX=i[8;MEIt-p[OJ63Umsbnol\#.6+]d1_
+c4iQBn*^g\g73YB3Ss4*DsuD(.WN/6Ndk/mmsd'C;Lq_s;Vk:OT_e-S;?61`;?61_;?if_n"B.<
+T`%c=~>
+ZiC#5!"AW!!"=EeJRO+<i*lZW)25)jKrX`uL%C"Po7_8CaN=%PTu!/-Y&7YH@2c0;o,(nEoCEf-
+d.*_!o,+RdVPmq%h4B=S4T/\3Wq1p,@>;e<_m`TV`kfR%</C."L%D4/WGed-Kc&8,M-p6j+_TX&
+clQ%moCEfth4B=S6K@ZGFn=F;3.8ZWObI51o7];X@=_j<@GYDmWqu>a@0#os@0#or@0Wb'o;_ER
+Wr6@V~>
+ZiC$0!"eo)!"a^dJ['d2i3E=V(m*>"_pnFBOS=iupQ10ucd2?jYL9Aea/o6E)V"NU.C$/PpF3B0
+pT=2a.G!X`f!3fcW0!*VrNRKppQ06s_qrM\_.JJZaj._7R.l](pT^O3Wm^X'.H^5drNRNRlM'!a
+OKnQS.G!LWOH=DLpMZ;jieM!Pgr5eFIBiO.D1SsCZ%91:YlN;Mp\V2qp\_8rp\V3"f(\pep\38;
+Z%)~>
+ZiC#&!!rT(!;lZf!!n-RJPq%si)0QJrI5SbBTP_dO@NE77n&,eIt)3Q?9<(N9Lo([$[JCp&5lE!
+Ih5M-OT'_;&7U<KIkb8cLjsn/rDFeaO@M$'>'5OG:bPF`KmQWLBokheO@N,k9Pok]&:]Xg1&Xum
+LPT7R:/[a7&710KIt'27La5`_CI'aWF,5Hu=D3dd0nE5R;Lqa&;?3Bdn,#u_n,/gYn,$#_mf]:]
+T^V@J;Le~>
+ZiC#3!"AW!!"=EcJR<t8i*QJ_rIYkmEKs4)PtYPM9MLJ)KS+/bAO:Qi;H!L$)M=u@(11FIK,.gL
+ObJF?(2](iKfX".M1pRCrEg_#PtX5GApoPd<Ad[&MLSV`E0X+(Ptb>-<-OU$(5Is)3;m2,P)Wrq
+?!jO_(2JkcKnDFRM_&#(D+-TuH]!T3?ZD?)3e:Xh?\)S@?N@)%oD;kpoDGTgoD;npo)u"!W:TWZ
+?[r~>
+ZiC$,!"eo)!"a^`JZXL*i2m"-rK%eCT!;OKZ!;^^>]mTMOH=gEHX`M4H'nT5$bt,O.BT`#O=@<J
+Xo=Ci.CHRRODD8/TTG7NrN.6XZ!;(HZ*gNnBj-V+W01juT!;OKZ!M^KIAjDU.D`!JC]1@X`M@Q<
+WNFU1.CHFROH=8#S3;tQHWY3iZ`'7QI@d]KCOrU=Xb!V2XT6fGp\V&mp\`G>p\V)mpB8pHdeEM7
+Xag~>
+ZiC#&!!rT$qY'sqJPq%sJPtB'r%\4;#r+_30gS)[5tO*91&j084\@jr8,Q9b1&b)N1&k,O62`MC
+;G&r(0iCb,r\==K+@._J;Gp7S1G_6j:-UNj5>FL!5s[4k6TIY&0elQl0erT(!]_tqr_ibN!`DcR
+r\5!_3AF,u0f;Bt:d[)p0gS)[6%Mpb;Lqa&;?2"=T_hX`T_hXeT`.jhT`%c=~>
+ZiC#/!"AW!!"=E_JQm\0hcp":s%!e]84YX082a"95W:SZ4[)8376XNF>Q6V\>Q6V]>6.2Qr\b*f
+<B`B#>?*jH2E(J;+@nC]>?b0!3]]c4=%>;47or5>84YX/8jH0C2E"c/3&^\=!^JY1r`fC\(L'm'
+3&W[!4uQ><2EFN9=@kS52Fp@s8:aur>Cg#8>6'3MVYaToVYaTtVZ'g"VYs_L~>
+ZiC$(!"eo)!"a^\JZ44"hl6Nds+gtoLko]"LhDO2GQ)7TEs-u[IrgkPWW-W1WW-W2W;qVMB*YE+
+F(]-bS9OsFr2CfpB8EOdU53Z'Ln^W"D/G*'LhDO"B8DRnP_`sbWJ#&"r2BaEB7'WWs(;D4S9OsF
+&ZKhaS=F5/NiAb1DeE^=LhDNpWI_%"WSXTS]DBhMWVXp;WW19CWW19BWIO~>
+ZiC#"!!rS/rjDd:!k#QEJPLbkJPLbkJPLbkJPMA'J,~>
+ZiC#-":W5gaN48$!"=E]JQ[P,JQ[P,JQ[P,P$*;~>
+ZiC$$!"Ah[qq_;]JYdpoJYdpoJYdpoJYeO+J,~>
+ZiC"s!#Y]-r_EJk!_uW1JP(JcJP(JcJP(JcJP)(tJ,~>
+ZiC#+"<:]S@:B%C!$$PkJQID(JQID(JQID(P#m/~>
+ZiC#t!%n/%qhG/'JY7ReJY7ReJY7ReJY81!J,~>
+ZiC"sof7RqJP(JcJP(JcJP(JcP"L6~>
+ZiC#)og"(.JQ78$JQ78$JQ78$P#[#~>
+ZiC#polktWJXh:]JXh:]JXh:]P+7%~>
+Zi>S6JMi!9JMi!9JMi!9K/J/~>
+Zi>S;JNA?CJNA?CJNA?CK0"M~>
+Zi>S_JR3n6JR3n6JR3n6K3j'~>
+Zi>T<]9!"(JU`6#JU`6#JU`6#r-n^%d?"?)J,~>
+Zi>T;]8lq'JUN)tJUN)tJUN)tr-\R"d>n9'J,~>
+Zi>T<]9!"(JU;rpJU;rpJU;rpr-JEtd?"?)J,~>
+ZN#LD^$YpG!.j!XhLXO7hLXO7hYc42me5,t!R55,~>
+ZN#LC^$PjE!.imUgO\+1gO\+1g\fe,mIo#r!R,/+~>
+ZN#L@^$5X?!.i^Peq)D'eq)D'f)4)"lL`Qj!Qel&~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+hu<cWrVZWks82orrnma,gV)>BRK.onJ_Pb1J_Pb1J_U+Ws6\:i!Lc`5~>
+hu<cWrVZWks82orrnma,f"KW8PQ69cJ_#D'J_#D'J_'bMs6A(a!L-3,~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+jSoJarVH?ap@\(Uo*4j[p@n@ZrT!p/gV)>BRK.onJ_Pb1J_Pb1J_U+Ws6\:i!Lc`5~>
+jSoJarVH?ap@\(Uo*4j[p@n@ZrT!p/f"KW8PQ69cJ_#D'J_#D'J_'bMs6A(a!L-3,~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+kPkngr;$*[oC;;;mHjc:$1.'In+#u@pA+XKs+/q<gB!`CJ_Pb1J_Pb1J_Pb1r7h8=e(Xnl9n3~>
+kPkngr;$*[oC;;;mHjc:$1.'In+#u@pA+XKs+/b7ecD!8J_#D'J_#D'J_#D'r7:o5e(+Pa8q6~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+l2M4lqtTjTn*TH*kiV!fjSn3>j9k#2kNV="n+$&Eqrn'2gV)>BRK.onJ_Pb1J_Pb1J_U+Ws6\:i
+!Lc`5~>
+l2M4lqtTjTn*TH*kiV!fjSn3>j9k#2kNV="n+$&Eqrn'2f"KW8PQ69cJ_#D'J_#D'J_'bMs6A(a
+!L-3,~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+li.LpqY0XOmH`uujPo+Th;-lcg]-%;h;7)Kj5oLimI9`@qs+34gV)>BRK.onJ_Pb1J_Pb1J_U+W
+s6\:i!Lc`5~>
+li.LpqY0XOmH`uujPo+Th;-lcg]-%;h;7)Kj5oLimI9`@qs+34f"KW8PQ69cJ_#D'J_#D'J_'bM
+s6A(a!L-3,~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+m/J@.p[mtBl/q$bhV?i;f@JL%eC2pse^i@)g>(QCj6#Umn+6;Om/MXk^"WRV!.imUgO\+1gO\+1
+g\fh+mF0ejRSA;~>
+m/J@.p[mtBl/q$bhV?i;f@JL%eC2pse^i@)g>(QCj6#Umn+6;Om/MXf^"*4K!.i^Peq)D'eq)D'
+f)4,!lI4;bPY-H~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+mf*mtq=X:Fl/q!_gtC<0e'ZLec2>csc-FY^daZk$gtq&Pl0Rp3q<e35gV)>BRK.onJ_Pb1J_Pb1
+J_U+Ws6\:i!Lc`5~>
+mf*mtq=X:Fl/q!_gtC<0e'ZLec2>csc-FY^daZk$gtq&Pl0Rp3q<e35f"KW8PQ69cJ_#D'J_#D'
+J_'bMs6A(a!L-3,~>
+ZN'[Uqel_0hT]uqhJ^[)h?(`\W;YQU[ucj!DrBIQ`Jsb5!LD""h>qQ>leVW=rGMmgXOZ1)T%3Dg
+!nEl\l.uH2!.j!XhLXO7hLXO7hYc71meGW?VOl?;h?)6!Dti)hDp@h/!Luo8~>
+n,F$up[dh<k2P:Qf[\Erc-+5M`l7ko'#hl2aihrTdaZn'hW!\_mdg,On,N.:qeZS.gWXNhgMP1#
+gB5BVVV;%("LX>Qb\c:m!Q'clD#opFnCmt\bj4!`V#G39DLAJ4gSCCho%O5pSSdWG!La">gO\+1
+gO\+1gO\,Wg]-[9gB+1Ae,J)'e"(@MgAu08n_4)59n3~>
+n,F$up[dh<k2P:Qf[\Erc-+5M`l7ko'#hl2aihrTdaZn'hW!\_mdg,On,N.5qeHG(f#_^Yen`Cn
+ecNUEUA`XGZ&FX`CZ*bE^PVi'!KtLmecBR.ldc'/rG)U_VTm\bRa:QU!md<Nl.,m"!.i^Peq)D'
+eq)D'f)4,!lM/p3TUO4+ecO0dC\QB\CWZ+t!L-3,~>
+ZN'[U!<?1!B*Xg\`AQN/!57^T$c?"Qc/.=4I3EOJ2;m<t_hVl2.l1gNP0NLQ!<Bh!h@"6P?>!_B
+=K((p?Hr&t!muERl.uH2!.j!XhLXO7hLXO7hYc71meGW?DdL]fh?(r.!;G=N!57pZ!Luo8~>
+nGa4"p@7P6jP\hGeBuRbaMu-7^q[Rrrk/9E'#)/t_o9^>c-XtlgY_&Sm-s]GnGi7;!<?-u@gA=S
+`%p*%!5@dR$c#eMakPS'I3`[J1>pmn^k?3&.PYFCO36tH!<Bk"gC%jJ>[q/9=/O_h?d/)q!mc3K
+l.Z6-!.imUgO\+1gO\+1g\fh+mJ,E;D-tNdgB,T+!;G4K!5A!X!Lc`5~>
+nGa4"p@7P6jP\hGeBuRbaMu-7^q[Rrrk/9E'#)/t_o9^>c-XtlgY_&Sm-s]GnGi76!<?$r@gA7L
+_(jNl!57^L$bK;A`R`ViGp-t>1#UUh]n9fu.5>=BNlUY?!<Bh!edH7B>%:l4<he/\?HMch!m>jD
+l.,m"!.i^Peq)D'eq)D'f)4,!lM/p3CL5-^ecNs"!;G%F!57pR!L-3,~>
+ZN'[U!<BP+ed'pceth0Z!57^T$efr"W8?CQ>QhIcUu:)8gt:2s>&2^?g@*l!!57^T$ZB4ff$UKm
+FkUb?c19]mg:a<Hh>s,HJ_kt7J_kt7J_kt7r8.JAptc'j?HrK+!mP$OpYGoN^%'q[S5+S~>
+nc'@#p$h;0in`;<dEThS`501#]"#5X[JmNJ[C3QS]"Gbm_oBgCd+$_(iTBFoo_\1YpY,]K[/JAW
+e_AQGgY2_Ble;g!GtP!hgW!J&[*t]+gBlQ_dDB(#dF$LunCmsD^?aM]D-Fg(bc"9Wennd<o%O5t
+\Y/3A!La">gO\+1gO\+1gO\,Wg]-[9gB)5!bl6>ub[1AEgAq;gn_4)59n3~>
+nc'@#p$h;0in`;<dEThS`501#]"#5X[JmNJ[C3QS]"Gbm_oBgCd+$_(iTBFoo_\1YpXT?FZ2MrQ
+dal^6f%'i7ldcHlG=\IZf"kGkZ-Jlted0dPcG*IocHal,ec>caldcGZ=MN/'UeGdVCL5-RecO:-
+SE\T*PQ69cJ_#D'J_#D'J_'bMs6BC1!c),armh.m?3'`N!<Bh'ecD"-J,~>
+ZN'[U!<Bh1h@7_JhVJ7GhV>_uF+^mSo%kC_8qGdSVG8_sc#;Iqg735*Ph+]HW8?BPOP\iUT^^e>
+c!G>ehAFtSK6)g[gtpbmK6)+(g>:Zd^#$;LDgSbZhCNSOc/.=.B4]S2?H&M5hVQeSVV]:UFa9L?
+VU_8VhVN1]K5Z+IhVPemDgSbah>s,HJ_kt7J_kt7J_kt7r8.JAptc'j?HrK+(!U%bhVQtVF*!Ss
+hVJ7Gc#:.>DiiQFh>s-AJ,~>
+o)CE?p$_2-i7ur5cH=/E^V%+d['Hs?Y-"h-Xf\b0Yd1XE\\,\o`lcTTf%]*Cl0e3@o)JI=!<Bk2
+gC;ADgY2_BgY'&iEe1OJo%P1Z8q>ULUeNDlb\c+hf9gW!P1/0>VVBjHNn`<HSFG87b[55cgDJPJ
+JT?LUg=t5bJT5b"g"Y6]^>$#CD0`AUgFR2KbhLn$ARa#'?cAS3gY:2JUt`bKF*O4;UsklOgY6ST
+K5Z%DgY9)`D0`A\gB!`CJ_Pb1J_Pb1J_Pb1r7h8=ptGje?d/N((!L"bgY:>IF)dAlgY2_Bb\a_2
+DiiHCgB!a;J,~>
+o)CE?p$_2-i7ur5cH=/E^V%+d['Hs?Y-"h-Xf\b0Yd1XE\\,\o`lcTTf%]*Cl0e3@o)JI8!<Bh1
+ed]`:f%'i7f$q$WDh"t=o%"hQ8:B"=TLpZ]a_TJYdZeZgONuF0Ut4+8LXt%3R./Z.a^/c]eeli;
+I;a\CeCN'MI;a%gdaltL^"0H4CNHWJegtTCak#%g@pmJq?Gi5)f%/09T[pl=EHRY/T[0'Bf%+WE
+Iqs89f%.*MCNHWQecD!8J_#D'J_#D'J_#D'r7:o5psoL^?HN2t(!0b^f%/96Df:`_f%'i7a_S/&
+CQ-R6ecD"-J,~>
+ZN'[U!<Bh1h@7-uhVJ7GhV+>O#Ut_`o%kCt:2ekCPYP-5]`?pGeli=b9$Z9JF5GaZ6JgQcA+8=V
+c!G>ehAFh&.0qYqg>:D>.0p2_f&#6`^#"ts!#UCZhCNSOc/.=.B4KA.?G0Z`hVQL`Dr.Qe$kul7
+Dp;SghVJ6s.0(3LhVOJ?!#UCah>s,HJ_kt7J_kt7J_kt7r8.JAptc'j?HrK+(!U%bhVQge#RF&J
+hVJ7G]`=96!(,!+h>s-AJ,~>
+oD]X'p$_2-hqHW.bfI`<]XYATYH=k)Vl$?iV&#r+WN*)(ZF.3S^Ve+8d+-k-jQZ+)r:Bs_gAq;g
+qqDRo!8H6.^>%8(0FB4ce+266[S:VjgQG9.gV*[BgXB.2#YE4o0QGk%$piY&4C.I2!mG"grS&1<
+MC8feR+^6CMC8`==kDE_!5@3J+9375n_5U3?d.9Zdq)t6D-t"aD;3gh?Z"Pt8.68>7r?IW!8H6.
+Q7N.UP2"`O+9375ptGh<!.imUgO\+1gO\+1g\fh+mJ,E;D-tNdgD.q>!8H8W<=B.)bM1bO^:jT-
+'EgkJptGh<9n3~>
+oD]X'p$_2-hqHW.bfI`<]XYATYH=k)Vl$?iV&#r+WN*)(ZF.3S^Ve+8d+-k-jQZ+)r:Bs_ec>ca
+qpl4i!7o^$^"1Vn/I3e]cLTO,YtAf[erWKrf"D(7f$7/!#YN+f0ltps#W^Je3Ekq'!m+barRMh2
+KI$mUOOD_*KI$m0;U3kE!56sB(]Y,#n^]7,?HLdLc=:2&CL4\\CY%(Y?>J,j8IQ;:7Vg+P!7o^$
+PUQSLPh+EE(]Y,#psoJ1!.i^Peq)D'eq)D'f)4,!lM/p3CL5-^eeQ;5!7o`H;@!P#`n&]@]tFE)
+&-,&:psoJ18q6~>
+ZN'[U!<BP+f)OS9]`?pG!576V:5Ho>3K*Ib*SPF,\_:t"SDLpZhVM.&`l:#!hK(^6[0R&ph?]tI
+h?(r.DuJN1O?J*0F%2hZO?J*5]d[IJh>k77!0l')!7p_t/T4h3f$9(/J)5*M]j>X6hT]AFX@Za3
+_.O<tc!CD,h>fRUhJ3DRc2a*[S,h.9h>s,HJ_kt7J_kt7J_kt7r8.JAptc'j>/gKl'ua>VhVM.&
+`l:#!hVJ7G]`:(4]eMkKh>s-AJ,~>
+o`#d*p$h8-hqHW-bJqB3\[A`GX/MnkU7e-MrgamtT:hmQV5UDsZ*h*S_8XRCeCi^=l0n9Co`+[?
+!<BG(e,S/3^&ZpB!5@3R9npH34H&db*S5.&[b#@pT%gsZgY5Rs_nJ5qgMo()Z4%#jf*J,?gB,T+
+D>i3,O?e<0ECQVUO?e<5\gV.EgAnt6!1)*&!715j/T"Y-e'!P,J(ngI^0ba3gWX#AX@cj2\ml:g
+b[1A)gAj(Jf51rNcN'9[RK1\0gB!`CJ_Pb1J_Pb1J_Pb1r7h8=ptGje=i10e'uF)RgY5Rs_nJ5q
+gY2_B^&U:0\hHSJgB!a;J,~>
+o`#d*p$h8-hqHW-bJqB3\[A`GX/MnkU7e-MrgamtT:hmQV5UDsZ*h*S_8XRCeCi^=l0n9Co`+[:
+!<B8#cMuH)]`?X7!56sJ:4p6,3J[1V*R\^qZ-mDcSCY@Rf%*_k]tHEdeoNRsXU#3`ed.f8ecNs"
+C]2g%N'2NuDap8JN'2O$[4,V:ec<D/!0kd!!7(/d/SeD#cGbDnHe)t=]j>L*f#_66W(C=+\R#\[
+a^+tuec7G<enYQBc2a*SS,gk1ecD!8J_#D'J_#D'J_#D'r7:o5psoL^<k\LX'tmWJf%*_k]tHEd
+f%'i7]`:(+[4t#CecD"-J,~>
+ZN'[Uqu@<?hVPpGhVJ7Gen\pLhU5nHf(.Z:QqEIN;Kq!S]`?p?!7'HX`W4;l!7lL#&?W&?n(n,j
+?>oi");8k4c/--;HeN7Ac/.<I(uF*L^!6V:f&#!Jh>hKm!%/V-c/*AF]j>X6hT]AFHWI]6hRQ6s
+c!CD,h>jD/hRrpGc2`gShU_JY!Ls.@hLXO7hLXO7hLXP]hZ*$=h>hKi!#+5?!7'HX`W4<@!56&G
+^#%VR!7pu&!Luo8~>
+p&>p-p@.D0hqHT+b/M0.\$N6<Vkg#XS=5h3QN!-eQC!u-S=ZFMVlHo*[^s5laj/AghW3tjp&=Xa
+pY5TG&J3^O^&ZpB!5?orA^fDX?Y@p[gDlMPOLS51fA"">gX?/GgY9FBcaEu*H!(i]V@;)GgB,T+
+D>r9-f4eO5gU^O5f4eO5gY8/6gY2_BcNK-SgXG]I!,_Z7-Q%!KgML<3?Z"QPb[546=h*5@\4^\_
+?NAj8!2A6&\cCL2"H([_e+hYuRK.onJ_Pb1J_Pb1J_U+Ws6]U9!,_N3'ALt9bM1dc!70C"^:jTY
+gY9"6e+q`!RSA;~>
+p&>p-p@.D0hqHT+b/M0.\$N6<Vkg#XS=5h3QN!-eQC!u-S=ZFMVlHo*[^s5laj/AghW3tjp&=Xa
+pX]6B&J3OE]`?X7!56ZjA'WZI?=V:Oef0iGN3uQ)f%.M7f$498f%.M7`jGflF&ERGV$QP@!m+ba
+rmht8B3N:*[8M(oB3N:*es$`sec<D'!0#4ScLKHcC]+5\'Q:tACL4\\CY%(Y?>Fac[FWp:8o)OT
+!7o^$SCZ9!!7o-iN6^#"psoJ1!.i^Peq)D'eq)D'f)4,!lM/p1C\[rDf$498f%.M7`mt.']`>Ik
+eu\qtq:5S28q6~>
+ZN'[U!<Bh1h?U^ohVJ7G`aeoH!FF%Ah@%.tCQMGahVPpGhT#Em$,,14S3iH<F)+D:h?(r.DuST#
+dUR4PhT]AFdUR4ph@%!shVJ7GhPEOM0q@dj!cMDiqq`Q9?G0Z`hVQL`Df8t,hVQL`Dp;SghVJ7G
+hVPpGhVP(q&2B^Mh>s,HJ_kt7J_kt7J_kt7r8.JAptc'j?HrK+"O16QhT#Em"hiam]tFFEh>mVr
+q;).B:4N~>
+pA[)Nq"!e6i7c],ai(s*[BQa2UnF9IQ^*_rO,f6[NfK0^P*D<$S=lXTX0AtA^;J%;e(NX?lgacC
+s7b7K!5A?b#JL2mgAnt*@Jg*+?-;`m$bfPRN`2D$gV*[B_tsE?]%\'n6'>)^D+X3N!mG"grn@e+
+@;XcRb$Al1@;Z"u$b?>mgAntBU-T>ERdo,6D-tNagEUQB^0ba3gWEf=D-b<=gW3T9b[1A)gAnh>
+gV*[BgS-tF0Uhdk!La">gO\+1gO\+1gO\,Wg]-[9gB)5!bl6?"b[1A)_tsE;]%[5!^&\/e!nRFd
+q:bq=9n3~>
+pA[)Nq"!e6i7c],ai(s*[BQa2UnF9IQ^*_rO,f6[NfK0^P*D<$S=lXTX0AtA^;J%;e(NX?lgacC
+s7b(F!589\#JC,gec<Cs?Mjd(>/g'`$b9#FN)#Vgf"D(7^&%d9[FQ1b6B"NPCJ+'H!m+barmhFu
+?>J-C`EI'!?>KPk$afucec<D7S3dcAPk!<+CL5-[eg"s:]j>L*f#:g.CKe^.f#:g.a^+tuec<,/
+f"D(7eso&<0pMIa!L*S8eq)D'eq)D'eq)EMf)P%1ecKVnao9ioa^+tu^&%d5[FP>k]`A#^!<Bh/
+ecD"-J,~>
+ZN'[U!<Bh1h@7-uhVJ7Gen]'ThV,rjnD5(1:.AF+hVPpGhUV\XhVQhkhVMFG#gSA`0pM.`!mP%i
+rn\RICL59B]iK@2CL59BhOG/6h>k7?Xkqp)!7(/l!cMDiqq`T:?G0Z`hVQ(HDgPNqhVPe8Dp;Sg
+hVJ7GhVPpGhU\gchOFSkq;).B!.j!XhLXO7hLXO7hYc71meGW?DdL]fhA4@B!8c9,f&#97[GKa?
+]tFEZhVPpGf(n/'S5+S~>
+pAZ$,oBk`"gXXWl`4idhYH"IoSXPk.OH#0TM#;uFLP^qKO-5crSY;mZY-YXP_oU-Qg>M,[o)/4]
+pY,]K^AHXo^&ZpB!5?orB@Ybg_T)*")L"hE=hreH^&Zp:!70ESe$@`_?!RlZMDR/Mn(Rof?Z#es
+)V8\/b1jL/GLpP7b1k[>'\h@B^=0+:gR8,co%O4_?d/E%,]-o&?Z"QP^/8`k<Ogf<\4^\_?NAj8
+!5@4B^&Zp:WnZ9s!6b2m!La">gO\+1gO\+1gO\,Wg]-[9gB)5!bl6?4b[1A)df@_KgXEI_gAnt%
+!4pq>[K+ePgB!a;J,~>
+pAZ$,oBk`"gXXWl`4idhYH"IoSXPk.OH#0TM#;uFLP^qKO-5crSY;mZY-YXP_oU-Qg>M,[o)/4]
+pXT?F^&-@i]`?X7!56ZjB@>AZ]ts3h)KS>5<k[)8]`?X/!7'0HcE5[K>$;3OKJ>3?n(%Q^?>KPk
+)U`8%`R_S#F4+])`R`V1&D#D4^!<J*es$0So%!kX?HN)q,\p`"?>J-C\P?p];RP*,[7Y5V?3&R-
+!56t7]`?X/V:O4^!64ic!L*S8eq)D'eq)D'eq)EMf)P%1ecKVnao9j,a^+tuc2c/@f$:DKec<Cs
+!4CD/[/eMJecD"-J,~>
+ZN'[U!<Bh1h@7-uhVJ7GhNUWgb)eoEnD48?2%Y-6h@mR&hVLjs`m.I:hVOb.+l:3=#gVnq!mP%i
+rSAER6A30r7\JV"6A3@l.:_5k!56qhV:Lk2f(.Z!DdL]chB[#G`FhZJdX)gLW't13_.O<tc!CD,
+h>k7GhRrpGed/,'PQ9;1h>s,HJ_kt7J_kt7J_kt7r8.JAptc'j?HrK+(!U%bhVLjs`m.I:hVJ7G
+]`:(4]eN.Sh>s-AJ,~>
+p\u31p@%8+gt'ip`4rjiY,S4iS!T>"N/<:AJUi7LIN*ceJV/Z4MiX$eR\-CSXg>OO_o^6TgZ%Gb
+p&=^cpY,]K^AHXo^&ZpB!5@3N98LQG6AP'b"/%UdH2cP3^&ZpB8PR+C;)I%^Sd6Ur`rl[on(Rof
+?Z#br)3@+5^2ZW8gQ4[M_n%7-gY2_BcNp8oOp',%gB)5!bkp-?D-t4m7C(-](i?3@?b3m]&8fWu
+!8H6.^>%DV!8Gg*U=58.chZ;rRK.onJ_Pb1J_Pb1J_U+Ws6]U9!c;;grnA13?NAj88PR+C;)I%^
+!5?/I352s\7JPU<RSA;~>
+p\u31p@%8+gt'ip`4rjiY,S4iS!T>"N/<:AJUi7LIN*ceJV/Z4MiX$eR\-CSXg>OO_o^6TgZ%Gb
+p&=^cpXT?F^&-@i]`?X7!56sB7YAO54bN7T".V4WF8j`(]`?X76;"r28hnoJS-U:h]`8>`n(%Q^
+?>KMj)2p_*\Sjs-er2b=]sT;!f%'i7c3TrcMu_/oecKVnansX7CL4he7^:'Z(i,p9?FdUV&8TBo
+!7o^$^"1cJ!7oF$SBd&ncM?#lPQ69cJ_#D'J_#D'J_'bMs6BC1!c),armhh+?3&R-6;"r28hnoJ
+!56&G0tjtL6MT+4PY-H~>
+ZN'[U!<Bh1h@7-uhVJ7GhV+&?#UP/PnD48h=tu]Lh@dL%hVQgU#REc:hVQfh>2J*Z3UY`*c!G>e
+hAFh&.0qYqg>:D>.0p2_f&#6`^#"\Z!#Usjh?%V%c26?BDdL\i70jT68oNRf8IQ;>8oMs\!8cQ4
+^#%VZ!8cRk&-*Q3ptc%A!.j!XhLXO7hLXO7hYc71meGW?DdL]fhA+:A!8cS`8dG\h`noPP]tFDm
+&-,>Jptc%A:4N~>
+p\u3-o'>Dof[A!_^UgeTWMH/TQ&pr\Kn4]#H?aZ5FrPXMH@10mKSYSKPaS,<W3*D:^;S1AfA5NQ
+nbW"[pY,]K^AHXo^&ZpB!5@4<N[b;[K[K;D"3+ItT)RIW^&ZpBcV4ZN6-%a7f*G[:gE8?@gB,T+
+D>i3+dtf=X176bLdtf=V$sD3:gAntBL(jV-P4@9.D-tNagEUQBbc4&<(gfjOgSdRM(0sFIb[1A)
+gAntBgV*[BgP-CB*0U*O!La">gO\+1gO\+1gO\,Wg]-[9gB)5!bl6?3b[1A)gWrS"#XQMcgAnt%
+!.>C]8^I1d!Lc`5~>
+p\u3-o'>Dof[A!_^UgeTWMH/TQ&pr\Kn4]#H?aZ5FrPXMH@10mKSYSKPaS,<W3*D:^;S1AfA5NQ
+nbW"[pXT?F^&-@i]`?X7!56t3N%##YJ'%32"2S"mSGq(P]`?X7c:S?J6G:t$c3RV)efcd9ecNs"
+C]2g$c@dJL0pL,;c@dJL#[5O)ec<D7KFe,#N:GI#CL5-[eg"s:aeV3.'O!tAetb_C'O!tAa^+tu
+ec<D7f"D(7eq=S7(l\7@!L*S8eq)D'eq)D'eq)EMf)P%1ecKVnao9j+a^+tuf$6kn#XZ5Uec<Cs
+!.,7W6H8fO!L-3,~>
+ZN#L4i8+^PW6*oQ]iodFh>s,HJ_kt7J_kt7J_kt7r8.JAj5'gM!;#%JS5+S~>
+q#;?2p$V#%g=4Bf_7R+YWMH,RP`L]VJpr#iF`MJ?rb`]oE,p&EH@:?uM2mdeSYN-d[(=&mbgY8'
+k3_g?q#>p"i7eLJW6!`J]N][DgB!`CJ_Pb1J_Pb1J_Pb1r7h8=j4aUK!;"qGRSA;~>
+q#;?2p$V#%g=4Bf_7R+YWMH,RP`L]VJpr#iF`MJ?rb`]oE,p&EH@:?uM2mdeSYN-d[(=&mbgY8'
+k3_g?q#>ori78.@UrCp9\QX4>ecD!8J_#D'J_#D'J_#D'r7:o5j447E!;"bBPY-H~>
+ZN'^Vp]0F4!,qT3RGJ1E8or8!DapD^h>s,HJ_kt7J_kt7J_kt7r8.JAq;)*ipAjpD!PJL)h>s-A
+J,~>
+q#<JOna#8lf$MOV]sb/FUn4!<NerF=HZsOMD/3iuB4bdhBkhL(F*;kZK8>MMR%:"OYI2!ZaNrDl
+j6?(/q#C-Dp]0F1!,_H1RG.t@88lSjDa^2ZgB!`CJ_Pb1J_Pb1J_Pb1r7h8=q:bmdpAjpA!PSR*
+gB!a;J,~>
+q#<JOna#8lf$MOV]sb/FUn4!<NerF=HZsOMD/3iuB4bdhBkhL(F*;kZK8>MMR%:"OYI2!ZaNrDl
+j6?(/q#C-?p]0F,!,M</RFVV97Vfu^Dap8ZecD!8J_#D'J_#D'J_#D'r7:o5q:5O]pAjp<!PJL)
+ecD"-J,~>
+ZN#L4hqeR13=$$VSD*,^!Ls.@hLXO7hLXO7hLXP]hZ*$(h>to"oA0M<:4N~>
+q>WYVp$V#$g=+9c^UUSNVP'BBNei=:H$+(BBkCj`?sd5I?t!PVBP_X0G^Y1"NK]d&V5pl1^;S4C
+f\biYo`"[dJ_T,;#MGV.$48hag#h#iRK.onJ_Pb1J_Pb1J_U+Ws6\k$!R"L7gB!a;J,~>
+q>WYVp$V#$g=+9c^UUSNVP'BBNei=:H$+(BBkCj`?sd5I?t!PVBP_X0G^Y1"NK]d&V5pl1^;S4C
+f\biYo`"[dJ_&`0#+R[Z#W\:#k10Qt!.i^Peq)D'eq)D'f)4,!lJpFr`_uEZ!L-3,~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+q>VK2o'>Amf$DIT]="f>Tpq=.M1^8%F)G`)@UEAD=T2AB=BSm8@:a.jEd)q`LlR^gTVnou]"uG4
+e_K3Mnbi4_J_Rlm!La">gO\+1gO\+1gO\,Wg]-ZigB!a;J,~>
+q>VK2o'>Amf$DIT]="f>Tpq=.M1^8%F)G`)@UEAD=T2AB=BSm8@:a.jEd)q`LlR^gTVnou]"uG4
+e_K3Mnbi4_J_%Nc!L*S8eq)D'eq)D'eq)EMf)P$aecD"-J,~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+qYreZp[@>)g=+9b^UUPKUn*j6MM-G'F)>T$?X$W4;Gg7d:Jaqg='K!@BPhd6I=mB;QCO_LYd_<a
+bL5)%kO/*?s+/q<gB!`CJ_Pb1J_Pb1J_Pb1r7h8=e(Xnl9n3~>
+qYreZp[@>)g=+9b^UUPKUn*j6MM-G'F)>T$?X$W4;Gg7d:Jaqg='K!@BPhd6I=mB;QCO_LYd_<a
+bL5)%kO/*?s+/b7ecD!8J_#D'J_#D'J_#D'r7:o5e(+Pa8q6~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+qYrhXo^1euf[7gX]<n`=TUM('L4FPjDJ3Nd=]J<o91_ZE84cHK:fLP&@V9OuG^kF*P*hl=XL#LS
+aNrGojm;U<qYu-$^"WRV!.imUgO\+1gO\+1g\fh+mF0ejRSA;~>
+qYrhXo^1euf[7gX]<n`=TUM('L4FPjDJ3Nd=]J<o91_ZE84cHK:fLP&@V9OuG^kF*P*hl=XL#LS
+aNrGojm;U<qYu,t^"*4K!.i^Peq)D'eq)D'f)4,!lI4;bPY-H~>
+ZN#L4^"rd[!.j!XhLXO7hLXO7hYc71maL"nS5+S~>
+qYrhVo'>Ale]u4N\[&93SX,=nJpVWYBk(FN;bfqZD3DK_gpKL=8PW/b>[hAaFF&LnNg6-0WN`kG
+`m*#fip-(3qYu-$^"WRV!.imUgO\+1gO\+1g\fh+mF0ejRSA;~>
+qYrhVo'>Ale]u4N\[&93SX,=nJpVWYBk(FN;bfqZD3DK_gpKL=8PW/b>[hAaFF&LnNg6-0WN`kG
+`m*#fip-(3qYu,t^"*4K!.i^Peq)D'eq)D'f)4,!lI4;bPY-H~>
+ZN#KG]USs%J_kt7J_kt7J_kt7r8%JBc-i*^:4N~>
+qYqQ0nEJrde',bD[]cX'RZi\aIX#jIA6rA:9h7\<r;Rh`4?l2'9N"qt@qfn*I>!NAR@pI\[CjE"
+db3RBn+cbZJXX6?!!%T)J_Pb1J_Pb1J_U+W!U\+ZRK-'4~>
+qYqQ0nEJrde',bD[]cX'RZi\aIX#jIA6rA:9h7\<r;Rh`4?l2'9N"qt@qfn*I>!NAR@pI\[CjE"
+db3RBn+cbZJX!g3!!%T$J_#D'J_#D'J_'bM!U@eTPQ4=+~>
+Zi>RV\c@<<J_kt7J_kt7J_p=]!,p3aJ,~>
+qu8t]p?q,%f[7jY]<n];SsPOqJpVTVB4+nB9h7T6lhAf*eGm`M3'BPt9N"u"Ao)O7JV]AQSYW<m
+]"uJ7fA>ZWpA=l@!4i/]gO\+1gO\+1gO\,WgAl*;!.Y~>
+qu8t]p?q,%f[7jY]<n];SsPOqJpVTVB4+nB9h7T6lhAf*eGm`M3'BPt9N"u"Ao)O7JV]AQSYW<m
+]"uJ7fA>ZWpA=l@!4i/]eq)D'eq)D'eq)EMec9L4!.Y~>
+JcC<$JcC<$JcC<$JcC<$[f6>WJ,~>
+qu8t\o^1etf?_OS\[&93S<]+iIs>sJ@pE&18OGX":bO=JXoHNr1,h<^85</h@VKe*IYEcGS"cme
+\A-)0f%oERo7?pms+13$s+13$s+13$s8N#uIt.~>
+qu8t\o^1etf?_OS\[&93S<]+iIs>sJ@pE&18OGX":bO=JXoHNr1,h<^85</h@VKe*IYEcGS"cme
+\A-)0f%oERo7?pms+13$s+13$s+13$s8N#uIt.~>
+ZN#L4J_kt7J_kt7J_kt7L>Ds$:4N~>
+qu9"[oBbPof$;=N\?Ms,RZi\`I<KOB?s-E%76W[d/LVkfWrL-f/29(H6q^BZ?Y4.tI"R??RA$R_
+\%]i+eD0*Mo)AOdJ_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"[oBbPof$;=N\?Ms,RZi\`I<KOB?s-E%76W[d/LVkfWrL-f/29(H6q^BZ?Y4.tI"R??RA$R_
+\%]i+eD0*Mo)AOdJ_#D'J_#D'J_#D'J_#S,!L-3,~>
+`r?+JHgU>&J_kt7J_kt7J_kt7J_l.<!Luo8~>
+qu9"Zo'>>keBQ"I\$)a'R?EG[HZX+9?<9rp69@"U-R'QLVuOd\-7gr65tFdP?"@_lH@h!8Ce^D%
+[CsN&e(`mInc&FcJ_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"Zo'>>keBQ"I\$)a'R?EG[HZX+9?<9rp69@"U-R'QLVuOd\-7gr65tFdP?"@_lH@h!8Ce^D%
+[CsN&e(`mInc&FcJ_#D'J_#D'J_#D'J_#S,!L-3,~>
+`r?27N$Wf:o)F9tJ_kt7J_kt7J_kt7L>Ds$:4N~>
+qu9"Yo'58ieBGnF[]ZO$R$!5WH?3k4>ZFNh5<(AI,97R5V>nLS+t53)5"/1F>@VDfH%:^3O]NAu
+VnBpjdb<[EnGW7aJ_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"Yo'58ieBGnF[]ZO$R$!5WH?3k4>ZFNh5<(AI,97R5V>nLS+t53)5"/1F>@VDfH%:^3O]NAu
+VnBpjdb<[EnGW7aJ_#D'J_#D'J_#D'J_#S,!L-3,~>
+`;]u6N[8o8o`'L!J_kt7J_kt7J_kt7L>Ds$:4N~>
+qu9"Yn`o,ge',bD[B?C!Q]R#SH#dY0>?"<c4uP&A+;ke#UAr.K+!rTt4@Dh@>%22cG^tR1QCa^V
+)HaAhdb<[EnGN1`J_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"Yn`o,ge',bD[B?C!Q]R#SH#dY0>?"<c4uP&A+;ke#UAr.K+!rTt4@Dh@>%22cG^tR1QCa^V
+)HaAhdb<[EnGN1`J_#D'J_#D'J_#D'J_#S,!L-3,~>
+_Z'c4O=#2;pA]^#J_kt7J_kt7J_kt7L>Ds$:4N~>
+qu9"Yn`o,ge',bD[B6<uQ]R#SH#dY/>?"9b4Z4o?*u>IoTDueE*[NBp4@;b>>%),aG^kL/QCXkR
+Y%et`_V*o3nGN1`J_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"Yn`o,ge',bD[B6<uQ]R#SH#dY/>?"9b4Z4o?*u>IoTDueE*[NBp4@;b>>%),aG^kL/QCXkR
+Y%et`_V*o3nGN1`J_#D'J_#D'J_#D'J_#S,!L-3,~>
+_#FQ3OsP;:q#>p%J_kt7J_kt7J_kt7L>Ds$:4N~>
+qu9"Yn`o,ge',bD[B?C!Q]R#SH#dY0>?"9b4uP&A+;kb!U&W%I+!rQs4@Dh@>%),aG^kL0QCaqS
+[(F"n+(W[]nGW7aJ_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"Yn`o,ge',bD[B?C!Q]R#SH#dY0>?"9b4uP&A+;kb!U&W%I+!rQs4@Dh@>%),aG^kL0QCaqS
+[(F"n+(W[]nGW7aJ_#D'J_#D'J_#D'J_#S,!L-3,~>
+^Ae?2PU:M:qYu-'J_kt7J_kt7J_kt7L>Ds$:4N~>
+qu9"Yo'58ieBGnF[]ZO#R#m/UH?3k4>ZFNg5<(>G+rh@1V#S@P+Xf!%5"/.E>@M>eH%:^3Q_((V
+[(O<"b^UgOg]%*MJ_Pb1J_Pb1J_Pb1J_Pq6!Lc`5~>
+qu9"Yo'58ieBGnF[]ZO#R#m/UH?3k4>ZFNg5<(>G+rh@1V#S@P+Xf!%5"/.E>@M>eH%:^3Q_((V
+[(O<"b^UgOg]%*MJ_#D'J_#D'J_#D'J_#S,!L-3,~>
+]`/-0Pp^Y:r;V?)eD:3+f"'Z:f)O%peq)\/hLXO7hLXO;h>s-AJ,~>
+qu9%[o'>>keBPtH[]cX&R?<AZHZX(8?<0im5rpeR-QsHHVuOd[,qLf35Y"RL?"@_lH@^p7R%L7Y
+[CsN&e(`Z7-$/;Js+/qSgB%B,f=K];f@0]E!RoYOgO\+1gO\+1gP+A_RSA;~>
+qu9%[o'>>keBPtH[]cX&R?<AZHZX(8?<0im5rpeR-QsHHVuOd[,qLf35Y"RL?"@_lH@^p7R%L7Y
+[CsN&e(`Z7-$/;Js+/bNec>cr\^pT%J_#D'J_#D'J_#P+!L-3,~>
+])Mp/QRHn<rr7Q+l.uKTSA"CJrr<&E]\X%Ic@d#O.4H)NK[/0<h?(B\^$sk`[<"Y`.621Gjk^9b
+PZfpn0iEtLjk^6MF$_<)3GYb`h?(B\]o(YJ]pucehLXO7hN-LoS5+S~>
+qu9+_oBbPoe]u1L\?Ms,RZiY_I<KL@?s-B#6p<Oa/12YbWrL-e.kikE6V:3X?Y4.sI"R<>R@pI]
+[_B`*eD'$Km$B,@kl1U5gZdGo\sg5!g]%6SbLaG^$eN^Z*"3Ai#T/0>fC7Mr\sg5"gBXm$749QH
+AZFkH#fMd.2CL=WLVi0-#Hi&8-n%2hWpJIA\sg3fgB+sT\q/UegO\+?gB!a;J,~>
+qu9+_oBbPoe]u1L\?Ms,RZiY_I<KL@?s-B#6p<Oa/12YbWrL-e.kikE6V:3X?Y4.sI"R<>R@pI]
+[_B`*eD'$Km$B,@kl1U5f'1`e[?S)ff)G^M`k9n&c2iS8r;Zp:Hd9q+ecN7D[ID`PX_U6P.61n7
+jjj^RN)heb0i!D8jjj[=CI0I!3FeoPecN7D[>NN:[?S(Meq)D'erSA_PY-H~>
+\Gla/R43+<s7>+IN;nP<HZO7DCL^OOONuSHh@?rPLkLG.F)u,4@p3'UeuIR.^!6!6h?*cP!7&=8%
+G$IeKZ;m*f%.6M.>6:Bh?(C8mdf3B``b*<V7!_$@j+IXl.uisO@<'+XgP*W68aD?l.uig=tt)p[
+C)N7+\IC3n(n,Zc0gJG!klkHleVUIkhZr14[qn-4ZPAS/L`+l+W(b%#RLA/J_kt7J_nu7!Luo8~>
+qu94bo^1bsf?_OR\[&61S<](gIs>sJ@pE#084#Es0eFk'XoHKo0fD*Z7o!#f@VKe*IYE`ES"cmd
+\A-)0e_T<Qo`+cU.<+JMo@jb,I<fsTD/!Qi?!1<jajob4%^(;.GBInBBk:^Y=]rYgWnRTdbjFlR
+"9AH%bLaPa&D,6c'JNO4F`h[q-kq9Zf@fcM!kQVCo%OPi=YOii[^)K9+A'0/gC2Dg6r8`A[&AOB
+1kEg6gC1u&0QEhqZCYVM8V,%QgB+t1m>BX"]$0R-gAq-7gD7;fTUqO6N.uh-F)bo*?!1$!76s$q
+0S.u0gO\,1gB!a;J,~>
+qu94bo^1bsf?_OR\[&61S<](gIs>sJ@pE#084#Es0eFk'XoHKo0fD*Z7o!#f@VKe*IYE`ES"cmd
+\A-)0e_T<Qo`+cU.<+JMo@EnVraYq2r_`fQ`R=,("/'FFBDuE?>5hD#^!<Y/!k$/8n(%R@mf:AA
+ecj?P#RDSGr^$`)#RH+/n^[cLam/HJ$b]^uF/?:PS7<^7[HZ6NabrScN30LdImQ#B`Tbq^]im.3
+V7!_$@j+Ho`UD@Z[E7]kecN8$lKd"$!9hu9hWsXrroXCChVQucf)Eto`WEi]V1I3Keq)E'ecD"-
+J,~>
+[f6L,Rjr?to\KS,qq_V0`jJuo@X#rJmG@lNqq_S/`jK!70tl0(h?]3QIs66\:*b&+h?(C8me#?:
+dUW4U"4$W@cJ@=ZDemqXkhZlr6B'dakMFe@cGml;F#hOsoA0P^c0k2[%BV'h[Ed(KcHaG+8e@ib
+h@@M?7Z>1/daHF`[<F3+_<]qfXXRbfcHb"dcGl\Q/R$![h?(C8mY]j&^!6!2hZ!lGh@Yi^LjsVe
+B3nV67RB*i+W(arquD<)J_kt7f%pFt:4N~>
+qu8t]p?q,$f[7gX]<nZ9SsPOqJpVTVAm\\>9h.K33&E?CYlDp'2`j8o9N"u!AScC4J;92OSYW<l
+]"uJ7fA>ZWp\t0qqO8sQ`UqmbIJ_n-f>k1"G@bp6ea;)lXKMHX#M7#%=dCnQcg0<kQ>MA+JU(BP
+Hck(E]$0R6gB#N*r;Zu\rrC6ohV/0MC":hglIus'cT!b$I;rCe9he2J5q"S9e(OBJ!kQVCo@j_W
+-t0R-cdU4`_kp-BU?gPD`+qc!^s19Sc,[2:0O)9WgCCA7@CFA*e'H4TVG/aK^@9kY]$0Q!gB+t1
+mH`O,qruiI]XH)*^:(2ASsG=iI<BC<=],/i!C8DjgO\+1gXb*[RSA;~>
+qu8t]p?q,$f[7gX]<nZ9SsPOqJpVTVAm\\>9h.K33&E?CYlDp'2`j8o9N"u!AScC4J;92OSYW<l
+]"uJ7fA>ZWp\t0qqO8sQ_=Z:YC\urof#FgiF(04,dd>TdTVVJA#M-ns;NroDcKj$eQue(:Ljrks
+J'-=D[E7_+ecEm!r;Zr>pAi4hecT]#cI1q-#gP.13D):K&.naF!\q^?o@<uNam/KK%BV'h[Ed(K
+cHaG+8e@ibedfN37Z>1/daHF`[<F3+^$F5ZXXRbfcHb"dcGl\Q/R#jWecN8$lAF-o[E7_"f)Ga7
+ecFe)mf*=^Xb#&Seq)E'ecD"-J,~>
+[/U:+SKqR_p>,h'hY[<Yn(q6+XCc[ug@!htYlO4hrs/#L>.pF\^"2Q,#b[-aZ*giu>)UP[!klkH
+p"fhV7Ql^,rQYK5!7(T#"-`cc^#e)RDZFFug?RMrc7ua*kPsE=ed'L?]tKXbJ(F8K!klkHo\L+u
++`kr[hWOA%pZL,@=qJC7h@S+V8taVdip641n(u0E2.k,#h@R[MF3`@nkO80>kLR>)2.k,'h?(C8
+mdf6)kO%++ipl4!hXTb/iq)".^!6!2hYmfGh@YubIs5sPB3nV65rgYK+W(arquH6Co7R+KJ_kt7
+J_p+W!Luo8~>
+qYrhTnEJoce'#\C[]cU&R?EJ^IWoaG@pN/69LhE85sIN?s3Eu!7nH?N<a9*JDg$P]MNO9uVQI5<
+_ogB[i90S+r;QosSKqO[p=fUnhu!EZn(Uj!XCl[meaD/nWiY[drs/#I<PFnY[a4<p#bmX,c-akA
+Dii,r!kQVCp"L.a938LDj5]=crrC6ogY7_g!4LMBgBQ>H!,'^0g$IH-f?Yj6H#Zti<E2mj8P)?:
+1aI@qg%F)$]$0R6gCM"DFj&7gkO8$6kL7.N&@Uu\&Bo,fT[26KlgaT6h8kR6A'"&l&ABE4bL>5/
+n+6/6e%Uf"A'"2p!kQVCo%W]tmFqX"n`T;on`Ko2o@j>XbjF`Nrql!8&\b]o^::JKU7.7&L3[cQ
+@9H>(8HD+2nD!O7!,[;AJ_Pb1p=fV:9n3~>
+qYrhTnEJoce'#\C[]cU&R?EJ^IWoaG@pN/69LhE85sIN?s3Eu!7nH?N<a9*JDg$P]MNO9uVQI5<
+_ogB[i90S+r;QosSKhCTp=97[hY[<Yn(prtXCcOiddGZfTVV#Qrs/#L;SAST[Ee-i#c+-Af%Sio
+H]ZD$!k$/8p!s8J7QH:$rPep-!65#h",m3[[H5sBCB/"mdd#Bdc63H[3VsBc#Qbi]cLfZh[E7_+
+edoG;F3`@nkO80>kLR=M&@LoV&BSi_T[MQRlgsl>hT:[5@`@`c&A96.cIUk8n+ZS>f"Hu!@`@lg
+!k$/8o%*?omFD9on`T;jn`Ko/o@<uNam/3CrW)67!TNkArrMl%nCI2a!3Lh'J_#D'p=98/8q6~>
+ZMt']M'ZKJptc%AhYR6XmolOD[:XX)g@*nu]`@Ksrs/!rn'7FX^"2T-#c*9]_90HY?Alt_!klkH
+p>,nQ78Bu]c3j:GcJICXHYWVhf'2#rg=C%38nZT+m+qfp6FHgUs6p!N$Js@Z`l>^"P\,^)p"fb`
+c0k5\"]AOLf&uf+s8VfqkJfhTmG8&7<g;%hn,*+a#5e/`eq?AOmG8CP>0]H,;H!Pp;Gp+ZLkJ*V
+n_O>\c0k/Zn`T;r!93P3mG@Br!93V,!klkHle_RGleW5DMnQg7[BZj5V4a?KPa%,[K`-5t)"?D\
+KE/:Rh?1$9KX$*bJ_kt7pYGq@:4N~>
+qYqQ2o'58je]u1L\?W'/S<f4lJU;KVBOY4J;GB`bq#;8Q;-$n0B5M^9J;9/LS"cmd\%]i*eD'!I
+nG`:a"P8DS>f6?k!f#2$qu6rf<M8*PB6D)An(RrKXQTQZrs.jilcY_R[a4?q#cO9@iT8t8I?Mb-
+!kQVCp=fbP:2A)6j8A'IrrC6ogAn7:!3Xf9gBlQ`d:Z0JA'<?SmFqci4@OO8rE0M.;,'bV76s$i
+14e!KgB+t1mI]-:9j,fokP+rP"o%WK_a-TUgBNm@PgeOYq>U6qq=X(&JjGFagCR(^cUCE&;>^5f
+;,'W:JjGFegB+t1mIK$%kO%"(iUQ*ug[XG,iUbe*]$0R-g\q$8gC_<BiSE2=e^;X``P]F$ZEC4)
+rh9F^8atL5!!$m4gB29m!,[;AJ_Pb1pY,_;9n3~>
+qYqQ2o'58je]u1L\?W'/S<f4lJU;KVBOY4J;GB`bq#;8Q;-$n0B5M^9J;9/LS"cmd\%]i*eD'!I
+nG`:a"O_rK>/0j`!E,cjrs8'kT\d(gF2?;necM(_de`tKmo&W"S2%FsmFM<9#2\P/ldh#Zb16X%
+am/TN"/nX\V>\F5c3j:G`n&]@HXd&XcKWmbd`uJp7UsThm+)<b3=%r+q@NN0!ZZ^<p!s2Pam/NL
+"\MtDf&uf+s8VfqkJfhTmFDK';O#Vdn,*+a#5e/`eq?AKmFDh@>0]H,;H!Pp;Gp+ZLkJ*Rn^[cL
+am/HJn`T;j!8d8/mFLgj!8d=u!k$/8ldl"7ldc*rp[8%^pU0MArIb0QqUPbNKS6IYeq)D'f([_r
+PY-H~>
+ZN's]"P\h]?,cZs!gVX6qu6rr>+k$&NI.bUn)")b!U0@Vrs/:%k2s'`ONHnH#cNio^V-Rs:l!3M
+!klkHpYH&*LHg!rr6G>j$KbB%f%t1*K/$QOleVutS8E%!<-_T9f%f]M(>?0+cKFBVhV.;YhU]i[
+`kAdUH\'/kp>,kac0k8]&]HVcdbaTms.H%bqtKF-G9t)oh?VGV@'8/Gp\k*k#Q=Jgi29=kcgT^'
+`ANS%7SZiZs8Ptp8kP2C:34bPh?(C8mdf6)kO%++ipl4!hY$(3mJl>Liq)".^!6!2hYmc\F6h]_
+T`<jYgtLE3eC)[fc,n)H_83ha\H"&Ih?C0QKS5f7qq_FqZ'qqKhLXO7hY5k-S5+S~>
+qYqQ5o^1bsf?hXV]<n];TUCt%Kn"AhD.d<`=B&,$q#;5R='T0GCiXcLKStt[Su&Np]"uJ6f%oEQ
+p%eXfgB?/c-!S7_gB2f@nbrCc#k_>ljNEL+V9\Pa"LbAbp\k$i#PD6[jg&NS_X6(`X.n/&i7GJX
+MoscU]$0R9gBQ,\:6jJnjo4HCkmR6$A^T1F<N&8d`nB_5$db;VBJWkD=I7@bg@*c3frd;?F(JQS
+;-?t!:J4#C5s@1]CVe`ugB+t1mIf3G^bgnshspO@TV22XoBFeJ-G8g%'$Y`0Y1`%3qu-KkqY'@7
+V+u$Rn(SJj1l9[Q9i4ddrD?Ed99>uFEQdq-!kQVCo%W]tmFqX"n`T;op#l@Ws5sC@o@j>XbjF`N
+rqc]]le<2mcLC8glg!]rjPo.Tgt:3-d*BkZ`)H0["`6-t!&gYMgB46g2Jn$"J_Pb1pY,_;9n3~>
+qYqQ5o^1bsf?hXV]<n];TUCt%Kn"AhD.d<`=B&,$q#;5R='T0GCiXcLKStt[Su&Np]"uJ6f%oEQ
+p%eXfecaHV,[%kXecIXOoDAOnpK!mJc&He;bO=!aM-@=_qu6oq<p&PPAq.Yaed/@[ip#^id".2!
+ecN8$lM&jFc\"B#[Dp5/b0J;\k#Q!;en7-m/QT^RedBTdBkK4oD,chHeF(lnd]FW<2'<GA%/gb7
+#Qk]K^!uc,!k$/8p!s_g0oOK:oDAQ\T`=o`ldg8+\aS)Sa`h'of]`).rr36%q=3C@:2e2Aee5YN
+Mpb'i;H!Pp;Gp+ZOJbila7@d_[E7_)f(%qjec=RskO$jnkPq[ak5aB1ecN8$lKd%#!!$g#ecFe)
+mf*=^[ID`NXdFcpR)/[N"2V+,Xb#&Seq)EHecD"-J,~>
+ZN'm["P\n`>f?Qs"'V/EqtpBuAq->:KlN!jn)")s!nul8qu6k4R%TCfA$PR\!9!k9#dKi1\Yt?k
+0mi0ArSltr!klkHpYH(m?r3u=VZ!1fU^NDf>0>RQB246_T[rMe%*OK&9O)4pZ?ocDeD0NL(=lfo
+kND0R[AhI2hTiO6[CruUTQ-4Kp>,kac0k8]"Gf@chXCIDs$Hbc"o%KK`@ZH*h?C5rL",8Zqu6lt
+oBXtQ<35QF&r8iqhG-tIW;lmrW(osPep15ro%jG]c0k/Zn`T;r!93P3mG@g)s766XrT=@OlJ17Z
+iq)".^!6!2hZ!i]F6_T_Up]am"T.rfo/Z9r"im'bKUTsXhZ'j3hLXO7hY5k-S5+S~>
+qYqW9p@%5(g=+9b^:1>HURd^4M1^5#EboAu?<UB/;,@0d*D]O2<`r^;B5DR3I"I08Q(4SIYI;-_
+bL5)%kO/3Bs8C[TfS_(\_Yi-j7X<GVqu6n6I[cXTBn=.igB>9j^uY7ers!,%TT"/!Wq"gDh#?+8
+Yc?C4f#agmJ*G_dh<*Gn]$0R9gBGB$BZo)MrkK#\`5])u=i](CARDA9T%!)]%EXE&;e9g>`.M6[
+cdph>gD8788p=cL;di[%=&ht#AP#6T4>f6^fCmr#]$0R7gC]'+`ng+\rVo;TrVQ9VkJAoun(SJY
+A;/Fnp&+ghs8Mrko'=eN<N>NB&q`Tlh+pnHW;lmrVGBpTe9P&oo%O5WbjFuUn`T;o!9*J2mG%U&
+s)S1BrT=?d3B=5)iUbe*]$0R-g].-Nlg!4*`7FP[#6"Gpp\4,^n(S#A2?3_8V#&jGD1UGmgO\,R
+gB!a;J,~>
+qYqW9p@%5(g=+9b^:1>HURd^4M1^5#EboAu?<UB/;,@0d*D]O2<`r^;B5DR3I"I08Q(4SIYI;-_
+bL5)%kO/3Bs8CLOdt]5O^&?LbdL$u>qtpBuAq->:IpRE8nC@cmFWc%lqtpBtAsf6MF%WD$ec=A%
+g'G$mjQYa^_ejthf)==becN8$lM&j6]j+=1[@WcaS.)3X<`[&bdUPn%!1_L)edTNO84HQ^J!t4R
+QHn"Ked0Pn(d]2R'KIW@&-=RP'`A:=-]6@GecN8$lLi^2ImM35n,E@e6N@&hp[@:a/U-[7"fbsa
+eE6N&rs&Alldg>ZVXN(KImM35:/\$hs8T$r:.go)GuCO1ecN8$lLNNrkO$h#hXTdrf)=e3Er`?@
+k67tJ3N_K$o@<uNam/3Crr<%7lIH!qp[8%^pU0J@"i6RZKUBUPf)Mk'eq)D'f([_rPY-H~>
+ZN'gY$ep[i>/T4Rih?Hsn,*+i\ZV<JEG9j7nD=3'"5_AVn,*+h\YP1&F'bC,h@R5l[C`K<\#>UD
+=scIRDfM`Ch@GRAWMu,HS>;gNP_41$GB<?3!klkHpYH(<:5,m5GPlLk@OY?gb1b_'!3n7Fb1c=@%
+a0E"J[NJB`P&X*<gqUpnD4th;VL-nn#=RN`Q?Q9_:loF[C*8`GJi51h?(C8me,E>7Z?'ep\t3m6
+N@&hp[@;%G<,-K"d3T+iplpCrs&Allf+pHMsoL+7Z?'e;H!Dl##\'\ii6+=o%jG]c0k/Zn`T;r!
+93P3mG@j*%J/T=lLXE+mHW2t[HHQ@h?(C8md&^1#]o7e$`(31i4lt=hZ)NM_>CqG\H;No2=B<)a
+-q[7R`G<^s2T]IJ_kt7pYGq@:4N~>
+q>WYSo'>Amf$DFR]<n]<Tph4+Lk:&!Ec#N%@:!/?=&r=%='/X3?t<qfEHZ_\LQ.LcTVefs\\Q82
+e_K0KnG`7`qqDM2N$hcEgY:2+!Gh*"rs-!5Q@3UYGId4t"kUMgX3U,0rs#p)N,NK5R.AuDgps2e
+\uW9kf$;72;FktQFfFf`&D`8?W2>lHTVeNXQA'[0H$Ai6!kQVCpY-OI>boWQTU;1:StLj"<OTru
+g!KfG5s`WEn(SApJQ7WGe_Jd*`e.B[cdph@gDJVH,].0s>@kCMHVI@KVT+0c5s.1V@DU[lgB+t1
+mIf3G7Z5m_p\Y!j77I1Pp[@;$G<53I#*<Q(i:-R@rr39'r;#sMii6.=n(S"8Mq@2j;>pM#rVKGd
+Rc:>MMXoL']$0R4g[XIogAp4&kO%%'k7)J4!',,&kH-`E!-@>^o@j>XbjF`N!W23IgC(sNs5:],
+^>AnI^qfo_#/%OW\Fo5pmb7o@2?3_8V#/pHUk.9OgO\,RgB!a;J,~>
+q>WYSo'>Amf$DFR]<n]<Tph4+Lk:&!Ec#N%@:!/?=&r=%='/X3?t<qfEHZ_\LQ.LcTVefs\\Q82
+e_K0KnG`7`qpl/(M'c<:f%-W,!)i:_rs-*9P^-kAEOYGg"he.R9=sZirs$$,LhgHlR.Af?fX[fc
+]<8p.jP\b,B2EktH)U/^%GHoBXJhANTVSBVR"p1jHh,_h[E7_.ech(+JZ4NHrG)m]?7AdW_:$o[
+!3n+B`R=5+%`NomGG_^SWh,Sp<0khZnCA/Q$ooaJ&4*Rs<Y,g.S@r5KrWiT1<k[#WecN8$lLi^2
+6&aO`p\t3m6N@&hp[@;%G<,-C"cI!!iplpCrs&Allf+pHL[Wdt6&aO`;H!Dl##\'\ii6+9o%!lM
+am/HJn`T;j!8d8/mFM:"%<DLL3HM=cXZ6@]F6DEOecN8$lKd"%!,LiM$f^p\i4lt=hZ)NM_>1bG
+qtIMdecimWKS5`/qpte`J_#D'J_'SH!L-3,~>
+ZN'aW$J^[j=i97Z$jgkLqu6m!m)c&IGId5"#2nS'da$SDqu6ishR/SOPk*ZCi1>4gYI1pDP_FTp
+0+nZt%!h9t&E6<YUnj*.Mj0$I@R_dd0bj38!klkHpYH'l8>;>\9)^g]F(-S![Dce4hVJ7CDZIW)
+n(nS>8;#+8c,IH2]s;ugSCZKdhAFsMT\A8^l`L3em`E#Umf2:h[BZoq@$KC>h?(C8me,E>*4aqp
+p\pic6N<\^SF>XtX;(-["at10k4?dnTE_",lf,lkH10Sn*4aqpUo=4k#Q(<e_;`FAH1Ken^!6!9
+hYQF8F8G(eh?)^"Xn?c8kO%.*k7.%6V8M<XjP87]N4nE6oA0P^c0joS!-@A\$`(31i4lt=hZ)NM
+_>V(G\H;No1%!g$a-q[7R`C!9J_kt7nD429:4N~>
+q>VK5p$V#$g!\*`^::GKV4X0>NJN17G][k>BOtX\?N+4M?=75QB5;F,GC4ssN09R"UoLZ.]u8(@
+f\biXp%\R_gBuVn-s49t]a4p^qu$I!rV>]sSSrPWnCn/j^:L8Sg&(^I#6"5NY)?5Ao%Oc4TnBMY
+^;eLDaMa][6U*=MI.#`#hbpDUXI>HHU7@?qB2_>h*qJ%e]$0R9gDFd5`jh%?92/-PLGi/<_I_9P
+f`9Qe!5?kMgCW)%9TIfbh:U6+e&6rFR*jRWgDJIB:2Np2=aC&IfQh88mJj+t5s.1\3g84jgB+t1
+mIf3G+Lp7rpRn7T77El@SF>XsX;(-X#(:=1k4?cirh9[lT:Nseil#5Kn(S$h\D?VLVZ$Mo#lFFl
+T#0L*@!D1r!kQVCo%X$(s)\&"mFq^$kH4Dus6&e(roa<&rW!3aF#a4#3N_K'o@j>XbjF`N!:/k'
+(;n]&i5!(@hZ)KK^qROq]XkV_[e&fhmFqf?2?3_8Uk.9OgO\,KgB!a;J,~>
+q>VK5p$V#$g!\*`^::GKV4X0>NJN17G][k>BOtX\?N+4M?=75QB5;F,GC4ssN09R"UoLZ.]u8(@
+f\biXp%\R_edBoa-W[iS9`bB7qtpBtq;f;XBQ(<Jecq:45;S)KqtpBso@Bmr8sJnt&_a%<ZbOQ/
+gtpi?\U@^b8Mbkaee$\AZ*gj0TVSNbS<.r1@ob&LecN8$lM&j5CIXhSA4Z\W%rYc#;Q[WBdaltL
+[:TELcL9<pO@+<,_7-G;S=Gs^;O5VXo%!ok<[9^)&.2bDs34S5W:'\D3W99d"t>S\pXTDRam/QM
+"<=u/n+ZgSs$HaY"e>&EhQ.F[ecg>7bNAE>qk+.b`TuO&@!1qh"WY)0n"co[rs/FsSAF4(@!2%k
+!k$/8o%*[#s)\&"mFD?qkH4Dus6&e#roa<&rW!3aF#a4#3N_K$o@<uNam/3C!,LfL$f^p\i4lt=
+hZ)NM_>:hI\bGj+mFDHWR"U-[_1C0geq)EAecD"-J,~>
+ZN'aW%H?7"OXXAa;ZI/5o(2bWrrr5`ab=rLp"o`,rn[t:kk!NI`Tm'dqu-NtoA[#YPk*ZCiiSZm
+d`8baIs5s3-57""%X7?t&Ee-#f%.sRXK84bHX8]T0bEp4!klkHpYHa*>+B_)2+CaL@OY?c`Ff2!
+g;*d"IfR11nD4Am>Yr&OY+klb"d<b'QI=LXhAFf\cIU_+kI'%Ds6eJ+s7=ga[B6Qu96Jt_h?(C8
+me,E>&B<_up\@,Yn)rE<#k-URGAG^lo:5YD"dnW6b@5P]h?=J1ipZX=rVm0#p\4.Bi6,SNo%jG]
+c0k/Zqr\'&!!%*;kO%+.iodF(pAb89kND6hr9"HqXgQ[.`heX-kNCjrh?(C8me,H2me(W$W:\pI
+U9jIkrV$BblS7b_"im'bKUTr4hLXO7hXTG'S5+S~>
+q#;?/n`o/if$DIT]XG#CURmj9NJN49H?O=IChdWqrad']B5)1"EclYVJqo;IQ^skLY-bgWaNi>j
+ip#t1q#C0E(YREhMC([-8,rs%m-XKGs8Dfai4XJW[e8Akg=Y!+cFCaCYG/D_mHsTHs8D]XeYZ3,
+o%Oc4XJO\3hUBWc_SDk"KS!u!Hg]W"hg=\Rl/CCIe'H%DWgJ]]*:hhc]$0R9gDFdC_44mq799JE
+2H@'"AH:!,^&Z]^!4^AEgBP]%=3/q/\c&r?XF"*6cI_XA(ss%9=&Dt!?,HXAf#6tUfS+$'4?>2<
+ERsm=!kQVCp"KW_a5QL[6iBFY6U=$*jk79Pn(S%iCt.\>S4*?F#Xh!FQg*DM@WCkk"qnu8n+HMR
+rr!,up[de:ho]DJo%O5WbjFuUqr\'&!!%*;kO%"+iTI='pAb89kND6er9"*%3W&j[3N_K-iUbe*
+]$0R7g\5XZlN#u;gB#1@pAYHtqtp-^p%._<=mXlHUc&2Q2PboYJ_Pb1n_4)59n3~>
+q#;?/n`o/if$DIT]XG#CURmj9NJN49H?O=IChdWqrad']B5)1"EclYVJqo;IQ^skLY-bgWaNi>j
+ip#t1q#C0@(WjA&HQ<<>*WQFHh;7T"s82QWg:)-?[Ir)ecbmH0X]A8>01q2OhVR]#s82EMcCdXk
+o%"$!Z*36Ul/)Bk!5JN3!g6H2ma_U!J+N-tlf\9,#1h5A]sWqNo%!lMam/WO(i*<DEC2NK<WHGP
+;Q[WB!6Wa#!4@"N[Ee9m#K9k=Xf[J+EW0k[BMqTeb0ok3"3qHD*<$KV0tI>ac+WQFc!ij7#Qb?M
+deD;o[E7_,ecZQ(ipZX;63Qc?g:[d\ecg,1eEHLoqEb@QleorqDsu6\&B<_up\Xph#lFAjn*AoT
+@W1hg!k$/8o%*^$"*4GBF8P.fecXdlXZ?+U!d!PfmFM3u!HU:!!!G<akNC^necN8$lLi`oCB1%"
+ecF_%nc&ahp\49em+)?VR"U-[_1C0geq)EBecD"-J,~>
+ZN'dX!Tr_IiY1+20hDcR#slGMg@tXIrV,$(Fh.5&(ujcAio8nQmeu:k`R<&OakHLhs82E(<g<13
+&`U!eda,IuM03`P9HXfP$j^e>h@Sjoil/mEWM#oSOEX_[&.ej4h?(C8me>QTDe#/02/T#"!%CsV
+`Fif``P#/I[=eOjcLBZoPXBr0RXtEa#&m.$NlTT%o%j]$(tR-dg>^B!f)>UUpYO'+[B6Ks:j(Fb
+h?(C8me,E>*4=tqoDY9[63j$JR-Wb_W"e^W"at+1l0l[jS-PLM_<0Of??u"r"WXr5l_'pLqZurf
+TU`dP^Ku3Vh?(C8mdf64k5]T%!!%*<kO%+/iofL,3Vi^V3HP2_mG@a'#0tHB`mhW6roX:@oA0P^
+c0k8]p]'ml!-@eh$_Xd)i4lt=hZ)HI_>V(G\H;6_1$d["a-q[7R`C!9J_kt7o%jD;:4N~>
+q#;?4o^1i"g=+<d^q-nUW2#oNPE(KRJ:2]dF)c,9rbWTlDfKiAH$k-qLlIRaS>)p`ZamiibgP2%
+k3Vg9s8(INdDl1&'=N*95m[Ms2kd7ip%S+Jl-+`u[eAGmf#u"K_S*D'j1_.WZEC"'`:`lpn)LiP
+P4I?>h6!a<kM=Y1^q[UgTUD-r4E^)H&Dqp#j5\nIe^`-n_mZG2Bb9ji!kQVCpY-O%Dn0UEC7_p8
+3*3E&ATn-i]MW=jWW9KRn_49%O[tDOZ_.2b#)unZMSdZjo%OJs$?Jp;;c?J/_YsKAg66)H4?>JX
+)JdmtgB+t1mIf3G)Re\lnX?&@6UR<0R-EMYV@r@P#'st,kO-<ZrgjCcR@(eNg:^a7n(S!a[c?\H
+UAalnp%+iF]\:&(G4OAh]$0R4g\g47F8Z(=F8Y4ggB?KukH-c@!!,*$ro`\'qr\!^3W9!Z3N`;D
+!9*P(!kQVCp"T3Dp%naTo\1.te,S@A^:rJ(hS6k?]Y(hc\@/j7k?7-*"f+$V!&gX(gO\+1g[a)"
+RSA;~>
+q#;?4o^1i"g=+<d^q-nUW2#oNPE(KRJ:2]dF)c,9rbWTlDfKiAH$k-qLlIRaS>)p`ZamiibgP2%
+k3Vg9s8(:`OCD7#F%ml!*<?-C+C&iXp[dk>ikotU[J&/gZ[#e\CLBG>HTrr:B4bIgT_J'Dle8I-
+Pk*B1g9J'Sn`Jc`rmh;#`P9*b>'o\g"Q"Y"n*g2;s5!n0b/TYho%!lMam/WO(i*ND8hjtG[/_LR
+XhA4S!55p<;RLiO[Ee9m"ctriS8Cms63]Lt22Arhddkrkc2^<Br=Auq\c)O1c#Ylfr<NH-B@?P*
+!k$/8p!s6_[HHlIrga!T#Fq0Klf-Ko&F\0RGA#4cn&P?r#F_$rk1m^VF77Z`(q&PmTV28\#l!q`
+SA3jo>]]Je!k$/8o%*a%!-A)=!-A)$mFDEskNAs-q>^OVF8k@if)+V2XZ?@\!BI:]k5aB1ecN8$
+lLi`o!!$g,edL@+s5:Z*^#&eG^VTf\s1&4*n$VK4"i6RZKUBT,eq)D'f(.AmPY-H~>
+ZN'dXro+[]oBt._(^L*A#:>bAhY[3GpYq9U\b=ksi8Wb[naQ&Ds7Ya?ilRj`Z/5BTp\2s2Pk*ZC
+i2iHh^S7$RHZ*\'1DC0)#]K.f&E6T`S=kt"N0K6MAjmsV&-2:X!klkHpYHa*<ff=2UqP%R?F@ab
+A(CWd;Hg?1HN:J!n_Ol5D+LCiF]:Le>]<2!M8@Kgh"';.c6:cadam.+hQd%Z$Lc9V[C*-9OA'fJ
+pYGtbc0k8]"?h7okNi-=s$?t^n*AuedVh/7h?AmFZ/k0<r::0`mH39VTN$j<h??&lio`p+r::0^
+8kP8tTN$j?h?(C8mdf65k5]T#!!%*=kO%++ir8*AXZ?:Z!BI:\kO%.'k6:8<eAgM>rT=1?oA0P^
+c0k8]p[7]q!3#PH%A:!+i4lt=hZ)HI_7dP\\c9&=n)lFjh?:lfKS6U]hLXO7hX]M(S5+S~>
+p\u3-na#8mf?qd\^U^\QW2#rPP`L`XKReJtH$=H1FW,IKH@:<rLPh.VR%9tLXKo@M`6-HXh;dbh
+rV-?ggDJ8DY/\u<^311q!!!3@DOB&CmH`r_Kl=EngDJJWZ+A3.eDB-3_nNjRCNGlpmHs0"^.jd]
+gC`5AW8HR`cca2?^:1#/Q@D&@mb8</>K5(@c,e&Rc,[K$U6oX-o%O5WbjG/Z(i<fh:.(_daT,VR
+_I[l]!*rN=e^:/m[a4Ku&_Uqs[Bl!09hf\g>=OC\a3iQ1gBl17ED'#%;,^JPrVm5;APG?N3&`K-
+CXr16!kQVCp"L'@J`#STn+6-:61O@.iRuOq2"00'MdN^Jkj@p>o*FpUm,m-RT2LI5gBB]jhrRL*
+rUU<bm7U$5e=TWoo%O5WbjFuUrT=0%qZ$V;rTES&!9*q?!NeB[!!,*^rTES&qr\!^3W9!YF8b8%
+iUbe*]$0R7g\5XZlN#u;gD7TQs5:],^>AnH^:q7m]"#2W['];`=mF`EUc&2QD1UGmgO\,MgB!a;
+J,~>
+p\u3-na#8mf?qd\^U^\QW2#rPP`L`XKReJtH$=H1FW,IKH@:<rLPh.VR%9tLXKo@M`6-HXh;dbh
+rV-?geej>t#YK/IANL/!!!!$"+*6#qjPo%8H#'h]eekYs)C]!.C3+)g6TmRT!$QF7k2PCSYsO]G
+ee-Q9Z0L`9i83,;f$qp[]r5+]ma_Np@b0](rnd\7s4RV(`kdl_o%!lMam/WO(i*$)2*mb?`;j)H
+]jkR#!*W9$Z*A?M[Ee<n&_(MZM/>C++X&R%,rL=c`Qm!(eca7u63n"u&--qQrrSuR)#X^B"p/Gc
+pXTDRam/QM"?CtkkNi-=s$?t^n*AuedVgl/ecgh6Z/k0<r::0`mH39VTMU:0ece'`io`p+r::0^
+8kP8tTMU:3ecN8$lLNO)k5]T#!!%*=kO$h#hYu[=XZ?:Z!BI:\kO$jtk5h\FrVuq>rT=1;o@<uN
+am/QMlY?Kno[XE,oDda`]tN;&hS6o*^&>JCp[>NTec`gVKS6IYeq)D'f(.AmPY-H~>
+ZN'dX#MRVNb_@JJ"oJ?&"<+5mrV$EVP&\&+h?D]cce@a]qu6i^]pP=tgAUaIekVJ"h@Q3.Wg\Qs
+Nd5#9>!jVP&.!4Ah@D#8?=$Ar8lADV3@#.E&-2:X!klkHpYHa*4+0Cq]?8iC`PlIrdc,1\B>)!C
+CB1cfn_Oi2CKR0X:dJ282+^)j]uej\n_OT#(t-RLdaGtRdf'1QpY*<gZ)OXW5BGKOh?(C8me,E>
+G;75!ir89D4U:<8inDhk-$Sh7"fbOMf&GiilNcY7hU]Ya:9*d>&pH(Pi^uh5SEoL2S45u,`G\MO
+o%jG]c0k/ZroX9&q#CD9ro`\*!93t?!NeB]!!,*^r9*J(r9"=VlEdV+_s6Xgk5aN5h?(C8md&a,
+md8j3TX"4j!;lci!;$3Y!Tu3&h?:lfKUTr4hLXO7hX]M(S5+S~>
+p]!8Pp$_,(gss`m`4iafXf/"eR[0+sMMHn;J:DuqI!pElJ:`H0MN*a`R@^1OXKo=K_oU-QgYq>_
+q"FaagBZEGW24V]!sJN%$Nh3@dHToYj3WKt[eAG]g<6h-a5#b6g]#k7^5[8nYgM_"jl+!JP4@9<
+Ss7ULa3)WC\[JuMTpgKpG4"#p1mYS]ZE147ZEU:#R[.Y#o%O5WbjG/Z(i;p><`QZMdqQV7AT@87
+H[0hkft*CJ[a4Ku&_Li-[[gu"="?UC7YeUpcdph@gBl15Db!Gn:J#Q?rVm5`O@_Pq3&W9%CXr16
+!kQVCp"L((1<AA5kNhFt53_1fg!R5TF77ifW`FPsiT9>'lNle=j5&8'DG@%tgCeceaPTQ^S=Jp2
+S=2r<N5KO-Vt/RD]$0R4g]$@9F85e9F8k@igAp42k5h\FrVusZXo.ALg\g4>F#a4\3<2(AroX:?
+o@j>XbjF`NqetlV!Pm.[rseu*qtp3`p%._Bn*T.<lIuH;2?5Y2J_Pb1J_TbM!Lc`5~>
+p]!8Pp$_,(gss`m`4iafXf/"eR[0+sMMHn;J:DuqI!pElJ:`H0MN*a`R@^1OXKo=K_oU-QgYq>_
+q"Faaed'W^2)76+!<N)u$NUm6akkn0f"lWI[J&/ge?<7=;KHtm>#\<n3>a2\Xi]GVg=!5mPk!?)
+SdsW:gtpuCeC)jn`PJQXHgTAd4gEGdrm(Pls3:bd_7c'Vo%!lMam/WO(i)'Q4]8W&dV$8,@p717
+CMRRn]p)t+[Ee<n&CP2bGt]YE<\#(721rBUcIDC8"O7!6#RLD<!CaEprrUbi'`A:>"9<)_pXTDR
+am/QM"EuTBio9t's#gVQk2P+C\Ku1_echpMIFdE?r9FUOjPJJ,Db?bmee30]al5obS=Jp2S=E&<
+N5]^-U@Qk:[E7_)f)Fh4F85e9F8k@iec=S*k5h\FrVusZXo.ALf)4\9F#a4\3<2(AroX:<o@<uN
+am/3CqePTM!T*G?rrDropAs`jlIH*SR"UjCJ_#D'J_'DC!L-3,~>
+ZN'aW$.d53W/Xh(',:lR!!33?ec#4EjGn/hp"fl+ccOVtq>UC!o]iuSR'G62rV$BA8sJl&&;<kt
+?rUZT>Wjr15;OQ##]K+e":QP--li.%!>H+E$ig:uh?(C8me>QTPWN>J>/AM@g<sV;`S0%ocGdJq
+G>9-gddc0)g1t#b=>Os)>S]bd^WG!\nD5#5*502.b.Xe.p]'jVs8Vi<[B69sHTQH*pYGtbc0k8]
+&[<I&f%T!?ier`Sg=juoB,J>Nh?M#69;^@si;MX?hV-Q(Q9T-/n(n/O+EuE97LMiJi^QC(6A(Rg
+C<c>+!klkHo%sE0!-@l7!d!PfmG7j&r9"3b3<2(AqrdA'r9"=b_2Q(QXi'6!k5aN5h?(C8md&a,
+s6\YOTX"OR]tM8As5(T2^&GPH[B[!In)?(fh?:lfKUTr4hLXO7hXTG'S5+S~>
+pAZ'-oBbVtg=4Ei_nERdY,S7jS=#S)O,SsPL5#V[)MNp$M2[IWPaIu6Uo:E$\%TZ"c-tA'jm2O;
+pAasC$.HJSJU0s2&.o3I!"&cFbj"<NhopXf[e8Akf>b"k]\)#lf#YLVGE/iMjltmch7Q7@n_4V2
+Atl2rUTq;/W19$7Mf1@mmFqd_AW;V'L&HW(Jc:-"<=\TS!kQVCpY-OJ6@3!@^<>3]c"1\RnaZ)6
+kM+(RCE0e/n_4W,Bkb"o4)qQ0*(c""`R!,hn_4o.(gf^%8OQe&p]&mus8V2/6o[(\-Q-sUpY,b\
+bjG)X&[3C%e_/d;iJWWOgXjikB,\AMgBPW19;^=qhu;R?i8*)9b*>5,b4"'eYTS/?r^R>fiSd9s
+772]m5\eI4gB+t1mIK$3k5]St!!76)kO%"(iV_jAXZ6AAXo%;Kg\g77!!PBbXZ6B&roX:?o@j>X
+bjF`NqZQ<@(;J8shS-_@ir7`J_Rd7e[^<?G\Ei*Tle;Q<2?5Y2J_Pb1J_T_L!Lc`5~>
+pAZ'-oBbVtg=4Ei_nERdY,S7jS=#S)O,SsPL5#V[)MNp$M2[IWPaIu6Uo:E$\%TZ"c-tA'jm2O;
+pAas>$-no)'fI3D"U+u,!"&cE_VX)!cFJ"0[Ir)ed^*jH4^_Mm8ina93HM.<g>:Q3b,IOgn^\8.
+Fh,?%]>rFHb.4ddZ^+4-mFD@^LomrYXo>7"HPl>)!k$/8pXU1A2dT*W\]34Kb%"JgdaHF_`P&3o
+72WGXn^\6!B23@u-Z?1j$9*aN_p6d$ecO,.2>mdf0tm>]c-?:ghHCWm#Qk28DpnC2!k$/8p!s_V
++EuDjhW!OQMrNIEd`#i9[I;ZN_.H?;f\GE`iWn>of#s@DB#X5i"0<Vhf)A,H9&ei"7RBFoQ9T!#
+o%!lMam/HJs5sB'pAb89kND6`!8dY:"KaZa3N`2AmFM3urr<3_XfXS`F8k>&hXf;"[E7_"f)#I7
+edL@+s5(H&_;bLO_8ZDerOE$Dp[>NUec`gVKUBT,eq)D'f(%;lPY-H~>
+ZN'^V&),.NkPtS\erN9C&/#0[dJikBif%fdo\L)5dEC88s8W&]etAD@g@P7:!mXE&n_Oh$+>G>m
+2*EZ6(*Y4Y+qt6"mG7pF#Rh.?#QYJZr<NE,!:ntJ^!6!>hAF:85@RHPb1b]f:;+s$cH=/CTRUDj
+@_pXfh@\SG_qJm*Q9d[&]jNRX_opWdn(no8@[OjF_4[e-s7=sqoDejI[Afg^BN1GUpYGtbc0k8]
+"k%T;ONu/LecjLI`IAS6mbS0#Ue=gncI2[B#1V#AU.RSCmbSQ(G9E!#KSYT<eqf-8It('RU@I(A
+^!6!9hZ)d3F8tFjh>lR4k5qc,Xnq5JhYlUGoA[BqkNC-m^#%r8iq)".^!6!2hY[??h@$!]s5(H&
+_;bLO^VTo[!4Dg2"1daS1$ma"a-q[Ma+<)uhLXPQh>s-AJ,~>
+p&>p(na#;og!e6f_nN[gYH+RrT:D=8PECodNW+kSNK0'^PEhN)T;&3_YHtaP_T0pLf\Y]SnGMtZ
+ptHS7^6lsqf@.$D0-1Z;"qec7iSDY+CUWli(>-a0YL2%Se%;JoNjRF$lf[<cgU]h:n_4V$0MYPC
+As0$_S:kBS;EYn:mFq[P.R*hos#L0I;Z/c[-jK7s!kQVCpY-P&<`"-FOic;2Bj]]Zl07Bkh8#nG
+-=aX7o\1#4Wkd5#?E[3iRCZ`ZO2&]\f%TWJ(tE%h6UaL)H2mosM1aI\s/JjS1+j_0Qe;&e!kQVC
+p"L&(FWcdhcdUFpe'l^f_LWJ8mb8?(U.SOic-b%keC2jk`hH*iU$gYIcZL@lKSG;Ae^K>1KRJ>C
+5,%N$!kQVCo%X3-olL/rmFqX"qr\$_F05<%mG%U&%!)D/XlnlL3B=5)kMc$e!kQVCleD:>mFrDj
+d/Vt:^;Ak,gV1J5[^NQKZEUe%hc9$t"JdpU2PboYJ_Pb1nCmu49n3~>
+p&>p(na#;og!e6f_nN[gYH+RrT:D=8PECodNW+kSNK0'^PEhN)T;&3_YHtaP_T0pLf\Y]SnGMtZ
+psp5/XV=rB:.6uT!uqga"q\H$d`St9B!q9^%Fi.#2d00Q5qaAeK<`l(h?DKU`hb\[n^\8"5@S>>
+J$I/8_5)ErC/cKtmFD:T62O[`?>odG!Bg_ZecN8$lM&jH^JmF,:6*?Ben7Ucb0J/P_7c@c@MiF^
+cLf["eYg%-B16Va4dNK\08mN_cID=6!n(7(r<O!Es8U>U@a4rQPU-S@"p-<>eG%Mq[E7_,ecj0:
++HXmor72&"cGb8I@d_eOc^m^1YKkSpecsXNaeDBhSF4r?a`ASdKS5/?f%,Y5KR\JD4.Pil!k$/8
+o%*j(olL/rmFD9oqr\$_F05<%mFM7!%!)D/XlnlL3B=5)kMGg]!k$/8ldkq5mFD^&oDd[\]tr_.
+hSI1EqmcgBp[>NVec`gVKUBT,eq)D'f'q5kPY-H~>
+ZN'[U(#$Xqqr[&8ig?CqiOFV]j7W$%MJ]oqh@/2cg@astmd/r#T\f;=p]'gdc:4&gh@QW0H[.mk
+(_R5a&/%N^GB'MIhYD'jGDH'6o%jG]c0k>_$egb,;HQ\(db\b7SGf)dS="Y4.4(Y0g@sG;h5sZe
+8`&0:4blX-Zc/<!b0JSnmG8Vh;SBWSW2/G@f#>JRlL)d!V3$=/F34.4!klkHo\K_a;CQstr5AlV
+X`GWg;R,ZH"jMfc;O4rn`<X;iO@g-9J]I38"MI\^Ha3Lf#JmN`8eNY*a7A'g^!6!9hXTdrh>lR*
+kO%.)k5t[:[Jf7lcFqflkMl*i!klkHle_O=mG7l:Z24J$rV?He!;$0X"7,.,1%!g#a-q[Ma+<)u
+hLXPPh>s-AJ,~>
+p&>p/p@.A.hV$B'ai(s*[]us7VPBfTS!fV/Q2[$JPno^RR[p(FVQ$]&[CO#haN`/ch;dbgqXjg^
+gD/8#e^M+<bHb]HfA*T[B[P_ka*h^2o@k#4ZEi!"\A5haAXM*:mHN`kh:K/(P4@9<WHru?8OS<%
+Q^31l;M0@;V!Zq4ErgWGrHA9bD=ZE_]$0R9gC2Yo7;[0MA'rtD?bjDT^^.ZaTSbcUU;GITgD&AA
+<";IRf4d[C<`?<@Q^>e:d+6q>gDJVN/kn]#3aB\GM,@9*`mB322D-I!@DpmogB+t1mI]-E\ksr&
+YenE"`5KHkE?YTaY3t$Vb(VuVQ+=iQ`PfX$NCag7J&Ld0&\:ghH*G0*`l,g2Wc:TE.t>M.gB+t1
+mIK$%kO%"(iUQ*ug\p=8!!%*=k67tJF6D`Fo@j>XbjF`NqZQ<@!PZqZrt,2-qtg*^p%._Bn*TH*
+kMK;,gB=<1!&gX(gO\+1g[EktRSA;~>
+p&>p/p@.A.hV$B'ai(s*[]us7VPBfTS!fV/Q2[$JPno^RR[p(FVQ$]&[CO#haN`/ch;dbgqXjg^
+eeQIACJH`=2'iNmdak@?A&Za4Z#"$[o@=Z)D`q>k0ek7+#aEd#inE,7b/'`2Pk!<9W-s/F:gC*<
+^V-RP=G;6GT^C>+G6*2TrHeQhC\$$X[E7_.edTuc4&AsQA'3A88sl"FS-YLHF'^:=TY](Nee?T3
+;@Z1IdUt@J1K(BhP*3Z#cID74!jN^brWj&u]t%_p-!n.$?6oj_"9M]Ap=9;Qam/NL"LUuRHa3Lf
+#/RE_+TtQBma_Q\JNHbq]D]\R_mb_"&h/7Fma_NK:+:Opr5AoWX`I)I.=K&'ecN8$lLNNrkO$h#
+hXTdrf)=e3!!%*=k67tJF6D`Co@<uNam/3CqZ-$7!T*GBrrDrmpB'sP[I)NJ_3fnC_1C0geq)E@
+ecD"-J,~>
+ZN'[U$JN>bf!Vp2ifotmrV$NhnaG=jCUs&n$f'"Zil/=Af]&-cir/TToC).n6Bplo!cJ>QrWiQ6
+#]IlB!klkHp>-2#KgIXW3Qg(0B/t&3D['ZS/L>n[deV`7h5sZl&-*m)hV=JdCJnEPb0\Sbf%fWK
+!nL\>rj`T=`mVQ2\\6,,[Af[?Bj-nXp>,kac0k5\'%4$g2,8XkXK7e58hF3X#Y'0SnD4i2_1bBF
+ArWUfU5*,<6T#9"@%>L2h@n>B=uB')S?/fZG=jGS2%1j?SB^]_!klkHo%rp"mG7j&n`T;rrT=7^
+PeI"Xs5*e=!93V,!klkHle_O=mG8;FZ2`[o]tr_,g:P&/[JR31kM@r]h?:lfKUTsXhZ(WIhLXO7
+hY5k-S5+S~>
+o`#a+o^D&)hV$E)b/M0/\?rKBWi)\fTV%eQS/.ZeTVA6[WN<>1\%BGoaj/Afh;d_ep[eFZgD.kg
+dADVMR^-@^g["+ciSWA=_Kfh'o@k#.Wi`muKT;q8@?0+.l/gm[f?prhP3q!*FZb0QQ3)OuFirG?
+]$0R8gD@tb91hT5a48^O:R[Z8QBmJX5pUlkc.VsJ(>>cf'bC?fe(`N?7X/0B]ZAFGd*pV#mFrE*
+=$TJI5sB@4;*INLEHtJJ1+"/&P1TE^!kQVCo\1#)Y$3YUI@I=>R<_@V=V;'1H+NM"'@jgM7R(IC
+UTC2H@66h6%OYVPb4+.!c`UJ-9mrM4XI4?*/jhK+-XW=bo\0GYbjFuUn`T;o!9*J2mG%U&!W[;D
+r9+*^s5sC@o@j>XbjF`NqZQ<@%DC*fhS-_>hYPm:^:(EJZ3@J8ZK9nBmb7l?2?5Y2qV2%GJ_Pb1
+J_TqR!Lc`5~>
+o`#a+o^D&)hV$E)b/M0/\?rKBWi)\fTV%eQS/.ZeTVA6[WN<>1\%BGoaj/Afh;d_ep[eFZeePFq
+?7?Es(a&g*dc0!3da#hFWbQ.Ro@=Yo>Ve_e&/6*,!.3/Rg=F]p_7?'rPjR$'G?1[A]`P-5GKSJ<
+[E7_-edKBF4Yo)Y_:$bA2/E/'#%CUb+a:K>q:6,-Vc"3>!$BM;e<2sq6!Ch:rlP8eeEka%c;#K!
+$j[8>:)jNR+\l2i'F4gC-&g:GecN8$lL`X?af&5p:4Je8XI+3(/QNDg7X)90ee?B?ImZG4NMNYM
+LL<201CPX;QGr@E'?R1R0i!4gXK7e58hE=b$n#AI`Uq^_[E7_)f(%qjec=RskO$k!k5kX)Xo.A^
+XoIPahXf;"[E7_"f)#I7edL@+s5(H&_;bLO_8Z8]"240d[I2TK_3fnC_>;a__1C0geq)EHecD"-
+J,~>
+ZN'[U("0e<UhZ-eZ&FdqoCr"NnaGr'LhjQmh@J8Z_mbDNR]*KMOOj$tp[eCQ!mX,smG7n_#Rp\<
+!Xo?Qb2*35c0k;^(>R)r@XFKbf&"tj3GWCf2(^+;J%a.]r8%S4X]6)IrVus6a8Xp&cX94Z<g(VR
+f\5-Hh?2KB<hTH"s1JlLZ*C^AXf\+C@T%Qnh"KS+^!6!:h@e8YIniU-:/45H:2dga(`3f^`UM^t
+fZg4(9M%lP8OZ3WQBjlT'JYNbnD4i,aa[&X8PW#L78@ceQ9uK'0oOHPh?(C8mdf6)kO%++ipl4!
+hYlU;oCh>Iiq)".^!6!2hY[??h@-'^s5(H&_;P.A]=kWNZ2^p.Z00sun(n2fRY7-Mq;2.VJ_kt7
+J_p.X!Luo8~>
+oD^QBo^:u)hV$E*bK%N8]=5/PY,nY%VPU)aUSO]^VPgDoY->7A]"Z&$b0SSjhW*hep@A7XgD.#H
+S9n"XFamV>c/[jAgY(*&^34.to@k#"RZEA;AU&NN>Be?Pj58VCdESmXP3q!*FZb0QQ3)OuFirG?
+]$0R8gD8MbO'm:#`RWYhAPJJN8P)3)4FOf_fDOA+g8\*e&H2Y@'u\k]fu[PrH<H<NdF?b"g?dQ0
+fsWk,91;$:8j5?u6q0L01+41iDoLH(gB+t1mIT'Fcc1<+7nQKM8460j\nr?&&6$I8gCr,[Tk$bd
+92/#J87%OF6Q$RmMSel;'@4[F9h.fM9h7ZHDj6JR)&+f_cLoon]$0R4g[XIogAp4&kO%%&k5]Ss
+k5aK4gB+t1mH`O("RXqZ][$Q6]tD,9pt!!g['I!AYcb(3j4dT&gB=<1!&gYKg]),AgO\+1g\9G'
+RSA;~>
+oD^QBo^:u)hV$E*bK%N8]=5/PY,nY%VPU)aUSO]^VPgDoY->7A]"Z&$b0SSjhW*hep@A7XeeN63
+,p3mo,n'cG_:m>cb/M'%Uh4/Fo@=YP4Vf4[0/j^V!(t)]daH:S\ZqMZPjR$'G?1[A]`P-5GKSJ<
+[E7_-eeZcQN*^^m_9UWW@l7n/0ek7+3HqmMdeqZ!eYc:Z&,lP0'Ys_!$HHC5>Y^3pbg=efldc?i
+YpgM0&-s*irWiK<rYPhF"99!G^XVu.!k$/8o@=Pr_08L@8PW#L5tYq#C)@d!:;-/J'@4Xf?q<d\
+:.[fA>*+e2(_eWW^$sSdah`0n7S-?M76sO]OH2[E'JG0^p!s2Pam/HJn`T;j!8d8/mFM7!!-@ks
+!8d=u!k$/8ldkq5mFD[#nGh@Y]tr_.hS6o(\HK=Nn)q+Iec`gVKUBUOf)Mk'eq)D'f([_rPY-H~>
+ZN'[U%Df<>O?ok^TSSE?lhC#LmfVF#BY!`k%aV\_Q=tEKZ(Qo/_<^jerU0g54d>?j!H/2?$ipQN
+b2*35c0k8]'\q?eaiVubhVQgr8o"E->$@H0cJ&6R"0Yi:%K$2,&?l&h#hkkF?=Zs$db<pA"ko&E
+S@,d(Ym[\5WMQ8LHY5cZZ/#$/!klkHn_Ol+]o6l>@rI=2`R;aG8g"CCddQ$*fZ0e9Bk(k*T"E1i
+EAKHd0j<#oh@e8MN,N39DiCs?bKOr^2&%d2f_4/'^!6!9hXTdrh>lR*kO%-rk5aN5h?(C8md&a,
+md8j5T!&+lrqc]irU^!R!9X7>!ST9th?:*PKUTsXh?1g'R^%G#J_kt7pYGq@:4N~>
+o)BL&o^:u)hqQ`1c,mrA^:Un`Za$^:XfVN&s/Zm:YHbFA\@]Jk`Q?BPe_8m?kjJ-6s7b7_R!j72
+32Wj.=^ebnh:^?-cc`n@B"%<c'tK3KI9gckQ@E%G[bKWke^;X`X?)O3gB)LQCAr\aC,0qSgB+t1
+mIf3Jg!e*_`6[,kg!OADO8r9`>FE.Iec"5)X]Q#@qu?a/Xo@&^g=;ZiC2m:@d+-h6gBH2f/j<&t
+rAk9F2E!BC-6OR8YhA^(!kQVCn_4Z%\qk95@;gt)_U$+>80A7BcgTU$e\n/.BOPS$S%-P]D_a-a
+0j2ikgChiDLi6^1DhtR5aN8?U1_ha0eb7`!]$0R4g[XIogAp4&kO%$ok5aK4gB+t1mH`O(Dsc9p
+]?L6OqY9gXoC;;<lg*fujl>CYhq(ltgB;@O!&gYLgB46g2Jn$"J_Pb1pY,_;9n3~>
+o)BL&o^:u)hqQ`1c,mrA^:Un`Za$^:XfVN&s/Zm:YHbFA\@]Jk`Q?BPe_8m?kjJ-6s7b(Z3=n&W
+0r^C0$m;Lob0%Q6[B5s,@^YgY'o+([9M')mDb:E\W6WQ._7?hMO>3!eecL%eP5_B]P"Bl?ecN8$
+lLi^BeBl7P_913Wf$7bp@fTD->*QG6df%`!WE'H:qu?a.WVtBRd[3R%<_S\!dcf6cdYJ_W+;">S
+rr`H)'Mbd[p!s2Pam/EI&]qG5C0k4]K;cK*]c9We#Zf(9ee6<DS9JLMA9X?G_o$:H2&%]Eam[dn
+agHb9?=%B!W4g*dCbmp_09FNRecN8$lLNNrkO$h#hXTdrf(%o'hXf;"[E7_"f)'7Meca^ps8W&q
+qZ-BeoD\%VkI'g1"Ke&ER)/XM"2V+,Xb#&Seq)EHecD"-J,~>
+ZN'[U%)&X)Ue]A0d]nb=kO\Z@"RXusB"@Ni%F)5NS9^4UimP)j[HI/[mfVn$3L&pf!cJ,ErWiQ0
+!cQ6<!klkHoA0K&rn@>-$.aG\!3s5Raj/W=h?r)MO]s:L#ljr7NVqW=gt%ul4Z@f;g?7;qg4s<r
+Xo54*V4a'&G?S$sWnR+%!klkHn)!ohs5""/CH5Q@#\VTRh>l4*dL+X`fUbu44VS07ddGugdf8/0
+fUbu44VTiFf_=5(^!6!9hXTUmh>lL(ipGUmiW.p.h?(C8me,H2F7nr$k4IL=Oa!b$U7e0LR$a2(
+OT(4:LB3#InD=.t!1N_g".Fn3a+<)uhLXPXh>s-AJ,~>
+nc'@$o^D),iS<)8d*0VN_S<dr\[SuR[/I<E['dBQ]"Pkq`Q69Le(<@4jlu4,nGi7;'qCGHU.<Jk
+_N\c3e(N:!ccaA;E+QKLgD.>eO-asGg=4!(Br9A4e^;X``MbbZmFq\b*&@LU!\ta<b1d!/bjG&W
+"PVMZe_0rV$JEgX8H>p)^r4RNrS%\5[uX]B'+"X=%?(/=$/![o;FWcqcILV3gB>uT4?,P&2@),l
+-mT]dIAkcigB+t1mI/g+ci;`)cY5@@+p_c+mb7`lqp,W"gXVfk83I[nA^Bf!qTo2r#h>GB83I\G
+Raq/e!kQVCo%W]nmFqWtn_rlin_jK)o@j>XbjG)XpZqKj!2]>B&$r7S_S3Uj['?d7WhcA\SGnuW
+QiWF@nD!pB!&jXi"#^-;Uk.9OgO\,RgB!a;J,~>
+nc'@$o^D),iS<)8d*0VN_S<dr\[SuR[/I<E['dBQ]"Pkq`Q69Le(<@4jlu4,nGi76'i&(fTKUT[
+[;%Rd_8a=%[B6?m>[k,4eeO?KEKY6ofZU[;2425"_7?hMV2-jjmFD>_.S9V?!_Fkcb16X%am/KK
+!7_"rrRM;#F"mZo[CsDqdf%`(e[(3:.2*!f!"F_]ed0dNQ:a"jH-4RuecaEJ.23?i#R1D3!$Q]d
+eF_;n[E7_&f)!Mged'</3EdO2@`e&h!71Pa$I@;LQr$@;'F80imah6Vs4.J%Qr$@;'K)3&pXTDR
+am/HJn_WZa!8?u"mFLga!8@%q!k$/8p"&GE!2/u8%+sS)lK7*ahVR&?f%0cIrQYDFnCISl!1<Sa
+".4b/_1C0geq)EHecD"-J,~>
+ZN'[U$duGjbuW]himt6>gAKe1gsUac\b"YdfYb,5OdbFrimt6>gAKe0g<)F?mG7i?qJQA2b2*35
+c0jlR#M*Mf\]WLWgA'M.Yq6Xi$=EYd#Mdn#AU1K-g?.6'g5pYkH]4>RKR[o@8p?BJg@O/&^!6!,
+h?Lu44]2t"`oPt]d[!d$1DC,7jPC-iQ;U4/%VO5ah?(C8mY]j&^!6!<hY.<KrrDKZh@-]NR$a2(
+P`h,iNJi_iLB)DbhXduPa+<)uhLXPWh>s-AJ,~>
+nGa1#p$h;1j5/MAe'Q=]a2Gj1^V.;X]+Vci^;.V(`lZHNdam./io]Rqq="@XgD.T2[`D7piRc,<
+Ur(3k^qRCgXDMLVo@k#*]!T51P2"dDa-ia?aMbm,\?r%iP3q!(W;:W:W63ir]$0R-gBcK[AH90\
+e(*.HgBFc3'EAJHqqDG2f?fmqHEGKDg?@9(g!u0i,Ub2t/h/=p)B;n=e^rOIgB+t1mH*(,_du#0
+'F;V;gBZ&h;FiSX#fG`X#LAW482C`echH/q]$0Q!gB+t1mIf6.qt1'lDtMco_m-VUYcXt*Vkp/_
+St)8GQiN!4g[f7^Uk.9OgO\,QgB!a;J,~>
+nGa1#p$h;1j5/MAe'Q=]a2Gj1^V.;X]+Vci^;.V(`lZHNdam./io]Rqq="@XeeP-bZ,K2\g<RBa
+R'F'(W2,rNN`oo"o@=YkWiisfN7QM(]n;]W[BZ['R$`O]PjR$%VYYK:VTRHk[E7_!ed'K1!3sAc
+daIpA"fj-f!"*!-ed'^MQ=+p;b0oG'#1AH*#Qt89r<*9("A4KueFV5m[E7^qecrfs4]2t"^#[`L
+acB7g1DC,.jOORXO&/>&%V!QSecN8$lAF-o[E7_,f'<;9C[fmYeC)^hcHH4/pr*6HnCI35!5X6;
+J_#D'p=98/8q6~>
+ZN'XT$.@D]<g]8=OGJ8^L^&QcK7R3:\anSaf[SWDGF4\\OGJ8^M#N#.Il3Imh?)6imciR1en;tM
+pYH//E&>3A"ZP95h?Mcdd*C"hgu[B%g:_iW:/45<2*l;1\_?T1!nHH$jk^3i`a_.C<lX4W#M@7b
+:aZfT`oPt]fZ]RV-Spe2pYGu%k3e,`!nHH$p"oFap$MhBJ_kt7J_m]h!Luo8~>
+n,Fj9p[[_9jl,%Lf@83nbf\#H`Pf[3_Sa:0`Q$!@bKeJ`f%Jm<jQQ"%r9jUZgD/Dfe_*`[OGo!D
+F*i=\GBIqECeeHJo@k#6eC)s5Dig!<Lja>kI<g$XEG]JHP-E^@g'$*Vj6YLcgB?3WA\c^fgBZ>J
+1V+8(2VS#^#MRbVc-+A[f]Cisf=Gs--5m^8'I$\"\C^9*!n68ujkC!c_dbkA=2X+R#M$q[;'uoV
+_rTPWe]F"P-Spb.pY,bujm@r[!n68up"T6,oksi,J_Pb1J_RKb!Lc`5~>
+n,Fj9p[[_9jl,%Lf@83nbf\#H`Pf[3_Sa:0`Q$!@bKeJ`f%Jm<jQQ"%r9jUYeeH6OejbIOKR7cT
+Df9E'A7/_K6X[=meeHHRdZ.srL4jnpC2\$+An#(Q=tPuCf)O8'eBR";e`t]fc==Q1pXTStCbiF5
+"Z=j+ecsXLa2c?JeE,6bd^a-g'F=[<";FIDZ-r0n!mfrmjjjXX]j<i5<k[SF#LC;I:+$TR^#[`L
+cbk`;-SpV$pXTDljQ_WR!mfrmp"&GE!2+noJ_#D'ZIT&@8q6~>
+ZN'OQ"cRqPF)Q!pCB/&IAccLo^[L"`[=rmIF)Q!pC].iG@\C!_rSI\=mcON+leV]odb=KQ#J2d5
+gVO1;eG%f"h#?"-gu@/mg:_uWrbhmg^"V30h?)j-k2bA&d`-'4_:%B##2%.eB4Jd+j5(!mba<%+
+ak6@E!p8q5MV\EsmcNB_!R9DNhLXO7hR),?S5+S~>
+mJddpo^M52jPetMf[eO!cd'eZbPoZab7DhBcdC4lf\50>jQGjtp&=@Yo@jG)HZ*b<C]8&JB*MsZ
+A7K(u]^OSZZ%7%8D/F(fC&_iGAcH6@@@jp^'&)!he^W*tdaHn1gXFX$e^iC,nCn&udEgG>gBY5D
+EnJ,3*msc;#27_[e(!"'jP'die[g2-CBK!pe_0HH!p&b0jP'ja_eW\rcf<aae]F.i@DL4LgBQ3M
+QY)B#eb@f"jR)#cgB-I'jPJVlb1V@#J_Pb1[+bVM9n3~>
+mJddpo^M52jPetMf[eO!cd'eZbPoZab7DhBcdC4lf\50>jQGjtp&=@Yo@="nF),RhB)?$=@"#TS
+ec`!uDej.dB)?$<?C\IT'%PIYd*U+ac-=kuf?V[fd*^=mn(%Qcb0p(9#IH4(e%5i+bkKZgeGdkr
+eDf$]d^a^?rau=[[F3LmecOdpi8iGmah;:m]uf<c#1(2L@U?aij44F\_i\Dg_pA).!oWA%MUhje
+lJUOM!QNW?eq)D'f!O!/PY-H~>
+ZN'OQ!ResY\H0Imn(n,ubJ3YZ!6)D'r87;-r86r!!8@8*#i0k][,0Z*$cC?Js4[M(s4Y]RrmK`]
+!8.;!i8+RgdaHd!hUpZeb^hEcJ_kt7J_m`i!Luo8~>
+m/IXrq"!n>kiLg]h:pW7f$r0trmLhq%Fiq[f\50=ioK:gme$GCs7=tGcbf:^!PH_HgB,pH]^rQ3
+_R\D-g=Om(dEp1ac-6+/$-^Z>cHjneeC`LGg],t&gBcMZ0!X0cPRG>#gB60_g"PE>!SQ*'eH+:T
+c.i6Di7e7^rm0NW"4b`DeUcK-gB5QI05Z9pJ_Pb1ZeGML9n3~>
+m/IXrq"!n>kiLg]h:pW7f$r0trmLhq%Fiq[f\50=ioK:gme$GCs7=eBah@;R!P->@ecO18\b!3/
+]t)]#e^Dgibfe/NaN+4u$-1-/b0/#Sd*pP8ec=.oed0fN/ZmUTOUAbJf)*n>f)EeLec=%qal(_P
+ccO;TJ_&K)"3#[@COt&feq)DYecD"-J,~>
+ZN#L4p"o]*r8@A/r8@S3l.uN[3bR+Eh>qYsJ_kt7U#$!tJLM682r0&AJ_kt7Zeb_Q:4N~>
+lMh@mp[[e>l0%-ei8<AGgY;\\%,9RnhVdDSk3;7$oD@ePJ_TqR$eX"YdE^"[aiMNB`VdX^`Q#s>
+ai_iQd*pOule;NW3G-h@gAu8lJ_Pb1U"]dnIjl!52VN`:J_Pb1ZeGML9n3~>
+lMh@mp[[e>l0%-ei8<AGgY;\\%,9RnhVdDSk3;7$oD@ePJ_'SH$e*JJbf\#H`PfX0_>M+K_$Rur
+`Q#s@bKeJaldc0M3+L>7ecBW`J_#D'U"0FeI4,^22:[9/J_#D'Zdo/A8q6~>
+ZN#L4pYPr-ro!b6p>Z&0ro!h6m+qf#/$&U)!5sHFJ_m0Y#g@iL'F"O;+Oku!J_kt7ZJGVP:4N~>
+kl2%hq"+%Dm-<fsjlGJ"iX4`,jlYdkm-aB9qre!1g\KS6f[\Erc-",I`59C,^V7G]^&PeT^VI_'
+`5]m@c-Fbeg$[SrLFT;$gAo*AgO\+SgBboN.ME!d!$BU>gO\+1gToQ7RSA;~>
+kl2%hq"+%Dm-<fsjlGJ"iX4`,jlYdkm-aB9qre!1f(ml,e'Q@_aMu07^qRLo]=PTQ\c98@]*c6c
+^qmq.aNDcSeF(lhKINbqec<C7eq)DIed06C.2)jb!$BF9eq)D'f!<j-PY-H~>
+ZN#L4q;2//ro!h8r8RJ2rSmh8s5<q7nD48h6X/&khLXOUh?;&R.MN*c!!*eOJ_kt7J_mZg!Luo8~>
+jo5Vaq=F.Gmd9B,r9F=J#41dHnb2hYjo9ndqqD\8e^DdfaiD?:^qRIn]",>[rjMj9%_0']]Y2+t
+_oBdAcI(1ro%O8e6<_cfgO\+OgB>WJ.ME$b!!*bLJ_Pb1J_RHa!Lc`5~>
+jo5Vaq=F.Gmd9B,r9F=J#41dHnb2hYjo9n_qpl>.d*9bS`PTF(]=PM\[^EKKrj)R1%^`XP\@K5b
+^VRk/b085_o%!o[6!2?^eq)DEec`s?.2)m`!!*bGJ_#D'J_%*W!L-3,~>
+ZN#L4qqhA1s5<n8ro3n:puMA5ro3t:s5<q7oA0P6.A;=LJ_m!T$I!ZQ'G:oW!!!P0J_kt7J_mWf
+!Luo8~>
+ir9Pfqt^!Zo^_SCnac>Gp\FaGs+/r&gCVudccsSO_nj("]!o,UZa-k6YRn(FZa@0M\\,Vk_T'[@
+cdUM<gB*QfSq5XIgRd.,a`KHT&e>!C!"Z#ZgO\+1gT]E5RSA;~>
+ir9Pfqt^!Zo^_SCnac>Gp\FaGs+/c!ee$9UbK.Z=^V%.e[^36DYHG#*X:VM:YHY:<[C<]Y^;7b.
+bKeQ.ecLp]Rt9.Aet1G"`H!jM&J"mB!"YlVeq)D'f!*^+PY-H~>
+ZN#L4r8.J2s53n9ro3q;rT*b8rT*t<ro3t:s53n7p>,nu:J]>ghLXOOh?Bo%$ig`jJ_kt7J_mTe
+!Luo8~>
+g].<QgAc`YrnA%<e^;[ba2>^+]=>;UZ*:C4X88h.X/rJ-Yd:aH]"Ghq`lZKPe_9fQ"3jS9c%4W#
+gR6e"W#lEJ%"j,cJ_Pb1YM0)H9n3~>
+g].<QgAc`Trmh_3d*0VO_S<^n[^<<CXfSP$Vl0His/-F,WiN5)Z*UmK]=u,#aNMr\psoPg9MENY
+eq)D?echik$NLTcJ_#D'J_%$U!L-3,~>
+ZN#Khrk/cU^qmn*`5Ta:aN;QHbPo`[c2YusbK@uLaN)<?`P]R/^q]]Y!f8.OJ\?WJRCrg9@k)U/
+#Y]f_J\?WJY.Xk+:4N~>
+ZN#Kes1/oR['?a5Vkg#XS=,\.PECodNJrdRrJD8HN/WdXOckrpR@Be@USb#lYd:n:\cRU2I=\t\
+]#2)Z\_+It[p^_,$4':U\q.GD\urUFRSA;~>
+ZN#K`s0WQHYH4\"U7[sEQ^*_rO,]'TM26qBrItu@LkpqHNK0*`Q'[r0StW!ZX0/i+[/tt)H@`JT
+[DTBP[+MbjZ<o#!$3s.R[=P`:[B?n<PY-H~>
+Zi:#TJPHtU:fCG!?"%8UBl%^-FEVkRH[L6jIt.HJrdXrr&:8_JG'%bDD/*]o@U<8@<)<Hf"%j[Q
+7Y+<c:<602:f73ir)<Vn!`;ciiD'VE&gg:#!"hqV:4Z/k:9@7k-\)~>
+Zi:#TJP?eP91hcG7RTU15X.Fq4?GSa3B0"t2uY`72ubl;3=\)34?Ykm5X@b*77Tm?9`7Zf8K\g=
+JPC\ia\De/s%E/[s%EAciCsPC&gg7!!"hnU9n?#i9s%+i-@c~>
+Zi:#TJP$PI84Q-;6U<t%5!;"i3]T/Y2`CUlr\XR2s#(BH3&s#\4$5\k5X@b*77TrJ8cqR)(.3XF
+JP+$Vs%35]q+(HUs%20A#<reG81"<J8V'Kb8qBU:8cU/f~>
+Zi:#D^44(>'le>=H$k*nKSPDBNfT?eQ'Rf*R[]fESH#&qR[KP0Q'@GnNf8jNKn=f&H?XIMDf8Yl
+7"K9-Douu(E,fo?F`hkOGPl[jGBS.PFE;JAk&1NC5SdI?D]T:"JT$*XJT%T-J,~>
+Zi:#B^44(<'l.MrA7AqQ>Zt62<E)jn:JX\Y9M8%V9)hQa9GU>t:Jaqf<E<4*>[CfIA7fLkD/E5e
+6\0**D9HerD#\5PBkV-lq.BV="DDLaCM`0N#])^@=)Ddp$YP$-JSfsTX)3@~>
+Zi:#@^44(:'PV2k@piVJ>?Fs,;c6Ff:/+DT8kSqOs%4)#9MJ8X:f:4l<`iO1?=75QAnl*s;\_WM
+COp9EC]A/LBEMmZAS([Jrac4EB4u!okA(?<4r%(5CE*[mJSTgPJSV<%J,~>
+Zi@`,!,oj5s5++?iSieVj5f:_roX7DrTO"?roj@Es5jgQjQ,@]io8qTi8<1#42ZX+J_nQ+rSRM1
+rSdV2rnlqr"2m<3fDaV-0Yi7rJ_kt7Wnr7~>
+Zi@`+!,]a1(>%$\ai2*/\?rKBWMQA^SXPq3P`h/jr/V_WOckonR$jJ9U8=fiYd:gO^r4==daMhi
+_1C?lgW\C[g"+[$cd'bXaiMQDrPnlXs2YGfbK\>[e(*.:gB5;T@FY;2!AM3<gO\+1gT'"Y~>
+Zi@`(!,KU*("1CM`PK3s['6X2V4jNOR?s/$OcPLuN#7P7OHPioR%'\@Uo:AuZa[Q^`5p3LA3%;R
+eq)DredL!TccsYTa2Z*:_nuAgs2#)[`5]g<b08/XeEYTe]fKNHrmh*&\Ui=_eq)DPepm~>
+ZN%Yq!!($qs5+=EiSrkWj5f=`k2tjikii!0q!.hBs60LGs5s@Cs5XIGio8qT[P3-cJ_kt7bMN6U
+ro!_5qr7P4rS[_5leV]%.]E=&!SXW+hLXO7hPo@^~>
+ZN%Yn!!('o(td?`ai2'.\$N9=VkfuVR?s/$O,]'UMM_:f(l=0/NK93cQC+27USb&oZF7B[`5nl/
+HeO&*J_SH(%b]C]d*BhVaMu08_SO%'rkAoX_84"+`Q-'Bc-Oeeg$RMqMCPJ$gB#p+J_Pb1J_R0Y
+J,~>
+ZN%Yi!!('j(t6gR`PK0qZ`gF-US+-FQBRGkN/EFHLPGb](l!g%MN!OVP*ME)T;&6`Y-PLJ^r3$"
+Gh%ArJ_&)s%+NYLbK7cC_nj.&]tF6Ss1A]Q^VRe*`lQ?Id+%I6!f&4urRM"tVLd<Leq)DOepm~>
+ZN%\r!Ls/0h@AH$iSrkWjQ,Fbk3(pkkl0iGlM0]DlMp,Kkl9iGjpC/1jQ#7WFu6khJ_kt7bhiBW
+ro!e7r8RV6qr7V6s5<q7n(n/i7T\&ihLXO7hP/kW~>
+ZN%\o!La#0gDS\occX5B]XP2LWhlG]R[95#Nf/aLKnP)1rdbo<K7nr5M2R@TPEqW-TqnZiZ*q9W
+AhU=:J_Pb1cJ'Sse^Mjhb/hQ=_8![r]=PP`\@B)[]">Vf^;.V(`lQ?KdF?k>gB5Mc<mZEPJ_Pb1
+U>(1~>
+ZN%\j!L*T*eeuuabJqB1\$N6;VP0TMQ]mMjMhm+@Jq8H%rdG]6J:W<)L51YFOHPotSY;mZXg,=E
+A1jn.J_#D'cIO5id*BhU`l#X,]Xt_a[^NTO['[6K[^NZT]">Yk_8O@9bg=l0ecWiX<6KjDJ_#D'
+U=Oh~>
+ZN%\r!Ls/1h@JN%iSieVjQ,Fbk3(pkl0834rTj:Grp0RKs69RI$g6[7jlGL>2K[g6hgsX8hTk!X
+hu;R6iVqj6j8A!9j8J!;iW%j9ht#V*QmePWhLXO7hOr_U~>
+ZN%\o!La#0gDSPgbJqB2\$E09UnF9GQ'%)bLkUJ3Isuclrd#H/I!pKpJq\u;NKKHmS=cUUXg+BJ
+@`$:6eUcJ+gX+[df@80laiD?:^V%1h\$i]NZi%*>Za@-K\@T>d^r"(3bKePeo@j>4.%GkCJ_Pb1
+T\Ft~>
+ZN%\j!L*T*eelcW`kf<sZ`^=)Tq%O9P)YBTKn=i'I!^/:GSk^PI!pKrKSPGEOd)6'TVSQhQn2XZ
+`ll_[eq)E!ee$9UbK.Z>^qI@i[^EHHZ*1A/Xq._?Z*LaF\%0,b_8O@9c-c.6!g4puJ_#D'J_$LF
+J,~>
+ZN%\r!Ls/2h@nf)i8N\UjQ,Fbk3(sll07Kulg+Q:q!J(Irp0UL%dE3@kND!gKeU!qiSi_PJ_kt7
+d,+f[s5<q9s5O%<qrI\:r8dk;ro3t:s5<q7p>,nu;,,>ehLXO7hOiYT~>
+ZN%\o!La#1gGmg5bf@T5\$E09UnF3EPE1WXKn=f&H?j^WFEDSGFEMePH$k*mKSPJHP*VQ.Uo.cM
+PJ"`ObL"pngO\,.gCi2idE]nT_nj(!\@/cMYck43XSf+2XKA\1Z*UmJ]"Gep`Q69LeCjTN"3s_:
+bCSE!gO\+OgOK~>
+ZN%\j!L*T+eeli[a25O"Z`^=)Tq%I6OGo!LJq&2pG]n3.EWC+YEYrn@GBnRbJV8f;O-5j!TVGsA
+O12d<`llk_eq)E$ee6KZbfRlA^V%.d['Hp=XK/A#W;NP*W2Zi!Xfo"9[^`r`_8OC;cd_^?"3F;1
+`du]leq)DEepm~>
+ZN%\r!Ls/3hZ)IGi8N\Uj5f=ak3(sll0@R"lg4!;mJ-,KmJlPQli68MkmZe=bs6"!jQ#7Yi8ELD
+hLXP4hZ)L5i;_d9irA';jSe3;k5=??jSn3>iWS5ui8<Geh?'E#PC_SAhLXOShLG~>
+ZN%\o!La#2gDehqcH*o;\?i?<Un=-CP)bESK7A8oG'%bDDf5Mj)/aD6F*;hUItEB2NKTTrN%Ri'
+ZF@K`aN`1bgO\,/gCr5hd*0SM_7mOk[Bd$>XK&7tVPX6e';_S(W2co#YHbIC\\,_qa3)]Uf_O8'
+TIH"SgO\+1gR[)L~>
+ZN%\j!L*T,ef3,bai(s*['-L,Tq%I5O,JdGJ:2]dF)l29D/B/d)/O/.EH?;JI"-a&MN3jdM(MAr
+Y-YXO_oU,Seq)E%ee6HXbK%Q;]XkPYZ*(1.W2HJeUALVsU8+N]Vl?`!Yd1[H]>)5&aj&<1ecM?i
+NIfZ3eq)DCepm~>
+ZN%\r!Ls/3hA"l*iSrkWjQ5OdkNM0plK[^%m-X3=meQ>Nmf2\Sm/QA]lKRQ"0!FF!jQ#:[iS`UE
+hLXP5hZ)L5hur#uioB(ujT"?>k54?>k5OKBjT"9?irA!;huM[3h?2;76cjo9J_kt7SDJb~>
+ZN%\o!La#2gD\Vhb/M-,[BQ[-TUV:2NJW@>I<g!WE,BE+B`)K]BPD7!Df^&HI"-g*N0.NiH).FB
+[(3ogaj/LhgO\,1gCr2fcH=2E^V%(aZEL@0Vkp2`TqD4R';(qkUSOcdX0/\5[^s/g`Q6<Of)48)
+dTf,YJ_Pb1J_Q^LJ,~>
+ZN%\j!L*T,ef2uZ`kf9qZ)jjsS<oG"MM?_2H?XFLD/3j!AnCsP)eEVoBPVI(Ecu_VJVAr??QOEa
+V5gc-]"c5,dXfu#f%/Ceda$"T_S3Xk['?d7W2?>`TUq^ES"'DG'UtV_SY)UMV5L>pYHkUI]YVP-
+bgH@>"3k"7_1C0geq)DBepm~>
+ZN%\r!Ls/4h@nf)i8N\UjQ5LckNM0plKdd&m-Xf?rpT^QrU9dSs6UEblg*j#Y2/:'k2k[aio8qT
+hgsX8hU^Q`hZ_rsiSrkWroF+@roX1Bqrmt@roX7Bs5a4?s5F.>i8EMkh?'f1LOn<5hLXOPhLG~>
+ZN%\o!La#3gDnkpc,[]6[]um1Tq%I4NJW=<H['UND/*]p@prgF@/jXR@qB:eD/XK>H@LR&N,4QE
+TV\Zm[_'>pbgG-qgO\,3gDJPkcH4&B]t1YXYH4_#UnOEOS=5k5R$X0=QkPmWS=ZCKUo:;rYdCpQ
+^Ve.:d+/-M!idc)J_Pb1J_QXJJ,~>
+ZN%\j!L*T-ef</aaMPX"ZE:%!SX>V$MM?\1G]e"CC1q0g@:*@?>o[0X@:Nh\C2Ip3G^P$pM.qm7
+S=uj^Z*q9\a3<(beq)E)eh>Isai2*0\[JcGX/MkhTUhU@R$X,'P`q;qPa.Q$R%'V<TqnTdXK](@
+]>)8(bL$7>!iIN"J_#D'J_$:@J,~>
+ZN%\r!Ls/4hA5#,iSrnXjQ5Oekih9rlg*p)mI'E2n,DhPnc/+Yn,MhUm1AXMlg!a!ki_*ijQ,@\
+iS`UEhLXP8hZ)I@i8NYSj5]4]jlPXeroa7DqW[tBroa=Ds5j:A$fg7+iS`YOhUlO(_h$ZqhLXOO
+hLG~>
+ZN%\o!La#3gDnbib/D$)Z`U1$SX>S#M1gA)G&qP:B4PFX?!CM3=WCUL>[CiKB52:'Fa8IhLl@L`
+S=uj^Z+%E`aNi@fgO\,4gGRU2cH4&A]XY>QXfA7nTUqX?Q^*btP*(lgOcbfjPa7]*S=ZINW2m,-
+[^s2ia3;o]eRpqYJ_Pb1J_QUIJ,~>
+ZN%\j!L*T-ef<&[`k]0nYGn=iR?WbjL4ObtF)Yr/AR]"P>?P)-=8uA@>$PBBA8#arEd)n]Ko(hR
+R%:"NXg>RP`6-JYeq)E*ehtn#ai2*/\?rKAWMZD^S=5e0PEM#gNfB$WNK&s[OckrqR%'\@Uo18r
+ZF7?Y_T0jIct,5LJ_#D'J_$7?J,~>
+ZN%\r!Ls/5hA>)-i8N\UjQ5OdkNM0qlKdg(mI'H3nF6GIqXXXUs7$'Ws6^Kdm-F!&l0.<nk2k[a
+io8qThgsX8hV$cch[JH%io9"YjQ5Lck3(q,kl'cClMToHkl0cFjp^A4jQ#:[iS`Y&0R_c.hLXO7
+hO*/M~>
+ZN%\o!La#4gHF6=c,[Z5[]ld-T:(q)MM6P+G&hG6ARSnL=]SO%;c6Om<E<4+?"%8WCiFNBItWW<
+P*hi:WNW\?^rFUGJ_Pb1g=mFqe'?(R^q@._YH+RsTUhO=Q'.5iNJi_nMZ8SNN/is^PEqT+St`'\
+Xg,:E]u%h6W\8_QJ_Pb1J_QRHJ,~>
+ZN%\j!L*T.eihO.aMPU!Z)jjsS<f:rLOsr!F)Pi,@p`JD=&`*r;,C+e;cHe">@(cNBl.m7I"@!0
+O-Q0,V5pi/]>;P3J_#D'g=@%fcH4&@]=5,MX/D_cS=,_.P)kQ\MMV.b(l4$,N/j!_Q'e&4Tr"`j
+Z*h-V_T/N+Gh%ArJ_#D'R+?c~>
+ZN'jZ!.4PB!1_<j!Ls/5hA>)-iSrnYjQ5OekiqBtlg4$+mdKW6naZVLqXa^Ws7$inn*f]4mHj0(
+lKRNqk2tddj5T%UhgsX8hV-idh[SN&io9"ZjQ5OdkND'mrosCHqs44GrosIHs6'FE$0C7/j5].U
+Fu6j_hLXO7hNm#K~>
+ZN'jW!."D@!1qHi!La#4gHO38b/D$(ZE:$uS<f:qKn+MnEc#K#?s?`5;G^.`9M8&R:/=bf=Bf-B
+B5DO0H@LX+O-Q0,V5pl1]u.q:fR_e.gYCO$f[S3g`5'!nZEC4(U7Rg?P`_#cMMR"@KS9>W(kdTs
+LP^qKOHPotSY2dWXK]+C]t\88Yh=T^J_Pb1QeR#~>
+ZN'jR!.4PB!1_<b!L*T.eiqL)`k]0mY,S1eR$*GaJphlbDe`ln?!13,:ej_X8kDWJ9MSD_<`r^:
+ASH"%G^Y1!N09NtTr5$!\\H)*dt-)$f%egoe'H1U^q7%\Y,\@mSsl"0Oc><VLP:A4JV!fN(kI9j
+KSG;?N/s-fR@KqGW3!83\[uH+XOMgPJ_#D'Qe$Z~>
+ZN'jZ"P1lDXT8@Ge(t*:`r+ZoS,gdis5+sWiSrnYjlYahkiqBum-X3.n*fc9nac8Dq"ad_q"F@P
+rq$0\(%Le_n*]T1m-Es$l0.<mjlGI]iS`XFhLXP;h@8B#iSrkWjQ,Fbk3(pkrosIJr9O:IrTjIJ
+s69RIs5saOjlPR`_DZJki89+BJ_kt7Qem5~>
+ZN'jW"OkE3WW<%=!8#`T!>*!CgB!`Cc.bJ:eBZ.P]XG&EUn3s:NJE+6GB.P6@p`G@;c@b&VmW^q
+BLYNa9M\Pd>$bZNCiOWFJVK)GQ^snNYI2!Ya3E+bgO\,8gGdj9ccX5B]XG,JWMH2XR$EhpMhm+@
+Jq/?"I=-EjI=?ZsK8#)<NKB?jR\$:PX0At&/n;lFdb99,J_Pb1R+m,~>
+ZN'jR"O>$,V#^M7e(+O2^&6F^PQ8tZ5Ln*%_nEOaXJVY[Q&gfUIsQ3TC1^m[=B&-qEKm?-Y*Wch
+7S$-G:fCJ$?t<thF*N.dLlR[eT;ATn[_0Jud"0c!f%nn9e^2LZ_7R1^Y,S7kS=,Y*Nf/^IK7SN#
+I!^0bH$Xd`I=?]uKSPGDOHZ$#T;/<cYaR.P^rXdNJ_#D'J_$4>J,~>
+ZN'aW!PJK[h>mVir8%IE!6j:;hr*JQj5]4^k3(smlK[^%mI'H3nF?)?oD\Ud!W;ZjoGI2jo'u5=
+n*]T0m-Es$ki_*ijQ,@\iS`UEhLXP=h@\Z'iSieVjQ,Fbk3(sll07Kurp0RMqsF@Krp0ULs60sU
+kND!hjFf4rio/hQJ_kt7J_laMJ,~>
+ZN'aT!PSQ\gAq;gr7_7@!6s7:f[A!`^U^\QVkKTGOG\aAH#mk;A7&M?;-*PiruK9_6UjX@:fUY)
+@V9P!G^Y4$Ng-!*VQ@)5^;S1@J_Pb1h:jm>d*'GF]XG,JWMH/UQ]mJgLkUG1IX??bGBS.PG'A1V
+H@13nKSPJGP*MH,U8Fr&-C)<_aNi:dgO\+1gR-`G~>
+ZN'aO!PJK[ec>car71n5!6s(5e'5qL]="iAURda7N/*"4G&_>2@U3)7:K7/druK6\6:==9:/b5!
+?tF(lFaARmMij?rU8Y6%]"l>/J_#D'h:=O4bJqB2\$E09V4a?FPE:`ZKn=f&H['aWFE;MDF*)PJ
+G^4[cJV8f:Nfo]sSt`)l-'GjS`6-GXeq)D'esP$=~>
+ZN'aW!PJL2hC\em(jk+u(]Y+oXPVg04U<$Sc/.0A0aK4ef&!r@&.D==hV+>O#RF&JhA?5(SGh:F
+S,gdi52Y;WioB+]k3(pkl0@U$mI'E2nF?)?oCW(]qtg-br;Zfqp%@tLoCDJBnF,i6mHj0(l07Ep
+k2k[aio/hQJ_kt7h;/k'i8ESRj5f:_k2tjjl07Kulg*p(rU'LMrU'XOs6K^Ms60sUkNC&RC#.h/
+io/hQJ_kt7J_ldNJ,~>
+ZN'aT!PSR3gF`Jh(j4Sj)up[qW8$($4:3-VbhLa60FB4ce(_62&.D@=gXhZD$4'5HgDBo%Rf1tA
+RK1Ue5h=<(_nEOaX/2DTP)Y6JHZj@DARJ_B;+spgjgLeAT@!W<i'Tas7nZWX>$kfSDfg;UKo;+]
+StrBj[_0JucId^&J_T):)VEK_aMPU!ZEC1&T:;.0Nf&RDIscNcF`VSBrGNTnEH?5FH$b!kKnt\L
+PaJ#'/l/OV]>2D.ce*g'J_Pb1RG35~>
+ZN'aO!PJL2eh-re(j"8](]Y+gUt4+e3=$UOak"n%/I3e]cIT6u$j]J-f$]X3#RF&BeeeAuPl9/6
+PQ8tZ5gdco^U^\QVkKTFO,AU>G]R_8@pN28:J+LajgLb?T$[N;ha0Ln77g6Q=C#BKD/slLJr#GO
+R\6OZZ+%Hcb0tpmJ_&`0):QjO_nNXeY,\=kS<oD!Mhcq8I<g$YEc>soD&I51EcZDKH[^R#M2[R^
+R>`^lVm3\B_8a[IJ_#D'J_$7?J,~>
+ZN'aW!PJL2hCS^^SBfC[A(IIVB@a"VF2a)$LYeCnLrOp)Mq2N5[CK%Jg6bWk`l:#!hVJ7Gr8%IE
+!6j::hr*JQj5f=akNM0qlKdg(mdKZ8nac;Do_nL_pE'22s7uB]p%7kHo'u5<md9E.lg!`ukN:me
+j5T%Ui.9a9hVI$$hr*JQj5]4^k2tjjl07Kulg4!;mJZJNn,;\SmJlPQli65Zl0+9_YiXs,j5T%U
+i89+BJ_kt7RGNG~>
+ZN'aT!PSR3gFWCVT$,F[A^@(NA'q/IEPdYuL"hnfL;84"Mq)H5['i\AeWrpa^qMongY2_Br7_7@
+!6s7`eBZ.P]XG#CURda6MhQY+F)>Pu>ZO]q84?TA2`3BG0STQ,ME3pf7nZZY>@D,[Ed)qaM3!pk
+Tr>-$]"uG3eUcJ+gYgg+g=4Ei`4idhYH"CjR[0+rM1pJ.H$47KDJa0(C&VcaBkhI$E-$/HH[g['
+MiX'0++0ufZ*q<^a3<"`gO\+1gR6fH~>
+ZN'aO!PJL2eh$kNSArPKA'USEA'U`:CV>NeK@Z8^K=uUlLXKg-Z*d>>dZdLZ]tHEdf%'i7r71n5
+!6s([d)s8>\$<!1T:(n&LOsnsE,&rk>#\9i7RU9;2Dd0C089H+ME*gb77g6Q=C,KODfg;UL5_:^
+SYW9i[_0Jud"0c!f&5+!e^2IX^q-qXX/;S\Q]dAdL4Xi"GB7bAChdWsBDuK]B4u!pD/aN<G^P$p
+LQ%=$*dONZXg5FL_T0rQeq)D'esY*>~>
+ZN'aW!PJL2h>mVHrn\O+f&!e7?Hmh#^#%>>Z.`u+f&"hbB?k-ZZ2NA`CM25ThSoQ@h>k7eh>s,H
+c/'Jui8EVSj5f=akNM0qlg4$,mdKZ8o(2MGp%J+Rp\jk.rVufhp@\+NoCDG@n*f]3m-Es$ki_*j
+jQ,@\iS`UEhLXP@hA5#,iSrkWjQ5OdkNM0plKdd&m-X3.meuVPnGVhUmf2Ydm-F!&lJ673kN:me
+j5].Xi89+BJ_kt7RGNG~>
+ZN'aT!PSR3gE$?dgY:>ke(_/.?d*du]%bW0Yh*T#e(`)RB?t9^Y5QrZBk>cJgV*[6gAntcgB!`C
+cJ'Gpe'5qK]!ST;Tpq:,Lk:"tE,&oi=]8'e6U!Oh1+t3X.N[IHZo'j,6:X^I=']<LDKL2TLQ.Lc
+T;AWp\A-#+dt-8)gYgg+f?qg^^q7%ZWhlAXQBI2_KR\>nFE)/5BP(db@fBdT@Us%_Bl%^/G'SOg
+L5UgTOe/>HXg>ON_oU-TJ_Pb1J_QXJJ,~>
+ZN'aO!PJL2ec>c@rmhspcIT)t?HICl[FWX"XjUilcIU*DA&`"JXo6ZTB4K6<f"D('ec<D]ecD!8
+cIO)fcH*l7[]la+SX5IsKn"AhD.mB`=&DX]69R=c0eP!U.3@@GZnsa)5Xe:A<EimDCiXcKKSkkW
+S=uma[(F/oc@OPtf&5+!d`fbJ]=+uGVkKWIP)bBQJUMccEc,Z+An,:Y@/aLP?t*VWB5)4%F*Dt\
+K85+INgcT9WNW\>^Vn:CJ_#D'J_$:@J,~>
+ZN'aW!PJL2h>mVirn[sG.4Ijh?HmCpc2HK"dUW1T$!tlmF"&5D^!^Ef!!Bpk!58<e!Ls/7hAtM3
+iSrnYjQ>UfkiqBum-X60nF?)?oCV_Lp@n@WrV7N5s8;Wcp@\(MoCDG@n*]T0lg!a!ki_*ijQ#7Y
+i89+BJ_o>As5+RLiSrnYjQ5Oekiq?slg*p)mI'E2n,DhRnc&%Wn,MegmHj3*lK[WtkN:pgjQ#7Z
+iS`UEhLXO7hO<;O~>
+ZN'aT!PSR3gAq;crn@aB/1='i?d*@mb5L&qcXH_O$!k]fE@;r@]$Fg^!!Bge!5ABc!La#6gE5+s
+bf.?,ZE0mpR?EM`J9c3QB45"E:J+#>3]/TB.45$>*m4M`0JkdR6V1'R>@;)\F*W7hMisI!UoLZ.
+]u/">J_Pb1iS,@+eBZ.P]sk;KVkT]JP)Y9NIsQ9YDJNlr@UNMIrEC7H?!h#MAnc+$FEr:cKo;%W
+R@g:TYdM*Y`llc`J_Pb1J_Q[KJ,~>
+ZN'aO!PJL2ec>cYrmhC?.4IR`?HHtd`Vn?ga^4lF$!P<YD^cf<[E2bP!!BX[!58<]!L*T0ej7g1
+a2,BpY,J%aQB-lTI<T[HARAS=:.[f:3A`B>-m^,`,Kg%d/i,IM6:XaK=C#HPE-?V\LlR^gTr4uu
+\\H/-J_#D'iRU0BccX2?\[/H;URmj:Nf&OAI!B^NChRBi?sR#@=]ed/>$G9=@:NqbD/sfGIY*?6
+Od;N2VQ@&2]>;M2eUc;&eq)DAepm~>
+ZN'aW!PJL2hCS`@hVQNXXkqn7?Hm[p^#%>-T\=0sg>:Q&akFSMhRuZsdVEXPhVQhkhVJ7Gr8%IE
+!6s@@hr*JQj5f=akNM0qlKdg(mdKZ8o(2MHp%J.Tq>(!c*rc3:q"OLUp%7kHnaQ#8mHs9+lKRNq
+k2k[aio/hQJ_kt7i8,:-i8N\Tj5f=akND'nlKdd&mHs?1n*oiFnbhtWnc/+Yn,MefmHj3*lKRQs
+kN:mejQ#7Yi89+BJ_kt7RbiP~>
+ZN'aT!PSR3gFWE>gY:$SY1q\2?d*^s]\ChsSC_Ife_A]m`n.rAgU^*jcY7%BgY:2_gY2_Br7_7@
+!7'=bf?qaZ]sk8HUn3s:MhQY*Ebo>p=]8$b69I.[.jlPa*Z[03s)TYD2*4&m9N"u!A86+.I=mE=
+QCXeMYdV3]aj5OmJ_T/<4kJ*)`PB'lYGn=hR$3PeKR\;jEG]E$@:*5B=&r=$<)lq!=Bf'>@qTRq
+F*N+aL5V1[S"Z^\Z+%E`aNiCggO\+1gRHrJ~>
+ZN'aO!PJL2eh$m8f%/+HXk)&'?HI7h\^o&fR*oV[dalj[_:#m-f!S+[b%GA8f%/-Kf%'i7r71n5
+!7'.]d`f_H\[/E9Tph4+LOsnrDeW]e=&DUZ5WUbU.OH>]*?6s0s)KP@1c[`f8l/Pn@VBY$H@Ud0
+P*qr=XKf:L`QNh`J_&f24jqQo_7R.[X/2JXQ&poYJUD]_DJEfo?X6f:<E)mq;H$Ln<`iR4@:a+h
+EHQSVK8>MMQ^skLXg>RP`6-MZeq)D'esk6@~>
+ZN'aW!PJL2hCS`@hVQNX[GGs)?Ho9<F2a)$I,'rYLrtfFLY?ZI]sUIJg6>3cb0Em>hVJ7?r8%IE
+!6s@chr*JQj5f=akNM0qlg4$,mdKZ8o(2MHp@n@Wq>0sbr;Q`pq>'g[p@\(Lo()>?n*]T0lg!`u
+kN:mej5T%UhgsX8hVd6,hr*JQj5f=ak3(smlK[^%mHs?1n*ol;rUTmXrpp*Zs6p`kmdBK/m-Es$
+kih3ljlGI]io/hQJ_kt7J_lmQJ,~>
+ZN'aT!PSR3gFWE>gY9mOZIa'r>KEI,EPdYuHeFQTLrG<>LXg0?]!=tCeWNR]`Q(h4gY2_:r7_7@
+!7'=cf$MOV]XG&EURda5MM-D%E,&oh=&DUZ5<1MO-mKcP04N]9`?HW[0fM6_8P`>k@VB\&H\.'7
+Q(+MHYI2$[aNiLjgO\,=gE"ehaMPU!Z)a^oR[&qkKn"DkEG]>u?sHi7;c-=dr_=G/:f::p>@(`M
+C2S*;I=d66P*hi9WNW\?^rFUIJ_Pb1J_Q[KJ,~>
+ZN'aO!PJL2eh$m8f%.h@Xk%On>/d"$DnUriH.7dBK>E@,K@4O5[B2o2dYpYJ_8])%f%'i/r71n5
+!7'.^dEBMD\?`35T:(n%LOjbnD.mB_<DQ1R4ub;K-R'QM/n3T8`??NX0K)$[85<)e?tO7rG^kF+
+P*_c9X0K.I`6-V]eq)E3efE,[`4iafXf%k_Q]d;_JphlaDJE`k?!:<.;,9q]r_+;+:/Fkh=Bo3C
+BP_[2H@LU*O-H**V5pi/]>;P5J_#D'J_$=AJ,~>
+ZN'aW!PJL2h>mVirn])>#S;>C+EQD43<p*7C#7R*.0q5Qdb_B,#RjbEhV+&?#REc:hVL6mSGh:F
+S,ggj*8f]5ioB+]k3(smlKdg(mdKZ8o()DEp%J.Tq>C3k+9)69qYBp\p@\+NoCDG@n*]T0lg!`u
+kN:mej5T%UhgsX8hVm<1hr*JQioB+]k3(sml0@U$mHs?1n*ol;o()DDqt0mZs763['_(SZmd9B,
+lg!`ukN:pgjQ#7Yi89+BJ_kt7S)/Y~>
+ZN'aT!PSR3gAq;grnAl=#S;8@,'2G+1^=U2BA:ss.L7;QdG(m"$4^.GgXV<6#RE`:gY4[jRf1tA
+RK1Xf*S/QY_S!=]WM>uLO,8I9F`1u'>ZFQk69I.[.O:>YrugER*$-=R0/YjY85</h@:sG!H@^j3
+Pa\;DY-bgWaNiIigO\,>gHXB>bf7H0['$C'SX5LtL4O\pEG]>u?X$Q0:JFGQ84c]X:e=>V;,pb(
+@:a1lFEr@hM3!miTV\]o\%T]$ce3m(J_Pb1SD/P~>
+ZN'aO!PJL2ec>carmiN6#S;&;+E,hu0`qt*ACf1f.0q5Lak!Rd#RjV9f$]L+#REc1f%)PUPl9/6
+PQ9"[*RW'L^::GLV4X-<N.uh-Ec#Gs>#S0e5s$qW.3t5XrugER*$$4O/i5US7SH`_?Y+"nG^b=(
+OdDW6Wj&qE_o^DZeq)E4ej%[/a2,BrYc=OlR?NYeK78&dDJE`k?!('':.n/K7Rp9P:.RuO:K(=u
+?=RYcEd)n^L5_7]S=uj_ZamiibLD*oJ_#D'SCW2~>
+ZN'(D#0_WI'*L8MiSFU*!6s@chr*JQj5f=akNM0qlg4$,n*ol<oCV_Kp@n@Xr;Q]qs8N#pqYL$_
+p\+:PoCDG@n*]T0lg!`ukN:mej5T%UhgsX8hVm</hr*JQj5f=ak3(smlKdd&mI'H3nF?)?oCMtR
+"SMZls8;lg)"[=hnaZ,;mdBK/lg!a!ki_*ijQ#7Yi89+BJ_kt7S)/Y~>
+ZN'(A#0D?D&d1,HiS+C%!7'=ce^)=R]XG#CU77F/Lk9trDJ3H_<DQ.P4>ec?,*DZss8Vu*2]<ed
+/MoLR7nlrd@:sFuH@Ud1PFA/BXgG[Ua3N=ggO\,>gHX99b/D$'Z)a^oRZrhhK78&dD.mEc>#eEo
+8Ol086+?moe3c\s9M\Sg>[_5[E-6MXL5V4]SYN0f[Ca8qcIRR$J_Pb1SD/P~>
+ZN'(<#/u!=&d1)BiRS$o!7'.^d*'AA\$<!1SsPV!Kn">fCh@$W;b]_H3]&H:+d)Qrs8Vu*2]<bb
+/2K:M78$N\?=[hkG^Y7&OI)K4WN`hD_TC8Xeq)E4ej%R*`k]0lXf%k_Q][2\J9uEXCM%![=Ar!g
+84>m35IUUle3ZPn8kr5`>$b]PD/slLK8>POR@g=VZ*q<^ajG[jJ_#D'SCW2~>
+ZN'1G#g@iK'*\F:+Oo?+!Ls/7hE]uViSrnYjlYail0@U$mI'H4nac;Dp%J.Tq>'mar;HWos8Mol
+q=s^Xp%7kHnaQ#8mHj0(l0.<mjlGI]iS`UEhLXPBhAP5/iSrnYjlYail07L!m-X60n*ol<o(2MG
+rq-9drr4#:p%@tLoCMPCnaQ#8mHj3*lKRNqk2k[bj5T%UhgsX8hLXORhLG~>
+ZN'1D#g%QF&dA=9+49$$!La#6gHsH9aMPTtYGe1bQ&^ZOHZX.<@9Z`,83o<o/ghe\'Fc'\ec5)%
++!rNp3C$&.;d*RAD0'uQL5hCcTVnp!]"uG4f7D\-gZ.$0eBZ.P]XG&EUn3s:MhQY,FDkl(?WpH+
+9LqQ;5!3lbruKQO5XIq4:K(>"@:sFtG^Y4$O-H*+VQ@)6^W"CEJ_Pb1J_Q^LJ,~>
+ZN'1?#fV3?&d878+3`Zo!L*T0ej@a+`4`XbX/)>RP)G$CG]IV3?W^6#7R&mh/LDSY'Fc'\eGnu$
++!iEm3'K`';-7+7C2nHGK8PbWS>3'f[_0K!dXfu#f&P=&d)s8>\$<$3TUM+*Lk:&"Ec#Gu?!($#
+8k)044Z[Q]ruKNM5!_S.9i4no?Y!niFaARmN00HsU8Y6&]>;M3J_#D'J_$@BJ,~>
+ZN':J"O2KH&dJ:7!>NH/h>s,Hc/(_Ci8N\UjQ5OekiqBum-X60nF?)@o_%qOq"X[]qu$ElrVliq
+qYBp\p@\(Lo'u5<md9B,lKRNqk2k[aio/hQJ_kt7inbU2i8N\Tj5f=akNM0qlg4$+mdKZ8o()DE
+o_&4Ws8F,<s8;Tap%@tKoCDG@n*f]3m-Es$l0.<mjlGI]iS`UEhLXO7hONGQ~>
+ZN':G"Nl3C&dJ:7!>NB-gB!`CcJ(\9cH*l8[BHO'S!B"iJU;KVB45"E:.R]52(g:#)\`bf"Voel
+^)n[Q1H@]i9iG5'B5M^8J;0&IR\6R\[(=)ocId^&J_T8?6.s`3`k]0mXf%k^Q&gcSI<T[IAmnnD
+:eXAG5<ChikOm$ud5F$K5t+@@;cm@9Bl8$=J;0#GR%C+RYdV6_aj8[lgO\+1gR[)L~>
+ZN':B"NGj<&I&+5!>N3(ecD!8cIP>/b/D!&Z)a[lQ]d8\IX#mLARAP<9L_9-1bC't)AEYe"Voel
+^)nXO1,qHc92SesA86+.I=mE=Q^jhMYdV3]ajYglJ_&o56.F3$_7R.[WM?#NP)P-GH?=%=@pW89
+:.dr@4ukPckOm$ud5<pH5=7t9;-$q1B5DU5I=mB:PaeAEXKoCO`QQe_eq)D'et(BB~>
+ZN'=K"j:mA',1oT!!*Y2hVJ:'!6s@Bhr*JQj5f=akNM0qlg4$,n*ol<oCV_Kp@n@XqYU3grr!l;
+rqZBbp\+:PoCDG@n*]T0lg!`ukN:mej5T%UhgsX8hW!BVhr*JQj5f=ak3(smlKdg(mdKZ7nac;D
+o_%qOp\Y!fr;Z`ip\+:Qo^hYEnaQ#8mHj0)lKRNqk2k[aio/hQJ_kt7J_lpRJ,~>
+ZN'=H"itU;&eb`R!!*Y0hV/("!7'=ce^)=R]XG#CU7@L0Lk9trDJ3H_<DQ1Q4>niA,97R5%1<Sl
+s7mof/i5UT7nlrd@:sFuH@Ud1PFA2CY-bgWaNiIigO\,?gHjH=bJ_-)Z)a^nR$*D_J9l<TBOY7K
+;GB\K4ukMVWrIjZs3NGV2`s>o8l&Gk?tO4qG^b='OHuE2WNW_B_T:$TJ_Pb1J_QaMJ,~>
+ZN'=C"iP74&eb`R!!*V+hUV^l!7'.^d*'AA\$<!1SsY\"Kn">fCh@$W;b]bI3]&H;+rh@1%13Mj
+s7mld/MfCO78$N\?=[hkG^Y7&OI)N5Wj&qE_o^DZeq)E5ej7a.`k]0mXf%k_Q&gcSI<]dKAmehC
+:eO8D4ZG8QWW.aXs3NDT2EF#h8PW2d?"7SeFaJ[pN09R"V5pl1]u/"AJ_#D'J_$CCJ,~>
+ZN'1G"fNOQ!"FY<h>s,Hc/'N!i8N\UjQ5OekiqBum-X60n+#r=oCV_Lp\=R\qYU6hs8O&6q"OLT
+o^qbGnaQ#8mHj0(l0.<mjlGI]iS`UEhLXPChEToUiSrnYjlYail0@R"m-X60nF?)@o^qhMp@nC^
+rV?BkrV60^p@\+NoCDG@n*f]3m-Es$ki_*ijQ#7Zi8B1CJ_kt7SDJb~>
+ZN'1D"f<@N!"FS:gB!`CcJ(\:ccO&:[]la+S<f4mK7%i\Bk(CK:e=#;2_cg/+<)+1&e\UPs#2D]
+2EX;t:K:V-B5Vg<JV]>NS"Zd`[Ca;scJ!j(J_T8?6.XE)_n<F^Whc5QOc+pCG]IV4?s6Q+8OG[%
+2)&J<dO)-sc71G%2`sAr9Mnks@qfk(H\%!5Pa\;DXgG[Ta3E1dgO\+1gR[)L~>
+ZN'1?"em%H!"FJ7ecD!8cIP>0bJh3*Z)jdoR$*D_J9c3QB44tC:.R]62D?U+*uYn.&JALOs#2AZ
+1cdom9iG2%AScC3IYE]BQ^sqPZ*q?`b12'oJ_&o56.*lp^UUSNVP'BANJE+5F`1u(?!($"7m]?u
+1bW;:d3Ysqc7(>"2EF&k8l&Gk@:sFtG^b@)OdDW6WN`hC_T:,Ueq)D'et(BB~>
+ZN'7I#2=8TM[p.tgti(%!6s@Ahr*JQj5f=akNM0qlg*s*mdKZ8o(2MHp@n@Wq>0seq]>\8rqQ9_
+p@\(Lo'u8=n*]T0lg!`ukN:mej5T%UhgsX8hW!BVhr*JQj5f=akNM0qlg4$,mdKZ8o(2MHp@e7U
+rr2cjrVuilq"XUWp%7nJo'u5<md9B,lKRNqk2tacj5T%UJ_kt7J_lpRJ,~>
+`r?&<mf2V-#2!uNM%9qqgtMju!7'=bf[.dY]sb/FUn*j7MM-G&EGK)k=Ahd]5WU_S.3ouT)&O6O
+s7e&q1H7Qd8l/Pn@qfk)I"I39Q(4SJYI;*\aNf@kJ_T5>6.O9%_S!=\WM5oKO,8L:G&V2,>uslr
+7R0$m0Jh_c80=r5bp=ek1,qEa8P`>j@:sFuH%1R-P*hl<XKo@N`QZh_gO\+1gR[)L~>
+`r?&<mf2V(#1IQFL(=VlgsuLj!7'.]e'#bG\[&<6TUD"'LOjeoDJ3Ka<_u@U4ukDN-mKfQ)&O6N
+s7e#o1,h?`8PW5g@:sFuH%1R-P*hi;X0K.J`6*Y^J_&l46.!cm]sk8IV4O';N.uk.F)>T">?+Hj
+6p<Uf/i)G`7j"i4bp4\h0fM3]7nloa?=[hkGC>+#O-Q6/W33M>_8joReq)D'et(BB~>
+ZN':J#JN'4g3<ZTgt^`eS,ggj*oGo7ioB+]k3(sml0@U$mI'H4nac;Do_%tQq"X[\rq[]8s8;Zd
+p@\+NoCDG@n*]T0lg*j#ki_*ijQ#7Yi89+BJ_oDC5i:MYioB+]k3(smlKdg(mdKZ8o()DEp%J.T
+r;Z]kqu-QnqYBp\p@e1OoCDG@n*]T0lg!d"ki_*ijQ#7Yi89+BJ_kt7S_ek~>
+c2RtHr;-6aq#'jhq"adarV$9XgBYAKCtEh31>1I;!La#6gHjK>bJ_-(Z)a[lR$*A]IsH*PAmeeA
+:.R]6:bjUO,pFHR5Oe]b/29%F5t=XJ=^P`UEHlqcMNF0qUoLZ-]Yhk<J_Pb1j4clLcH*i6['$=#
+S!8qhJU;KVBOP+F:J!o:2_ckVs-4K>WW10b,UtH)3^?/.;H[@<CiXcMKo;+]StrBk\%]f(dt-8)
+gO\+MgOK~>
+c2RtHr;-6aq#'jhq"adarV$9Xed&Z@C!q&(1">"0!L*T0ej7d/`k]0lXf%k^P`CQOI!0ID@pN27
+9L_<0:baLL,U"6O5Oe]b.kihA5=J4B=']<LDKU;WLQ%FbTVefr\A-#+J_#D'j46NCahtd"Yc=Ih
+Q][2[IX#mLAm\\>:.R]62D?YSs-+E=WW10a,Uk?&3Bfi':fgq4BlA-AJqoANR\?X]Zb!rlc@OPt
+eq)DCepm~>
+ZN'=K#D"J2hVLO6dG*LYS,ggj5i:MYioB([jlYail0@U$mI'H4naZ2Ao_&(Zqtg-aqY^?mrqZ<^
+p@\(Lo()>?n*]T0lg!a!kND!hjQ#7Yi89+BJ_oGD6/UVYio9"ZjlYail0@U$mI'H4nac;Dp%J+R
+q>UBjqu$EmrqcKeq"OLTo^hYDnF,f5mHj0(l0.<mjlGI]iS`UEhLXO7hOWMR~>
+dJjOPrVH<_o^hYDnGM_\nF?)@p%S:[rqcZ^gBW3ZY1q\r(=([h!La#6gHjQAbf7E.Z`L$sR?NVc
+JU2EUBOY4I;+jAEYhbab=&it,o`+PY0fD*X77p?U>@D/]F*W7hMisI!UoUc0^;S1CJ_Pb1j4clL
+c,[W2Z`U*tRZi_cJ9c3QB44tC:.RZ42(r,2h]EOFVuOpZ+=8Wp3'K`&:fgq5C2eBFKSknYSYW9i
+[_9T$d=L&'gO\+MgOK~>
+dJjOPrVH<_o^hYDnGM_\nF?)@p%S:[rqcZ^ed$URWn,`b(!>:^!L*T0ej7j2a2,BqYGe1cQB6uW
+IX#mLAmeeA:J!r=YMGXa=&`k*o`+PX0JkdR6V1$O=^P`UEHch_LlRaiTr5$!]"l>2J_#D'j46NB
+aMPQtYGn7dQ]R)WI<T[HA6rA99L_6,1bMo/h]EOEVuOmX+!iEl2a'N":/tM-BPhj;JVT5KR@pFY
+ZFR`ib^n>req)DCepm~>
+ZN'CM"3*N6fDaV-2Sdu%JcC<$JcC<$JcC<$JcEjl!.TM~>
+e,KgSqY0[RnF#]0lKRO2kPs`Pl0@X&n+$&Dq>L6kn(Rr^4^lk>gAs4Gf\=[N)>EXaiS)`'`4`R]
+VkBH@MhHM%E+rfe<`-=$ruU974?u>-:K:V-BPqs?Jr,SUT;J`t]>D\;f\bl[q18Qss5a2Hrq>gD
+i7QH!_Rd(SUn*d2L4=DdBOP%A91(g&hZ$[p&e:c<arDWU0fVEg:0(Y3Cik#VMNXC$W3<\E`m*&h
+jQlDgs+13$s.95jIt.~>
+e,KgSqY0[RnF#]0lKRO2kPs`Pl0@X&n+$&Dq>L6kn(%TU4C6A5ec@V<f[e=I)>EXaiS)`'`4`R]
+VkBH@MhHM%E+rfe<`-=$ruU974?u>-:K:V-BPqs?Jr,SUT;J`t]>D\;f\bl[q18Qss5a2Hrq>gD
+i7QH!_Rd(SUn*d2L4=DdBOP%A91(g&hZ$[p&e:c<arDWU0fVEg:0(Y3Cik#VMNXC$W3<\E`m*&h
+jQlDgs+13$s.95jIt.~>
+ZN'FN!fe_,rS@S1WhS>hhr*JQj5f=akNM0plKdg(mdKZ7nac;Co_84[rqulpq>U*fp&FY"oCDGA
+nF,f4m-F!&l0.<mjlGI]iS`UEhLXPChEg&WiSrnXjQ>UfkiqBum-X60nF?)@o_%qPqu?Wlr;HWo
+s8Molq=s^Xp%7nJo'u5<md9B,lKRNqk2k[aio/hQJ_kt7J_m!T!,mA~>
+ec--Xq=aFLmHa$"jl>@Zi8FUl%H-4)j5f@dlKn!1p%\Lbs7"bEN%(S$gB$!+UYA&acH*l8[]ld-
+SsY\!Kn"AhDJ3Kb=Aqsd8og`If\=]TGrdiD4?u;*9i>%t@:sFuH%(F(OHuE2W3<V@_8spTJ_Pb1
+jP*#Te'5nJ\[/B6T9te#Kn"AhCh@$V;G0GC3&7$(W>H6V#,;.>'c\DH0/bpZ8P`>j@VB\'I"R9:
+QCO_LYdV3^aj>UnJ_Pb1T%a6^J,~>
+ec--Xq=aFLmHa$"jl>@Zi8FUl%H-4)j5f@dlKn!1p%\Lbs7"S@M(#%qecF9rUXh]Wb/D$(Z)jgq
+RZrhgJphi_Ch@'Z<`)O]89(HFf\=]SGW@W@4$H#$92JVl?Y*tkG'edqN09R"UoUc/]Yhk@J_#D'
+jOQZJcH*i6[BHO&S<].lJphf]Bk(FL:e=#<2_gg%W>H3T"eu%='H82D/i5UT7nlob?tO7sH%:X.
+P*hl<XKo@N`QNh`J_#D'T%3mWJ,~>
+ZMsp]oD\pY<+GLfs8RT=rtX*O#RF>ks8UY:#RF>ks8UY:!!lKkp](8Krr4#9XYgMQ\c;^(TIgR<
+\c;]pN$/<0;XaYcmnsE(H2dgiO"WCT7@aCl?tX=uH\(YcqqeWW^?GUsp=[3rg%GCFr8>,b\E!>`
+!+,X(%$W4d*#*\us7^"/&9IjN"Rf4o&9IaKs+gXS!R4C;!!7)P:Ab(mDsmT(!"f#,!QG-3s8LmG
+KE8XGrS@PBJcC<$JcC<$JcDqRrnd4!!q2XSJ,~>
+fDc?ZqY'LKm-3ZniSWJHg=cJX'A(mhg"P3:hVdDTkN_I)o_ACbg[kFIlVqBbn,NE;nc'?U70j<%
+kPtS670j<%kPtS65m.HnlhLJ]rJ-7/ruq9@1^l^^s8Vbb/dt"RrVu2B+pJ<Qli7"N<<s+OkiLZ5
+r;ZmsX_.G1-YII56k]\=4&/F6+9_oi4@`"81(OL(883$dI=mB<Q_'l[ZFRck@Jp02Du]k3@0dEe
+rr32g<<s.Uqu-No#5s=6s8UA?qu?e8]MJG*#&Wc-s8Dg/qYpT6!;-<jg[]ps[c@>@!:>@;_>ck$
+p@%2&f[.aV]!AB4S<](gIWfXB?s$8u6=TlZ1E@2?#GV7@)'LC^2a9c,<Es'MF*`FpOdVl?YI;0a
+c.(P0lgo]-JcC<$ZN'pYnq$r/RSA;~>
+fDc?ZqY'LKm-3ZniSWJHg=cJX'A(mhg"P3:hVdDTkN_I)o_ACbf(8nDlVqBbn,NE;nc'?T63mip
+kPtS563mipkPtS563%9hn+Zk^L]7;sqlM^a6+R$qpRj)H6+R$qlAQkh#ZC-ks6ihk%rUaqhIlce
+!`6"1qZ&!WEbIlT";O!n90XO&"Wfcr8kLiL";j^FE-?Y^M3+'qU^FE<^rKs`!!dB@s7^"/&9IjN
+"Rf4o&9IaKs+gXS!R4C;!!7)P:Ab(mDsmT(!"f#,!QG-3s8LU?EriE"rRLu6JcERd6N6]IkMY">
+ahbQoX/)8NNJ;n*DeEH[;+a/ar9Q3['b1JCs2l3&-nmSE7SZrgA8?74Jr,VXTVo!%^;\@HguRem
+JcC<$JcE%UrmpX]!p>e?J,~>
+ZMsp]o`"uu0=1'G!e3GLo)BGO>'G$gPlLc1>'G$gPlLc-:31JOSGN6gqrYRmKDtm@fR7(G>`%PA
+bB7?<@Z07G]4,/hF&&8*s-Q].F'-N`s*S%-NKM9]gRt@@XHnk>s4k]0aMZR%s6.bUda.+Vs6\.Q
+bJ;Eor;Qotn)_GfrVn!k=+,@:ZiC'18onoCaoDC.;Km1[`T$ppk.OfJs8V/KrbDX908J>OrbDd=
+08K8uk.RPrqu6`hDZKG0rn[X.oYCT[R-+A(!:GF<JcC<$JcC<$YQ+UY!/1!\"%)IH:4N~>
+f`)N[p[dk>kiLg]gtLE3eC2jnr6Q#&daQaug"Y?@j6#Xonb)b5o`"uu0=1'G!e3GLo`#a,rHhgo
+F]Xh-rHhgoF]Xh-rHV1]F&/8$rri5]]N0^bs*!%D?>s2-jT!DHAp%U@i;U?!@WZZeRfEDT<HiIZ
+[HQOM/lbeFI^"Jn5s@CR&T`+j1aOUp0MGA)*ZcCD2GR+9-mU>k3F[,XJVT5IMMGpN[CjE"<%hNb
+A#oY0Z:]+T9$726QrS?O;SqAlqrYOlK`D)4Rf7(*<%j$\Rf7(.<%j%#qrYPc$N'i)o5+L"s8LaQ
+K(Qh[J<o6ogApVls1nY#p@%2&f[7gX]!JH5S<](gIWo^D?s-B"6b<<7Kn+SsGKg*GItL0E3'To.
+<F'-OF*iLrOdVl@YID6cc.1V1lh#c.JcC<$ZN'pY!.sjY"$u7A9n3~>
+f`)N[p[dk>kiLg]gtLE3eC2jnr6Q#&daQaug"Y?@j6#Xonb)b0o`"uu0=1'G!e3GLo)BGO>'G$g
+PlLc1>'G$gPlLc-:31JOSGN6gqrYRmKDtmofR7(G>`%PAbB7?<@Z07G]4,/hF&&8*s-Q].E_j4/
+i)VI1;GVeHKg\3j4<P2VG"sk?.NpH=;E,[<*um.6;*lZV/1*AeFaJ[pNKK*RCB_,Y_obn3?!q0D
+s8T>rF)O[ms8SHaGB6[$irAo<]iKdcs5]XJCBRTiLYS?tCC!lmL\CW-]qbr2rrVe1!;-<jec9d`
+\H7&<hYl"*l@JuNs$?AIkMY"?ahkWqX/)8NNJ;n+DeNN];G'<fs2'J?I<g%\s5AH[756bd7o!&i
+A8H=6Jr5\YTW#''^;eFJguRenJcC<$JcE%Urmh'joXP&akEJSh~>
+ZMsp^pAY6b@TDd]rr[a8J%t[V(\[8.[I`gR+ogsA[I`gR+ogg9V"=#5-2RWEn?m*^J,]I<Sm&Gb
+TO+l"N*scqZYQZ7HW\J\mYiIlpE?4$l@*7Cs&Yr_mdKuOr:0=Jl(,oqs/!-[p=dFDr6rj[oZYe^
+rRJgNptrd;r;QondB\X(rVn][TBtn0p](7VGOFTs@fQ0GT_%Gq>-.bn[;@@Bs8W&glK[AnF3FOQ
+lK[AnF3FUQ[;AeAqu6_^5lgQWrn[[/s7Yj_hI^uorS@PBJcC<$JcC<$JcDqRrn[[/s7Yj`blI4&
+:4N~>
+gA_faq=X7DkiC^Zg=Xs(d*BkYb/sV's2bhpbg"J]eCN=.hrEkamdem+p\t?c@TDd]rr[a8J%t[V
+(\[5-[e&sR+TLg?[e&sR+TLU7V"=&6-Mm`Fn?m*]J,]IsSm/PdTjY2'N+'isZYQ]7H<JG]mu/Un
+pEH:%lZZCpj#;1p\$<6FW0id.I4A'EHlOP-?9TT!<\#=`80KE\<\Yjo?V<"IH@Ua/P)jQa2?:8%
+`m$AecIUhCs8P9.mH7\bs7[_1oBUa-XoImuD('o6s8;HRlf+(JbP^r2lNuR6Em+LP[;Ab@r;Qlt
+PX5BBs8LaRK)bQ3"5IL2j8I^4m=G;Qru(S"kht.Ab/1csXJMJRNe`+/E+rcb;bTWnp&>tI1HIfm
+:fgt8D01/XMisO&W3EbG`m3,jjQuPjs+13$s0D\(gAup+p?`",!:-(JJ,~>
+gA_faq=X7DkiC^Zg=Xs(d*BkYb/sV's2bhpbg"J]eCN=.hrEkamde^&p\t?c@TDd]rr[a8J%t[V
+(\[8.[I`gR+ogsA[I`gR+ogg9V"=#5-2RWEn?m*^J,]IsSm&GbTO+l"N*scqZYQZ7HW\J\mYiIl
+pE?4$l??7nj"u"o[^!3GWgJs.I4J-FHlOM,?9TSu<\#=`8KfN]<\Ygn?V<"HH@Ua/P)jQa2?:8%
+`m$8ccdghDs8P6+mcI\^s7[\0oBL[+XT.dtD(0u7s8DNRlJe%LbPh#3l3ZI7F3FUQ[;AeAqu6_^
+5lgQWrmh*ks7Y^[g159]rRLu6JcEOc)>EU`i7ZN#_Rm.UV4Ep4LOXPfBjt7E9LZYfru5c13^H;5
+='fKUFF8_!P+&)CYd_BecILb3m.Gr0JcC<$ZN'pT!H\;7l3,3/kEJSh~>
+ZMsp^p\t<00rF79s*k*bJ%t^W(\[8.^&.Po*<5F<^&.Po*<5/>p](9$'`.h^oZa7.J,fQEI<"WR
+fOg-9Fa*T[ibaPCWjDU&s0WR@lN$DRs2H,[s"oFpRCr@nru8MHqZ$>F]_;Bn_:&8Ck5P(td/<d_
+anu,/]>jdK"Sglt]1Mu$*'Ae2Log@No*F(Ms03RDlN$DRs2Gb0s7FR5:4N0@"3#Phqu-O$`HeZa
+s7FR5S,iKe"2.=&!;-<jh>r<0p>,nb:3Yk!h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+g]%rbp[dh<k2P7Of@/*kbK7fD_ns7g^_=Q$_o0R9b082[e_&[8jQPsUp&+Xc!l$IelMpm6!l'6"
+pAYs&m1?r+pR30'm1?r+pR30'j_a\js0NX>s*F=^VG2R?s7q(^li5RMO7dX=pAa,iMt3jPqZ$T&
+)#rn%mJm4'(@C6"?Y3o%\@8`CUn1IEL5(!V1hgi1.5tO#6s<J9/R)I2/nJm11.-SGMij<jK6:l.
+]Yhk<'k2-+UA+]Z#h]1WYTWu3!:Bgd`>FO5oZa7-J,B6J`H\N]rVm2CGcgiBoZa8%!;uj!\k/[t
+o`+pF!J:@FgB5#]FlWGT!:>@;_#H^qnEJocd`]P@[&p3sQ]HrRH#d\1>ZFNhLT./GTUq^DgAgE1
+U/Ns56q^E\?tXD$I>*WDS"cme\A6/2f&#NUpOW?qs+13Us8LaRK)bQ!"I]>VRSA;~>
+g]%rbp[dh<k2P7Of@/*kbK7fD_ns7g^_=Q$_o0R9b082[e_&[8jQPsQp&+Xc!l$IelMpm6!l'6"
+pAYs&mL[)/pRE6'mL[)/pRE6'k&:"os0WR;s*F=^VG;X@s7q(_m/P^MNV.F<p]'5iM=R[Qqu?](
+'`[J!n,NF*'CFor?>*o$\@8`CUn1IFLPC*W1hgi1-oP@!6sEP;/R)I204f!21.$MFMij<jK6:r0
+]Yhk<'OYs(T_JKX#ho=YYoNf0!:Tsf`Y=:0oZa7.J,B6J`HeZarVm2CH*@,FoZa8'!;uj!]h5(#
+o`+pA!H\;7ecW<PF5HlH!:#.8_#H^qnEJocd`]P@[&p3sQ]HrRH#d\1>ZFNhLT./GTUq^DgAgE1
+U/Ns56q^E\?tXD$I>*WDS"cme\A6/2f&#NUpOW?qs+13Us8LRMF8tsb"I&oLPY-H~>
+ZMsp_q>UQkE(]6Vs8RQNs1a&up&>bF6@3o6MuWfq6@3o6MuW\Bs7a31HhdUlmVdUTs6t#VrVu/"
+Jbb"+bO2c&J,T$5qqA_eHiN[SV"<l$#ljWUJ!>h-\,H=8ie?Ops6kBNrr;Z,b5VDLk/>!ls8:*P
+kkEl+^A7d0k=,CM(\g+?MKhXas5F%Us8UXQs77)'oBLf*J,]HLmVdUQrr_J=L[+j<"6bGolM^_a
+mbRsBrrh%NUtu+Ds8LjUK`Cc&"2.HRk5F-Bmete2KnGoFqsaUdmXOp0!qs+<p&>-LT!%F2s+13$
+s+13$s69R_h>r<0p>,qB!:QFQJ,~>
+h#A,dp@7P6j58VCe'Q=\`l,^.]tCqe\c0)Q\[oDc^;.V)aNMlVe_/d;k/d#`qY^?qpM`adl2Ud5
+"96,c^\@aErr$\"H$;*'s8?e#H$;*'s823`pUjXUq#>C%D1DTcnSrsSs64?Oq1W2"n$PE2rUfg\
+ft:I7s77))oBUl,nD>-jBNmHB]="f?KHko-N-G=bGB@IM2J?]48LPcNA7RVI=_q([5_b2YQCFSG
+XdK1)`m)[E?u]mMUAs6Rq>^KD#6493VXs,'!eC:M!psiSr;Ql^Knnpkrr_G<L["d;!q"_BrVm#S
+:86JCo`+pF!J:@FgB5#]FlWGT#jqQATS8&hde`J5!UYC0rrVo&^\.U/gn(\7JcGTH62C'9inMr+
+`4`U^VkBE>MM$7tD.[-W;+a5?3&3'6,pTPlc7:P*4$cA3<Es$KEHltfNg6-1X0T=QaO&Prk3i%r
+s+13$s0D\(gAup+p=f_=!:-(JJ,~>
+h#A,dp@7P6j58VCe'Q=\`l,^.]tCqe\c0)Q\[oDc^;.V)aNMlVe_/d;k/?`\qY^?qpM`adl2Ud5
+"96,c^\.UADaJep22hM7DaJep22hM3mf3$p>'p&EEpdjqs8VS.IJs32D1VM:?H_cE5C`Y(pA<RW
+>'p;@(o6cgIfSus(gLfZ2L2pBY,I("IZ]S5!'PRKB.c&TAn4L^,"6'R2^hgF<?=D[Mia6oTr5#^
+!5QV!bnj]-BLAHmiW/lUs4.>Qo,+:pl@/e`rr3&fDh%]b"6bGolM^_bk_4fWrVlreh>mNS"PQVH
+h>m3Jrmh*ks7Y"G[7YMsrRM8>rRdcsK:LHgnG`OWJ+`gCp:%g0rr_&JY3^`>qYrkWn`o,ge',bD
+[]ZO$R$!8YHZX+:?W^/t6p<Rc/LVniXoHZs0/YgW7o!&h@qp".ItiuKS><3k]"uJ7fAG`Yq18Qs
+s+13Us8LRMF8tsb"I&oLPY-H~>
+ZMsp`qYpW>1mmJ+s*k.N^OO#krs`^+HZq3&s8QgsHZq3&rr3;HK6)\-s36%CMuEZ,mVdUTs715Z
+rVu/"JcEW&@!-3?KE(u4VL*B:k5YI::31Vc$ifsqfDkB.>Q+R&R&g5d#P!#Nrr;Z(`r>uHjM8:[
+rr;&k[(Nf5^%q[/k<]+I(\jiXs6b@gs5j=Ys8UXQs8RjLF*CprKDtlPmVdUQrrTHD^&7m3Z#@>R
+rrVWF!<3!&o3ue8g&V$Cs8LjUK`Cu,s/,bO"2.HRk5F-FmaHYrF`Ur3aoB86me?_aL[P3)3V`UX
+L[P35OIZ"D".W2\m-O`QmXO0p!lMYDq#:E5L[O1%!qs+<JcC<$JcC<$df9='!JLLNh>hKlh?9>K
+n!m.'~>
+h>]/*p@.D2in`;;d*0VN_S<ap\$iZMZE^X<Z*CU@[C<]Y^;.\-bKePfgYg!6mdp8RrrU>"R-4ML
+Ifo_cJ%taX&,uNC5'_9+MuW`k5'_9+MuN__b(Fbdjo<VUIuF:*Ep[^ns8VY1I/O$0D1_f*Ch%[)
+15#W,jJR?GJ`Zq3LJ`2>>mL#^MRV3UB-Y1%Z`?;aS<oCf!'bmYDD=1jD/2ou,Y2`i<\Z3d1`8`?
+OHuB/VQ@(p!6!%-c@rpqj+/i_jT,,Vs4%>Rs+aHoH!L].rr3&eD1DNa"9,K@]`%j4ri^1Or;Qic
+gAq6Q#P2MJo@F!<rV$9jgAup+r7h7IrS%Fc9m,LpgC3JtIV!YD@WTZk_h[^Trre,Gs5Q08rrn2H
+s7),>p&>,b;4m1@rrMM:i;Wkr]D)+#!lKf^ir9)R[_Ll&62L0<j4r20`kT!eWM5iFN.l_)E+rcc
+<DH(O4ZG5N/M"(*cnRC=5Xe=D=C5ZVF*`FpOI)Q9XgG^Xb0eo#kO8;!s+13$s0D\(gAup+r7_3g
+r7_@C!:-(JJ,~>
+h>]/*p@.D2in`;;d*0VN_S<ap\$iZMZE^X<Z*CU@[C<]Y^;.\-bKePfgYfj2mdp8RrrU>"R-4ML
+Ifo_cJ%t[V%;J%QG;5$Us(X]DG;5$Trs?f"F+`WTc$t5$rVpp+Dh%fenoK6Xs6=HPs2/SZF_W^b
+s8V/WHZOi%s8RjLF*Cpqo]:q=fu.GG^U^\Q5Ydi9P(*HsIX>re3H&bN:b3k_Ci<?./2oC(7>m7n
+S"QX[ZCh39b0eRh]^+R,/cXr5qu?]I"TSLW:31Vc#_W-V!q'uVr;Qi'DnZ)K!jQ[Wr;Qidh>mQT
+#4l;FpY#WEp&G$B!H\;=f)MEAecW<PF5HlH%-l;kA9Ds$F34I"L[Op:"GcFFjuN5:"c)OGnrTC7
+rr\cfT^;%F!UbHqrrU*MpA"Xh_h[[>rrVo'^Z5>[qXWt4gssZh^ULGHU7.:)Kmn5bBjt:H:.R]7
+3&<3>/$T'#0f;!W78$N\?Y4+qH@h!8Q_((V[(F5udFmI@n,%\9JcC<$ZN'pT!H\;=ec9L`ec_3;
+kEJSh~>
+ZMspar;QlrIR)`Os8RQM^OO#lruCk+%(Z90QlQ.t%(Z90QlQ/+Z"AKnp](9<It*CTru:BEJ,fQG
+Irk&Xg1ZKGm_+X7NEh_JfSag>[J0\##i;)$Mi]CfkL';/!RO%0rrV1ol2L]!qK9.<s6R/7rTNPH
+oXr'<s7Y?j_8E1gq>UKX4oYH^l-fS2'#k@[pB]XUs0WjHs5'8qMi]BPrr3&fDh%`c"6t5_mf!.f
+l?e$Kr;Qidh>mQT#LWlfHYWV.`V0?2h>r<0rS@XR2`IW5h?1GdGNSk\%.9Kh\aJn#>)E-/#i>=U
+":3lapUU)!"UNubqq0]srrR[akj/6LiW.p:!eYR^q#:DJ#i=S@!q:2ZJcC<$JcC<$df9='!JLLO
+h?%TqDuJMqS,i#J:4N~>
+hZ"Agp@.D1iS<&5cH=/D^:Un_ZEUL5X/c)s)60d?YHbIC\\5esaNW#]ftQM1mdp;PIR)`Os8RQM
+^OO#lruCe%%_DK/QluFt%_DK/QluG/Z>"`qp&G';It*CTru:?BJ,fQFIrarVg1ucLn%Oj<Na7nL
+fSss?[e9Y";r=0tNK>XaftHG%etNPj^:9@AOJ883N<MImJo!82FBr3nBJ;AaG&^_U6qT12P*VT1
+VQ6u1T`E3\e],&]n,139s7H`Rs8TMMs8UuJJW5a@PlC[am;7@Orr_M3IdR+6"6k,\mJQtcmFqX?
+rs-sZ@<lPeH,TFVrn@I*s8C[SUc(-,rn@Od9m,LpgC3J9?+B@l^KcZmK*^<-rr`V`s7Nturri\a
+s8(@&p&>)DB]n^]!T*t:rrRgnmeHe`K*^;mrrVY.JE-Yqr:K@;hU^#o_7?kPUn*g4Lk0knCh@$W
+;b]eL4utSY1UI,/3'9Gp8l/Pn@VKe)I>!NARA$O^[_9W'e(WgGnGRq<JcC<$ZN'pY!J:@MgB)3l
+D>i2lRK2ZB9n3~>
+hZ"Agp@.D1iS<&5cH=/D^:Un_ZEUL5X/c)s)60d?YHbIC\\5esaNW#]ft-5-mdp;PIR)`Os8RQM
+^OO#lruCk+%(Z90QlQ.t%(Z90QlQ/+Z"AKnp](9<It*CTru:BEJ,fQGIrk&Xg1ZKGm_+X7NEh_J
+fSag>[J0\#;r4$oMi]C^fY$8#etEDg^:9FDOeSA4NW_OoJo!2/F^AErBJ;AbG&UYT6V0"0P*VT1
+VQ6u1UB&E^e]"r[n,106s7ZfUs8TJHs8UrGIuBC;PlC[amVdURrr_P5J+!:8"6t5_mem(dmbRsC
+rs-sX@s_tkHc>^Yrmh*ks8CLNTJ\U"rmh1Z8orkfedUi2?FfLl^KQKkK*^?.rr`Vas7a)!rri\b
+s81I(p&>)CC$=m_!TF+;rrRgomeHe`K*^>nrrV\0J)gPpr:K@;hU^#o_7?kPUn*g4Lk0knCh@$W
+;b]eL4utSY1UI,/3'9Gp8l/Pn@VKe)I>!NARA$O^[_9W'e(WgGnGRq<JcC<$ZN'pT!H\;>ecKUe
+C]2fePQ9m28q6~>
+ZMspbrVluM3f<mtrr[a8J%t[V'`%>/[I`gN+oh-B[I`gN+ogg^J):1iq#:E`Dh%cd';/gLpSq],
+s2CMVm\"=.oT!%WjSnHErsamgpZ>Y+s3k,rp[",Urr3"oJGfEcOJ^e/d]V4#ahI95[__nAiQUKX
+b,a1pn*U)PrrM7Arr3ed?d8?1ImO,76%o.,@UfB;Mlla9>'ms^rrVV,J,TBK^LX/<rrTrGV#1/n
+mbRsCrrCpTIfjThJ&V-]rn[[/s8Lj_VDeJT2l>Hg]hWe6rSB9sLK`%&s80F?_*n?JgAfT_IuD;G
+s,-l$g?sIjs3d!YMp;9[!-d/X\%ht"U4\QJpAP"'a%/:jm/,+pKq?rqs1bSbON%%q%.bJ=s80'V
+K;ePEW3uX)(7;r<rRRKmQI#I.^T+c$LU69b76@I7qYpc=70%Pc\Z#N-)j&>4J's7)W;$>lqltp/
+W;$>ldZAs4XQK>6NVreXp:%efs+13$s+14(s8LjUK`D&.!,qi:!,qkn"IoJ\S5+S~>
+hu=Pjp@.D0i7li1bfI]:]=5/PY,eP"V5'cZrh14(USOcbWiWD0[^j)f`QHNU\_Z<0m`IPIrT4%]
+Im8Ftp&>a#mgc_rn!#$rmgc_rn!#$rkq[hGrp0@Z!psiSrr3Y*A%hT:A?u6TS^HhuCq]J#>-I#d
+li6u`NNVs9?$lOl9=ENqC,X/N]j!7nVkT`M-T>[k=Yj3-7QP="0g']0@o.#k=?LDeN/j^7YdV0?
+!6s!G\OjC#l[M>&s$VJ7o4)A3s,F2Sj^!5Hrr3&eD1DNa!l&9@r;Qi5A>B&%!q"_Brr2uTrdP#e
+!.W#^s8LaRK)bi)$`#Z\!&gY-gU^+%j8I^em>"iirVu`+]>6r:FkH`@O+3)+s8S&YFkH)2s8UN0
+IuV\PN<"+RijQW$gnKLba7fK3&][C&VsF6,QA(m]rVsX4e;qQDrs\E?s8Vu%LP)W$s/<=(rt^s<
+s8CN=KpL*_s1bVENJOn)`^W"elh^Vc`^TrNfXRs\ru7*Gm=3QBJZ/8As80*WK<"\Gs3d$ZL99S4
+Ll_K6!qs(;li06Lp?q,%f[7jZ]X4f<T9te"KRJ#_C1COO;GB_N5s@ClQHlWt6:OUE<EimED0(#S
+LQ7XiUT1T/^W4XMguI_lJcC<$JcE"Trn@I*s8LaQD>jM8D>r8mRK2ZB9n3~>
+hu=Pjp@.D0i7li1bfI]:]=5/PY,eP"V5'cZrh14(USOcbWiWD0[^j)f`QHNU[GBm,m`IPIrT4%]
+Im8Ftp&>a%o*i%umZ\mpo*i%umZ\mpl7meFrp':Y!q'uVrr3Y)@__Z;@^,mOSC6huC;'8"=Kgfb
+lMpl_Mlla9>'p4h8@I3mC,F#L]j!:oVkT`M,r]Lj=Ya*,7ltO&1-Ko3@S^ii=$(5cN/sd8YdV0B
+!6s!G\44'tl@2,"s$;>8o3u2/s,4#Rk$!,Frr3&fDh%`c!l&9Ar;Qi5A>K,&!q+nFrr2uTrdP#g
+!.Vu]s8LRMF8u6j$_T?W!&^G#f!S+khYl"[lA&QhrVuc,]>6o9GM<)FOFN2-s8RuWGM;J7s8UN/
+IuDSOMZ@tTjL;o(hP,Xaa7fK3&][F(W9jE-QA(p_rVsX4er[lHrs\K=s8Vu$LP)Q"s/<@)rt_!<
+s8CN=KpL'^s1bSCMheY(`C2kem/$_d`C0cNg:=0]ru7'EmXNZCJ#N,As80'VK;ePEs3d!YKrjG4
+LQ263!qs+<li06Lp?q,%f[7jZ]X4f<T9te"KRJ#_C1COO;GB_N5s@ClQHlWt6:OUE<EimED0(#S
+LQ7XiUT1T/^W4XMguI_lJcC<$JcE"Trmh*ks8LRLC]4;6C];lfPQ9m28q6~>
+ZMt-hs8W%W3Rd$g!e3GLo)B;G>'"a_PlLc->'"a_PlJ8oA,U3<rrVV,J,]H\g4O*d@Z0=I`GB"+
+At&)A>VTmiC]FDDMb\J;>2'#A@VLLKElJ%X!G&M6ru0=nW3iM=nGh(@Z*LRes8V#\W3N5;oDchE
+p\k*mjYQo9([PdIG]R'!s8TK)Is4Z0s8S!PGB6sAm/I"dmVdURrrSKoao)/?Q=.i3rrVWF!;c]r
+h>m3Jrn[g3s5)V02uN^\2l>HF:3Yk!hD+H*=CRAuf_#3_70%PcpJOV1C.@stMZ@tTh>mTM;J1>g
+:A9YHGM:hjJ)H/mF^f1+rVmJM83<d:cZ`iB@Y*85IlD:]^%hURMuWgU>'k<cSH"(%s8V@$[K"^,
+CNj0/c2W8TItM?6Y/NgkW9jB\-,i:QGM8]Aqu>Xiakd#=HYZ'Cs8T$$HZMrPs7]E(HZ<5`qo-PP
+rrVh_VLebus+13$s4[MPh?8N3hVN2K!!dH!hOFT7S5+S~>
+i;X\mp[RS2i7c`.bJqB3\[8WDWi)YdT:MLARf8]lR[]h=TVJ?^X08k=]>);+cF)<\iIEf-rT*t[
+Im:^?rtGD1H!>E6;j@=\H!>E6;j@<j!+YtCq#:E_D1DQb'&%tOHt82ss2JtfF_@-.g06:ErG2H5
+;iOUtF'I;sjAoDuAkJH8aM8p3ZE:($T5I@b7Q3tcKj-5g2)ANjL1i\-5s&80Sn_f2Z*q9\WW:K"
+hU5>,G'-oss8TN)IsFf3s8S'TGB7!@li-ncm;7@Prr`7b?c`3G"9+NlaSYu=mFqX;rrLjSo`+pF
+"bQd/gS?b+!!Y?WgU^+%j8I^emBfr)OL*R3s2IM.FkHFc8pP,>p&C!OFkGFKs7]N-H"g"IN<"+R
+fkl5qLh([=CrH;P&][C&VsDZQ@Wc+1gAcX]DelrZs!<U's/K@MF&/>+Im3i2lPR)1e:VO[@<Kip
+Ili16B2u+S7QRI5qYqk]7K@S`ShBp?itf_j!-NX*7%XGYWa0mk:RqIZ<G?_u>GD#6`Vf`;o9uQA
+s$-8Il/LIHbf.<*Yc4@eQ&^WNHZX.=@U3)7:J45I6UF+,6q0aB;-$n/ASZ:1IY<WBR%L7X[(F2s
+d+@.:mJ)84JcC<$Z2agX"G6[.gMQig#Ar5MRK2ZB9n3~>
+i;X\mp[RS2i7c`.bJqB3\[8WDWi)YdT:MLARf8]lR[]h=TVJ?^X08k=]>);+cEZ$XiIEf-rT*t[
+Im:^=rt0HYF)t6Ds8R:HF)t6Ds1&,>rG23.!q'uVrr3VbK5#[AMraoWCgqO!RdAg70k^H#s8Q#U
+:3Ub_gAg25<bc/=RE`gi+_n<bW2-&'9ftj&96l7r0Jt^D?A+&H3]02a>)o1hAu)]?]>:QKdb*F(
+;HS*`>.O\5[8MKu:<EP9Mb\J;>2&?BrrVV,J,TBKQ=.i4rrSKoanu)>mbRs?rrLsVo`+pA"`s^p
+et=o!!!Y<Rf!S+khYl"[lEjZ&OL*U3s2@D,GM;dh8pb;Bp]$-OGM:mRs7]E(HY-%IMZ@tTgi%]#
+M.1U:CrQAQ&][F(W9hiS@Wu:4gAcX]Dem&]s!<U's/9+JF&&8*Im*i3l56r/dt):Y@!0`oIli.4
+Alc(R76@I7qYqk\70%PcTIp'@iY9Mk!-<L&7A0\\W*4Oh:7V@Y;J1>r>,(o5`Vf`;oUMfDs$-8I
+l/LIHbf.<*Yc4@eQ&^WNHZX.=@U3)7:J45I6UF+,6q0aB;-$n/ASZ:1IY<WBR%L7X[(F2sd+@.:
+mJ)84JcC<$Z2agS"EXUoenb0`#A_oAPQ9m28q6~>
+ZMt*hs5$(iqVqPT^[_=7lC`WZW:U&hlC`WZW:U&6qg\D@!qs+<rr3Q.es_5_h#IEJ`JoSQk5XS@
+qg\YG"R_e0Mp;8$"P]B%PK!M#!MJKNru1gs_R7DKs8V`B^;&Cqs8VoO]XQ,Rs8UToq#13nnWs.R
+"Pf;mLV<]e"T,HVK=V!]"R_e0Mp;2"!qs+<rVlr8Y3c)d!l;&+qu6`kmXP*5!UbI0s8LjXK`Boc
+VYb98VV]!]GNSk\s6_PII;<J0QJhdm!8dbMCUO&]!9X=]!8db4!<;KfWV>+np\t6Ms6afTW*l^r
+bD!>$rt'Zumer;T_sjm8UAo^'F5$B`s!7%4q^nK4mZ]$ldL>"4W%%?8P\/&,_-E#tIm:F9eQRV*
+IrFcMs!3'ohZ)^Pdf5[hqq_=3mcoQVqtht<oBqhhp[8*]pZSWfqtBa]rrW/[k(3P`s+13$s4[MP
+h?/H2hVS*Is5!mK!:QFQJ,~>
+iVtk9q"!e6i7lf/b/M0.\$E0:VPBfTR[BD*PEM&jP*2#oQ^O>7Tr"]hYdCsT_oT(1]K'ljn+H\A
+s8Tk(rt"FiJVC&os8VDZJVC&os31@iq#:Eh[_MhA&H1.JKqI0#s7aNoLTT\<jehp)s8P[ZSUldE
+s8W)FN-'B@f$_g^A"^?<Y,\@kK3_5WI?0D>@S'1'K8beIE)KJFN1m(sH`OTf_8a-$fA5KOb)q11
+]`%m1qlkd.])M^4n"##hbl%JBp9qa8rr`89Y3Z&d"9-*=lhg\`p?dA+rrMM:o`+pF"G6[.gSF^`
+"f0na9m,Lpg]-Xo[=)h(Bp[cXIfS7'okV#3`W5'!rrCgRgAq9B"K;"IH2%==g]-YXJ#HeYnB-Ek
+r;R=XD=.7_?,?!6?).FL3d'0Lq#;W,s8+LCnaD\fpX0W,s/7@;qitj9nA/@hqgUi>p=*8us*nnQ
+q#;Uh!8IP8'[m#K1ATZ)Npl:f./WlqT^hK8,kpa1W:f>R\GQ!nr;QirioTJ**rGNojPAD5aMGHo
+XJVVWP)G$DH#mh9@pW;<;GU"[r^n2):/Otl>[V,YE-?V\Ll[gkUT(K,^;\=Fg>V8ar.4m!s+13T
+s8LaTK)aT[qJH8e"I]>VRSA;~>
+iVtk9q"!e6i7lf/b/M0.\$E0:VPBfTR[BD*PEM&jP*2#oQ^O>7Tr"]hYdCsT_oSq-]K'ljn+H\A
+s8Tk(rt"CfItO]ks8VAWItO]ks3:Fjq#:Eh\%hqB&H11KK:^lus7XEkKrjG:k,/$*s8PCQS:?IA
+s8W)HMfa3>f[A$bA"gE=Y,\@kKO%;VI?0D>@S'1'JrG\GE)BACNM31tI&j]g_8a0%fA5KOb`I=0
+^&J$7qltd+\c2U3m[Scbc2@SCp:%g8rrU$>m/6kb_63/%rrVo^J,90GmXOm/rmh3ns45boqeHA.
+f!S+khYl"[lL)$-CM.@Ii;\9,hZ*=c[JS&Gk5YG]hZ)F4s6frepY'ugrrCpUmVdTR@'&k@Ks^dX
+&:\WdrK:L)n??/ls*m%Mg@tCB,jt^0/YM_'PU6(P%,V#_.J*G$B$'PY>`S]25I^@:>(cj)DsmE#
+,_#gNs5k$Ds-PP<h>iN&lA$hcq^nK4mZ]$lmf9?]kc22jp@eFa!r_3BlMhq&o'>Amf$DFR]!JK8
+T9te"Kn"AhD.mEc=]J?q9hYIX*DB4*<**=4ASZ7.I"I08Q(4VKYd_?cbgY;)kjSG#s+13$s0;V'
+ecU!nf%0\5s4.=;!9]S=J,~>
+ZMt$gRl&6<s+p^Sh>r<0p>,nb:3Yk!hD+BZkk*N6Io)[4IfS@*s1sqePQ9S?rrCpUh>mTM??_$l
+f)PaMhZ*"^Itqh!s7tU8r;R7VDsm7?GP;'rBSHJ9ABFKD,3f/PIt)A:iqkTps%.kCl?,18Is3hk
+n:,'4s6afTs*ntTq#;Le!8dbU8q6k(MuVW6lMpnL!:&hLGCP*\!93`ZGCtsel@Jtds+13$s3L`E
+h>r<0p>,qB!:QFQJ,~>
+iVseloBk`"gXXZn`P9!lYcOatTU_C7PE:f`MuAMNMi<XVOd)3$St`*^Y-YXO_Q/&7Wnuh%nbA+D
+)?'6sl/UUPd`ohL^:CVTXJhthSt)48Q'@L3Or0CIQ'[o.StVsXX08k>]YVV3dFR+4kO%uPs8LaR
+K)bQ!"1h3Lj8I^elK.7%f<g$(Sbmm:g].5fQ'[^8g].9Rg]-".s7]rGK:C<hrrCgRm;7?.CZ>Bi
+hrXe9%Y&?_oQ56Ks5IdJs*nS#o`$-$!d0!BDZJhp304)3KE(7\4*lC#2f\A;B'''[D1DS8D=.,u
++b'LHs8P]BrB-)>gApL<s5sCJlN23YIr>>IpL/8uO14?1ruV.3mcWN]d`]SB[]la+S<f7oKRS/e
+DJ<Wh>Zk*,;uTZ7;cQn'?=IM^E-?SZLQ.LcTVeit]"uJ6f%f<Onq$gls+13Ss8LaRK)bQ!"I]>V
+RSA;~>
+iVseloBk`"gXXZn`P9!lYcOatTU_C7PE:f`MuAMNMi<XVOd)3$St`*^Y-YXO_P_c3Wnuh%nbA+D
+)?'6sl/UUPd`ohL^:CVTXJhthSt)48Q'@L3Or0CIQ'[o.StVsXX08k>]YVV3dFR+4kO%uPs8LRM
+F8tsb"1:aBhYl"[kiV+$fX$'(SGRd9hZ*VlPaI[8hZ*TUhZ)F4s7]iDK:LNmrrCpUmVdT1CZ>Bi
+i9't;%Y&EboQ>BOs5I^Gs*nS$o`$-#!-`pBDZJeo23@i0KE(4Z4*uI$2f\>:B'0-]Dh%e:DsmE#
++b'LKs8P]@s#l;?h>lj@s69ULl2Z$XIr>>HpKi&rO1FQ5ruV.3mcWN]d`]SB[]la+S<f7oKRS/e
+DJ<Wh>Zk*,;uTZ7;cQn'?=IM^E-?SZLQ.LcTVeit]"uJ6f%f<Onq$gls+13Ss8LRMF8tsb"I&oL
+PY-H~>
+Zi:-j7;qmNs+gXRh>r<0p>,nb:3Yk!hD+5gT(N'_l>(V<IfS@*pJud2VuY]SrrCpUh>mTQ_5)j1
+>5/$shZ*"^It_Rqs7t0ur;R7VDsm7?GP;'rBSHJ9Dr1-d,3f/TIt)fXlMm)/hAFuHl?,7<Isl=8
+oRCfIs6afTs*ntTq#;Of!8dbUTIn_3hZ)F4lMpnL!:&hLH[gNlBBoB1UkaG5W;D/GJcC<$JcF*s
+rn[[/s7Y:PS,i#J:4N~>
+ir9qpp@%8+h:Bus`P9!lYH"InSXGb*Nf/aLKnK>U)M<]tLl.1RPF%c2Uo:E$\#V8c`mi`#k3V[:
+NW0jmoBti%h:U0#aMbj*\$N9=W2?>`T:MLArL+LkSXuLKV5LAsZF7?Y_oL!Kf%f6Im.@adrn@I*
+s7Y1L\kR>-rS''hU7_,Ys649Ap4!(ss7]TEQ`:&?s8N)Rs4[PRqnf4cF]nJ=!8IP@D1@7RirAi(
+gALs\Ir4TFFER9Vib=,HIr3s4s!$\-H%1<jBC#S^3o1k1s64VfI"-QaWV(aXmJlQjJ,b"8mJ-]*
+IfS7's.V-o(uG;I!9sO`klBu4!-s'DHY;[A_PW*;B;k^bs#p/IlJp[McH!c4Z`U.!RZrhhK78&d
+Deiuq?s[)A=]np4?!h&PBl.j5H[pj0OdDZ8Wj&tH`66T^hra>#JcC<$JcDtSrn@I*s7Y1MRK2ZB
+9n3~>
+ir9qpp@%8+h:Bus`P9!lYH"InSXGb*Nf/aLKnK>U)M<]tLl.1RPF%c2Uo:E$\#V2a`mi`#k3V[:
+NW0jmoBti%h:U0#aMbj*\$N9=W2?>`T:MLArL+LkSXuLKV5LAsZF7?Y_oL!Kf%f6Im.@adrmh*k
+s7Y"G[7YMsrRN^aU7V#Ws6=BDpO<2"s7]QDR&C#As8N)Us5!bUqn](`G?Xb@!8dbDDh!ISirAi(
+gALs\IrFcIFa*QZib4&GIrF39s!$_.H[gNlBBoM]3SkV,s6=_iI=HZbW:YRXmf2]nJ,b":meHf+
+IfS@*s.Csp(uG;L!:'Ual2^,7!.03FHY;X@_5)j9BW1gcs#p/IlJp[McH!c4Z`U.!RZrhhK78&d
+Deiuq?s[)A=]np4?!h&PBl.j5H[pj0OdDZ8Wj&tH`66T^hra>#JcC<$JcDtSrmh*ks7Y"HPQ9m2
+8q6~>
+[/U3,196!+L&_//!JLLHh?1GdGNSk\1$Xj"Y3>;m@#Xu4!8@JA!7(V\!8@JQ!8@J0!<;e+hYXPX
+oD\gEs6afTU0OkjbB^&arsjNsmer5P_sjm8UAo^]hXpglq^JK8o;I<As5F`28cShfP%`,3c'H3G
+IrFcTmVdUTIr4QIruupmgAh38'OFQ7s5!a7md>iZqthh@oCJo5s7^0_qpnkpq>1*mrT**ls+13$
+s+14(s8LjUK`Cc&"IoJ\S5+S~>
+j8U+uq!m\3hUp9#`k]0nYH"FlS!T:uMhct:Isl]krd#K0I"$TuL5CkNPaS,;VlY%dGf.YLe_B*I
+me2V>(AdXiki1FNe'?+T_7dCfZELC1W2?Ddr1Xt%Uo(&iXKSq;\\,_raj&8cgu7G_oDZ2urn@I*
+s7Y1L\kR>-rS''kO&`FJm_iLjqL8Lss6Tm4rPAQds8N)Ns4[PRok3.WXoe.n!8%8<D1A9bYOK\[
+W;QZ*Ir4TNO'KNiY[!q&Ir3s4s!%7gVXa8XL&_23(3*%Js7qdjbOWrF_Z,+&mJlQjJ,b"6lhLK(
+IfS+#s5t/):B1@K!0$C6M(&2q.]2b-WeLKGBAWI5=F']<rrW,Xjludcr:KC=hq6B#`4iadX/2GV
+PE(HOIX6-VD/*]p@q,FG*+NMkBl%^/GC4srMij<qU8Y6&]>;S7e_K3MnGRq<JcC<$YlF^W!J:@F
+gB<rFl^COu~>
+j8U+uq!m\3hUp9#`k]0nYH"FlS!T:uMhct:Isl]krd#K0I"$TuL5CkNPaS,;VlY%dFi2>Ie_B*I
+me2V>(AdXiki1FNe'?+T_7dCfZELC1W2?Ddr1Xt%Uo(&iXKSq;\\,_raj&8cgu7G_oDZ2urmh*k
+s7Y"G[7YMsrRN^cOArCHm_rRmqgSV"s6fs5s1n]hs8N)Qs5!bUpLi@[YlOCq!8@J@Dh"KdY40V[
+W;QZ*IrFcROBf]mY[!q&IrF39s!%=hW:TVZKE(u2'Q6SCs8.smc1B2G_>f"'mf2]nJ,b"8m.gT)
+IfS4&s5k#%:B1@N!0$@6LFN,t.B)k0W.Y-EBAWO:=F'`=rrW/[k3;mdr:KC=hq6B#`4iadX/2GV
+PE(HOIX6-VD/*]p@q,FG*+NMkBl%^/GC4srMij<qU8Y6&]>;S7e_K3MnGRq<JcC<$YlF^R!H\;7
+ec_3;kEJSh~>
+[Jp@"DXln@s+ULPh>r<0p:UR0:3Yk!hD+HGG?Sp+ApMT"O<JDnpH<;IL`p^:rul13h>mTQ;JLPk
+<r;n?CYIQ^J)#ZaF^f1+r;R7VDsmYMF^fK$J_L-RDr1*c"e]%CG>aP%rrPb'Z2Xb:c[BJNA9#Zi
+IrFcTmVdUTO@Gu2q>VY#+`#g3s%Wj$s8UpUCNjhgT`>%b>'G0gOT52UC3sr,W;ZSm!q`"[JcC<$
+JcC<$gAh0/!JLLH]`ai*n!m.'~>
+j8U+ro^:o$g=4Bf_7R+YWhc8UQ&pr\KReJsG]e+Lrc/s!F`r%WIY*<3Ng#j$U7P#VT"`.cdF[48
+lLFb1rtbG%mHETeg""HnaMbm-]!o&OYHFt-WrAt5WiN5'YHbFB\\,\pa32fYf\PQMm.(%^s8LaR
+K)bPU"0,(<j8I^emEg&]Df]N7b5[MFCY8;DCPRckDu]h[CY7AAs7oT/H"U4Sruc+0fkl5nK4/n4
+D8lGQ%Y&?_s35XoFC9[Rs*nn?oD\ug=a,'iOoG@^8eSB-rtEb-BQn'0aT$a,mJlQjJ,bR!U?hXT
+,**j^f`1tH$EjF/gAkr3ECcc&s.WY?G?'e*q,;'SE*oRAqYpWgR\o<K*;Asej4r22aMPTuYGn=h
+R?NYfKReGpFE)59CMNi_)es2,E-$2KIY*?6Od;N2Vld;9^W"FFg#(rZpOW?qs+13Rs8LaRK)bPU
+"I]>VRSA;~>
+j8U+ro^:o$g=4Bf_7R+YWhc8UQ&pr\KReJsG]e+Lrc/s!F`r%WIY*<3Ng#j$U7P#VR_H__dF[48
+lLFb1rtbG%mHETeg""HnaMbm-]!o&OYHFt-WrAt5WiN5'YHbFB\\,\pa32fYf\PQMm.(%^s8LRM
+F8tsA"/JP1hYl"[lHsfZDf]N9bQ!YICYJMGCPR]hDu]h\CYIVFs8,]/HY6CVrul13gi%\tK4&h2
+CrQ>P%Y&Ebs35[qF^TdSs*ntDoD\ue>'G0gOT,7]8J&0+rtE_,BQn!,a8^X-mf2]nJ,bU"U?q^U
+,*3s`gAh1J#d"(+h>h>8F%)c%s.EP>G>aP&qbh0UEF,UBqYpWhS>PNM*;Asej4r22aMPTuYGn=h
+R?NYfKReGpFE)59CMNi_)es2,E-$2KIY*?6Od;N2Vld;9^W"FFg#(rZpOW?qs+13Rs8LRMF8tsA
+"I&oLPY-H~>
+ZMspfJcCH(rn[[/J+ZP<-[4_OhD+HsfV!qNSCIH9c_,dAs1O&?`Lqk`s.FkqmXP9:c&7(5f)PcC
+J(itm^]3#ZK94.Ir;R8A\+]k!c^'3Rf_tib\*ikf"o#*NK;A,<rrTl`oD\b'qpCd`Pfrn&^UNq:
+p:%g:c]G6pq>VVaTRY\qs+;<Zs8UpUabPMIp](9fXFl/$oDej8MgpMglM:G]p:%efs+13$s+14(
+s8LjUKR`Yi!s%e[:4N~>
+jSqCBq!mY0h:Brp_nEL_Whl>VP`L]VJUMfeF)Z#5CMIU"Ci+*1FE`(]K8>MMQ^jeKXdQc9`m)ud
+i90M"rf$jlq=F%=jPS_Dda$%V`501"\[SuRZa0S8s0<<E[C3TW]thP*b0JDcg>:lRmIU:`s8LaR
+Jq*Gf![`'MrS''or7@TqKUgKes3I?hf`/[<M8l9Ds8SaCf^41gs3?OPOjsF2TRkbT[_MgpSqN6I
+p\b%$^UEk9qTb@ZSCd`>^UEP$rrr.uKnH8orr3&4J+<O<'Dp1EKTs^Vs1c#9s7Wn9s3He/lhUQ(
+c_,jAs8R]mn,NFB!6BqJWqZPnpT0($VXsifcAR1.Zg%;c!qs(;kl2V"o^1f!g!e3c^q-nUWM?&Q
+P`L`WJq&/nG'%g(E>rq>Fa&.[JV8l>P*_]4VQ@&3]u/">f%oBOnG\"=JcC<$YQ+UV!J5go9`kC]
+RSA;~>
+jSqCBq!mY0h:Brp_nEL_Whl>VP`L]VJUMfeF)Z#5CMIU"Ci+*1FE`(]K8>MMQ^jeKXd6Q6`m)ud
+i90M"rf$jlq=F%=jPS_Dda$%V`501"\[SuRZa0S8s0<<E[C3TW]thP*b0JDcg>:lRmIU:`s8LRM
+F+<jT![VpErRN^grRdcsK:LHgs3I?fgAej=LW,p=s8SaAg?sIjs36IOOOjI3TRY\V\%hssSqE-F
+pAFq#^UNq:qp1R\SCmf?^UNY&rrr.uK7fukrr3&5J+N[>'Dp1EK9XRTs1c&:s7Wq:s3He.m.pZ)
+c_,dAs8R]kmf3=D!6L"KW;$>lpT0""V"=Wdc&7(,Zg.Ad!qs+<kl2V"o^1f!g!e3c^q-nUWM?&Q
+P`L`WJq&/nG'%g(E>rq>Fa&.[JV8l>P*_]4VQ@&3]u/">f%oBOnG\"=JcC<$YQ+UQ!HWb`8co(V
+PY-H~>
+ZMspgJcCH(rn[X.o3MHpk5F-:mXbE;rrVdmDuTb;h>i-,JcC<$JcE=]rn[X.oR?rCn!m.'~>
+jSqC?o^1i"g!\*`^UUSNVP'BBO,8O>HZjFJCM@Bl@q/tXA7]FhD/jZCI=d65P*_`7WKss)_TC-T
+h;dejqhtIgqt0@Bk2G.Le^DadaMl'4^:h.i])B/Q]">Vh^r"(2b0A>`f\GEHl0e9EZiC$Z!.sfH
+!Me]RgApVls8W*$rUX01rr3#R!6>+"p[RP0h:L&t`P8sjY,S4hR['"pM2$Y5IXHHeH$FU\H[UBp
+KSYPIPF.l6VQ6u2]Y_b8eD&sFmeMG6JcC<$Y5eLU!.sim!s%YU9n3~>
+jSqC?o^1i"g!\*`^UUSNVP'BBO,8O>HZjFJCM@Bl@q/tXA7]FhD/jZCI=d65P*_`7WKO[%_TC-T
+h;dejqhtIgqt0@Bk2G.Le^DadaMl'4^:h.i])B/Q]">Vh^r"(2b0A>`f\GEHl0e9EZiC$U!-@a4
+!M80Hec=uds8N$"o2]f/rrLsVa8\0on`o2kf?qd\^U^_SWMH/TQ'%&_L4b#*I!U'`G^4U^I=Hg$
+Ll7=XR%0kIX0K.H_T:$PgYq>`q18Qss+13Qs8LRLF7aqa!9]S=J,~>
+ZMspgJcCH(rn[X.o=Y1Uk5F-:mZ%5Im&^)6!J/)crr_8%3R[p,!Tl+fs+13$s+13]s8LjUK`Cc6
+"O-r8S5+S~>
+jSp7qn`o/if$DFR]<n`=Tpq=.M1gA(F`;/1A78hN>lIqI>[CfJAnl4(GC4ssN09R"V38*n^;\=E
+g#2&]p58k_rUo[HkiC[Wf[\Erbf\#H`5BIi_%FQ%`5]m@bg4\df\><DkNhU4Z2agX!.sgN!RTm*
+gApW#rrMGeqgSWu_YsK:hfCj(rr3#Z0ZX2QrUoUBinW,3b/D$)['$C)TU_C6OH#-QKnFu.J:N3%
+K7nu9MiX$eR\$:PXKf4H_8jgLg#(oWo7?pms+13Ps8LaRK)bQ3"O$l3RSA;~>
+jSp7qn`o/if$DFR]<n`=Tpq=.M1gA(F`;/1A78hN>lIqI>[CfJAnl4(GC4ssN09R"V2qmk^;\=E
+g#2&]p58k_rUo[HkiC[Wf[\Erbf\#H`5BIi_%FQ%`5]m@bg4\df\><DkNhU4Z2agS!-@b6!Qs9t
+ec=uprrMJfqgSWt_>XB9ic@-.rr3#]0us;RrUoUBinW,3b/D$)['$C)TU_C6OH#-QKnFu.J:N3%
+K7nu9MiX$eR\$:PXKf4H_8jgLg#(oWo7?pms+13Ps8LRMF8tt!"N^Z,PY-H~>
+ZMsphJcCH(rn[X.o=Y1Uk5F-:mZ%5Im&^)6!J/)crrV20W;Z_spT];LJcC<$JcE=]rn[[/s7Y:P
+S,i#J:4N~>
+jo7RDp$V#$g!\*`^:1>HUn*j7MM-J)FDko*@9m2cO,n`p<)lt%>[LuSCiOWGJr#GOR\5_D[(F/q
+cdpq5lgk"3s!Rg@o'Yf*j58YFf$r-ocHOJSaiVWGai_fNc-Oedf%Jj9io]LmnbfWkrn@F)o<n\H
+j8I^4m>_,Hl`Bu5!J82err_50W;Z_q!VN\:ru1b*m,m6[e^)@U^:CVSX/;V_S!TA%O,]'TM>i;K
+M2I7POHYuuSY2dXXg5FK_8jdJf\YZRnG@e:JcC<$XoJCT!J:@FgB<rFl^COu~>
+jo7RDp$V#$g!\*`^:1>HUn*j7MM-J)FDko*@9m2cO,n`p<)lt%>[LuSCiOWGJr#GOR\5VA[(F/q
+cdpq5lgk"3s!Rg@o'Yf*j58YFf$r-ocHOJSaiVWGai_fNc-Oedf%Jj9io]LmnbfWkrmh'jo;r&9
+hYl"*lAbfEm&^)6!J/)crrV20W;Z_spT_a<)Z''lk2=tDccO,>\[8Q@VP9ZOQ^!VnNJi[NreMGK
+MN!RWPEqW-TVSQhZF@K_a3;uahW*njqgncus+13Ps8LRMF8tsb"I&oLPY-H~>
+ZMsphJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jo6:roBbSqf?_OT]<n];TUD"&L4FSlDJ<WgP0Wk$ru_-N>Ye6t=^>HJCiOZIK8G\USVsMP\%]i*
+e(WdEn+qk?&H)7lmHWioi835Af@AC"daA'@s3V>)eCE1(gYLfJk3;7%q#7Jsrn@F)o<n\Hj8I^4
+m=G;Kru(S$lfI$XeBc7T^UghXXf8.kSsu.6P`q5lrf@tZP*;/tR[p+HVlR#-\@oc"bgG%uiooh+
+JcC<$JcDhOrn@I*s7Y1MRK2ZB9n3~>
+jo6:roBbSqf?_OT]<n];TUD"&L4FSlDJ<WgP0Wk$ru_-N>Ye6t=^>HJCiOZIK8G\USVX;M\%]i*
+e(WdEn+qk?&H)7lmHWioi835Af@AC"daA'@s3V>)eCE1(gYLfJk3;7%q#7Jsrmh'jo;r&9hYl"*
+l@JuHru(S$lfI$XeBc7T^UghXXf8.kSsu.6P`q5lrf@tZP*;/tR[p+HVlR#-\@oc"bgG%uiooh+
+JcC<$JcDhOrmh*ks7Y"HPQ9m28q6~>
+ZMspiJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jo7R?n`f&feBQ"J\?W'/S<].kJpVWYBk(IPo`+sQai`oKs6!QY:/Y.u@:j=rG^kF+P*q0)XgG^W
+ajA\tk3_hrrsnquna>`,jl>=Wh;$`;g&BY(faQThh;7)LjlbprnFupas8LaQK(HDOd,Y)Z!:>@;
+])NWHp@.A.hq?N*b/M0/\$N9>W268^St)7;rKnChR[]k?TqnTdY-GCG^;J%9db!:6kO%tos+13$
+s/Z2!gAup+p=f_=!:-(JJ,~>
+jo7R?n`f&feBQ"J\?W'/S<].kJpVWYBk(IPo`+sQai`oKs6!QY:/Y.u@:j=rG^kF+P*q'&XgG^W
+ajA\tk3_hrrsnquna>`,jl>=Wh;$`;g&BY(faQThh;7)LjlbprnFupas8LRLF7ZL7b23*J!:#.8
+])NWHp@.A.hq?N*b/M0/\$N9>W268^St)7;rKnChR[]k?TqnTdY-GCG^;J%9db!:6kO%tos+13$
+s/Z2!ecBjlp=9A2!9]S=J,~>
+ZMspiJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+k5RaGp@%2&g!\$\]X=o?TUCt$KRS,bC1LXR;sL;e69dUrQ2gls6qC!K<a9'GDKL5VLl[jVUoL]1
+^rOaNh;mnmre:@[qt9OKm-<fsjl>@Zr87tAioB+^kj%O&nb<$`s8LaQK(HDOd,Y)Z!:>@;\c3KE
+p$_2,hqHW-bJqE5]!erKXK&1pUS=I[TG=/qUo()kY-G@D]YMJ-cI1>"iof_$JcC<$JcDbMrn@I*
+s7Y1MRK2ZB9n3~>
+k5RaGp@%2&g!\$\]X=o?TUCt$KRS,bC1LXR;sL;e69dUrQ2gls6qC!K<a9'GDKL5VLl[jSUoL]1
+^rOaNh;mnmre:@[qt9OKm-<fsjl>@Zr87tAioB+^kj%O&nb<$`s8LRLF7ZL7b23*J!:#.8\c3KE
+p$_2,hqHW-bJqE5]!erKXK&1pUS=I[TG=/qUo()kY-G@D]YMJ-cI1>"iof_$JcC<$JcDbMrmh*k
+s7Y"HPQ9m28q6~>
+ZMspjJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+k5RaEo^1bsf?_OS]!AB4SX,=mJU2ETAmeeA:/jSF4#f)S1pm;Z6U=17;-.%5C2eBGKoD4KTr>0'
+]uA4EgZ%Jfr.G"UrV?-WnF#Z/lKS61$0ga@m-X94p\b#is8LaQK(HDOd,Y)Z!:>@;\GmBCp$_2-
+i7li1c,mo?]t1YZZ*1:1WMlcpV\Z51WiWA-ZF.3S^Ve+8cd^V'iof_#rdk*#s+13Ms8LaRK)bQ!
+"I]>VRSA;~>
+k5RaEo^1bsf?_OS]!AB4SX,=mJU2ETAmeeA:/jSF4#f)S1pm;Z6U=17;-.%5C2eBGKoD4HTr>0'
+]uA4EgZ%Jfr.G"UrV?-WnF#Z/lKS61$0ga@m-X94p\b#is8LRLF7ZL7b23*J!:#.8\GmBCp$_2-
+i7li1c,mo?]t1YZZ*1:1WMlcpV\Z51WiWA-ZF.3S^Ve+8cd^V'iof_#rdk*#s+13Ms8LRMF8tsb
+"I&oLPY-H~>
+ZMspjJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+k5RaDoBYJme]u1L\?Ms,S!8kcIWoaF@pE#08OG[%1bgU6/9h-o:cgs49N,)$Ao2X:Jr,S?T;J`t
+]>Me=g#2)_qLSYOs8Moip%.bEr:'aV"7u6^rMBPngAlis[K4b8rS%>>JcE4Z(&[anlK.![f[J0i
+a2Gg.]=>;VZa$b5Y8+:HZEpsJ]"Gep`lZKQe_8m?kjA$AJcC<$JcD_Lrn@I*s7Y1MRK2ZB9n3~>
+k5RaDoBYJme]u1L\?Ms,S!8kcIWoaF@pE#08OG[%1bgU6/9h-o:cgs49N,)$Ao2X:Jr,S<T;J`t
+]>Me=g#2)_qLSYOs8Moip%.bEr:'aV"7u6^rMBPnec9d_XT?T$rRLu6JcE4Z(&[anlK.![f[J0i
+a2Gg.]=>;VZa$b5Y8+:HZEpsJ]"Gep`lZKQe_8m?kjA$AJcC<$JcD_Lrmh*ks7Y"HPQ9m28q6~>
+ZMspjJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+k5RaCn`o,geBGnF[]cU%R?EG[I!':<?W^3!76W[e/h/1o,]j"c5W1\j85E5j@qp".J;9/7SYW<l
+]"uM8fAG`YpjrJArs&K$r;?Nmrh0;jgAlis[K4b8rS%>>JcE1Y'`I^olf[9ag=F]tbK.Z>^qRIm
+\[_UIs0r]Q]=ktq`5]pDd+$_'i8s4kpATXCJcC<$W;lkO!J:@FgB<rFl^COu~>
+k5RaCn`o,geBGnF[]cU%R?EG[I!':<?W^3!76W[e/h/1o,]j"c5W1\j85E5j@qp".J;9/5SYW<l
+]"uM8fAG`YpjrJArs&K$r;?Nmrh0;jec9d_XT?T$rRLu6JcE1Y'`I^olf[9ag=F]tbK.Z>^qRIm
+\[_UIs0r]Q]=ktq`5]pDd+$_'i8s4kpATXCJcC<$W;lkJ!H\;7ec_3;kEJSh~>
+ZMspjh>dMinc'<gTS%lqoDejUTS%lqoDejMP^eqSpAb01rr4#;es_;ch#IEOc^'9Xh#IEH`K5Y'
+W;$>lpS`_"\c2U/^&<E^\c9qOIi%PQqpq3iT\TSIn@OO6\aKLtqp1R^T\T;A!/LOQ!58>\!4i%-
+!TJV+rr@iQru(IJOF`_Dqu?WGRY@Eis8VT#M2Ae2s8UrIrI4gXrr3,;LP)Q&p&G$J!/0sW!S6E3
+h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+k5RaBnEJocd`]P@[B6<uQ]R#SH?*e3>uj`l5rphT-mKfS*4c+".krtH6q^E\?taJ%IYE`1S"cpf
+\A6/2f&#NUp?M\X^[_=<l_9#cWq68jl_9#cWq68jj-,%XhY7$Orkl\Rruq?kR>%<hs8VrAQA(sb
+rr;Z1OFi+bp&G'bWe6):rVuo1rI4m[s3CLk)"%A#eX;,ah#IEE]8DKVmf3=`c^'9WgA^pJ!W@lR
+rrB_1IfR(XrrM).r;QfrM>dGlou3#EQI#F-rRI<iT\TSIn[j[9\aKLth4=Lo!4r10"MfkHWql>f
+rn@F)o<n\Hj8I^4m=G;FrtGD+o'P]&i8!#9da-.[a2Ps5_8,u`&\u6#`5]mAcI(.ngYUrQlgOY#
+s+13$s/,hqgAup+p=f_=!:-(JJ,~>
+k5RaBnEJocd`]P@[B6<uQ]R#SH?*e3>uj`l5rphT-mKfS*4c+".krtH6q^E\?taJ%IYE`.S"cpf
+\A6/2f&#NUp?M\X^[_=<lC`c^W:U&hlC`c^W:U&hifnqWhY.!L_uBZVrRREkT\TSIqp1R^T\TSI
+oYloCK;ePEs7`IELUmEa!58>\!kJ?UqgTFMs81B9KqR6$s7!XWM7N'Ss81-.KqR5qrr@iQrrBb2
+IfR%WrrM,/qu6YOrVmc-`K5Y:chmb@es_;ch#IED]8;BTmf3=DT)F-=\c2U3_2!ZAqt:!gec9d_
+XT?T$rRLu6JcE.X'E7asmHN]igtC6+ccjPP`P]R/_#1qZ^qmq,`lQ?KdF?e&hW!_an+hP7JcC<$
+VZ6YH!H\;7ec_3;kEJSh~>
+ZMspkh>[P+5JQdh'RO#-F&nP*s*IpnF&nP*s)1q^>%[U1"T.>p<eLDO,1q<MEEn@]s3#OqF^g9g
+s1;`JF)t*Hs8SHaGB6[$s8Q[krbDS?s2k4T)Ef83s06uYEEn@]s0lHMBje7Hs3#OqF^g9gr;Qos
+k16=6rVln13W<doZ2O\(o5=X.rr`#HU^6r!)S9HdF's.8s4Da+EEn@]s0lHMBje7Hs0>I!rbDeE
+s8U&AF*C6]p&G$J!/0sW!S6E3h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+k5RaAn*&]_dE9A=[&g*pQB$`NG]@G,>?"9b4uY/E,97U9>Q=_<-7q&96:k!T?=n%sI"R?*R\?[a
+\%fr.e_T<Qo]lGXIm:^?rtk\5HX1i<=-Wa`HX1i<=-WabEE.9gC&Ro."T.>o<eUJP,1q?NE*\@^
+s3#RtF^p<erju]MFE:6Hs8SHdGB6[!s8Q^krbDS>s2b.S)E]52s0@)[E*\@^s0uQOC1=OKs3#Rt
+F^p<er;Qosk1676rVln23<![nYl4S'o5+L,rr`#HU'go")udH[@WZ%#bl?=E?>s2-jSu`"B51n^
+rr9<#;Z:G;YlFaC=`nj[YkA%qgAlis[K4b8rS%>>JcE(V-i3H'lf[<dgtC9-dEg(\b/hWD`l?'>
+aN;TKcHt"if\>9Bjlu1'r.4m!s+13Hs8LaRK)bQ!"I]>VRSA;~>
+k5RaAn*&]_dE9A=[&g*pQB$`NG]@G,>?"9b4uY/E,97U9>Q=_<-7q&96:k!T?=n%sI"R?'R\?[a
+\%fr.e_T<Qo]lGXIm:^=rtKf`GB6fLs8RFLGB6fLs8R"<G?SVSrri5]]iKdbs!$*D??'5,jT!DG
+A9D@>ir?W"?upBaSH&VV;Km1[`W,sM3W<dqZ2_rECDo>Zmf0P???'5,jSu\uB5(bZs8U8bA9D@>
+ir&fZqrZJ*#lXc(Ai]j+!3uM&!qU=1rr3)pet`TMru/LY?uo^uc2ZFE??'5,jSu\uB5(bZs8TB$
+;Z:G;Z2ajC>'"m[Z1\.rec9d_XT?T$rRLu6JcE(V-i3H'lf[<dgtC9-dEg(\b/hWD`l?'>aN;TK
+cHt"if\>9Bjlu1'r.4m!s+13Hs8LRMF8tsb"I&oLPY-H~>
+ZMspkh>[S,5C^H@rtkCs&@M,tQm)Lt&@M,tQm)M$%))DS#kRom"Rrg9.=_?s,+_uDlC_Ifqi"q)
+m^$]1oQs]`nEu5]s7[\0oBL[+s8P6DrosRZs82f\)qn&Ss8P5cZKe)hYk`cZg>6Fiq>6+YamQKN
+XSi)$n?n'M!<)ou4co[.!;HHl!gGtNrr3)[Lf+6Pru:TW=Ng3I=H`]U>-dFd?Ej6TAD5mPIJNo7
+B"e3/#l"B!<dX-'PaM.Drn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+kPmmJp@%2&f[7gX]!JH5SX#4iIs5jF@9HK$6Td1W-6F';0(/bG*$Zpf3']u/<aB9QFF/UsI$pY+
+YID6cc.1V1lgsEA"+NOb^\.UCp?`F"oC%tfs6UB+oC%tfs76`5pV[F-qYp]f[;@=Arr4C<>I3Ug
+@']Zg@EIuECT[2S=j-@(N$eT!,,"PnHX$OM5`b0qlh1;Rrp(NV9UPk[5$PAYTjY2%J7[EiB70IN
+N+'isZYQ]@rrhi!M,=9OrrkZKl0I[.rr3*!PX5BLrr_5:;#pUq-hDXebON8KP5h+XZg+5lZMB#^
+g"g:gp]$k!]]nbJp&G%nH0b!bRe?^[gAlis[K4b8rS%>>JcE%U&cMIpmcruqi8*/?f$r0rd*L&;
+c4J=KdF-Opf@o$;ioTCjnFup5s+13$s.o\ogAup+p=f_=!:-(JJ,~>
+kPmmJp@%2&f[7gX]!JH5SX#4iIs5jF@9HK$6Td1W-6F';0(/bG*$Zpf3']u/<aB9QFF/UsH't>(
+YID6cc.1V1lgsEA"+NOb^\.UCp?iL"oBqths6^H+oBqths76Z4pVdF0qYp]f[;@@Brr416>-dFd
+?Ej<c@*.iCCTR/T=Ng4%N$\Mu+e\GlHWpIL4co[.!r)`lrotHV:72(]4^,/VTO+kuIq79iApsLP
+N*scqZYQZ?rrhi!Lf+6OrrG9ErosLXrVlq`5lgoa"6,,7!<3!;oQs]`n@_qes.3E"lC_Ifq0ur/
+hI_33s.3i9rosd`s8Q,HlLU7-p&G$B!-@b6!Qs9tec=uds0DY:rV,mNlK@3ch:pT5eC2glcd2U9
+&C8_NdaZh!g>(TFjll(#p\oaDJcC<$V#UGF!H\;7ec_3;kEJSh~>
+ZMspkh>dM)!l'6"pAYs&mL[)/pRE6'mL[)/pRE6'o7-Z;dL>aDs"<rgVG;X@s7q(_m/P^MNV.F<
+p]'5iM=R[Qqu?]('`[J!n,NF-'`\1MDh!88p\b%1MeDeao*B@&s4CqCq743;k\ktHolYKQs5ImP
+r;Qolc*<c=rVm$<Dh!88p\t0p]h5(#rr3)cZ((gns!RB;ZhsdVA;U,1EU<_XArZVs^&@/5J,0,&
+6[+$0W;$>d&?1G;SD*Z9rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+kPmmJp@%2&f[7gX]!AB4S<](gIWo^D?s$8u69?tS,TRUJhZ(kD)'LC^2a9c,<Es'MF*`FpI$pY*
+YI;0ac.(P0lgsEAs*k*bJ%t^W(\[5-]_V;j*rkU=]_V;j*rkh]qu+kMn,!&:oZa7-J,fQEI;nNP
+f4^6<Fa!KYibj\FWNl="s0NXClN$>Ps2>iTru,m*JZAJBru6l-p&FUhE9mPUBTMu"^&7#1IJ<DW
+G4tsqDN"Gm"SBsERK3<d"WDB/JZAJDrr]i(U]CDo"6m+[!<3!Gnu8njs4M"Bq0d5Js4:qFq743:
+k&,VAs,9BjI=\Ems7[)%M1_DSp&G$G!.sgN!RTm*gApVls02M5r:][KlKI?hi838Cg"=pTf)O>1
+f\5*9hr3YYl0Rm4rIP!"s+13Es8LaRK)bQ!"I]>VRSA;~>
+kPmmJp@%2&f[7gX]!AB4S<](gIWo^D?s$8u69?tS,TRUJhZ(kD)'LC^2a9c,<Es'MF*`FpH't>'
+YI;0ac.(P0lgsEAs*k*bJ%t^W(\[8.^&.Po*<5F<^&.Po*<5V[qu>(QoD8J>oZa7.J,fQEI<"WR
+fOg-9Fa*T[ibaPCWjDU&s0WR@lN$DRs2GcQrto[(J#N,>ru6l/p]'gjEU<_XArZVs^&@/5J,/b[
+GPD-sD2J2j"SBsDS,iNf"W20-J#N,@rr]r,U]CDo"7!.]!<3!GnuB%ns4V"?q0d8Ls4CqCq743;
+k\ktHs,06gIt+Eks7[)(LP),Np&G$B!-@b6!Qs9tec=uds02M5r:][KlKI?hi838Cg"=pTf)O>1
+f\5*9hr3YYl0Rm4rIP!"s+13Es8LRMF8tsb"I&oLPY-H~>
+ZMspkh>dM)"96,c^\.U9DaJep22hM7DaJep22hG5!e4*Wp\uf4Dh%fen8WmTs6=HPq1W.um^59/
+rUfg\g:^[:s77)'oBLf*s7[LKIr@cKrVm;S3S+61iW+E*s6=HPrr3DABj.b@q1W.um^59/q>UKP
+!<3!-pDdsuDag?!s4U5Dh>mKR!T!hUrt#)#pA<R%C;'+VIJs32D1V]d'Ye?cYlFTW6Zmls7A0\C
+!,m(&8u2.[rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+kPmmJp@%2&f[7gW]!AB4S<](gIWfXB?s$8u69?tS,TSAhs3r#$)'C=\2a0]+<Es'MF*`FpI$gS)
+YI;0ac.(P/lgsEAs*k.N^OO#mrt#,-D*`Gk1lMD4D*`Gk1lMA5"T<aI@K$!$/F@;(s8VV/I/O$/
+CkDJ:?d.uH5_/h*pA<OU=aU2?(oHojIffZC*c6=F8>?(_*7-ars8V*ZI/O$/CkD]erk2uKYQ"?O
+?d.uH5_/\1!S[VRrseWBD1-CpUAt8I:86JCr;QfP!<3!GrUfg\fnsOXnSrsSs64?Os8W)3BNhV=
+qM@X`I;qfPs5sB#H#lWSp&G$G!.sgN!RTm*gApVls/uA1qt9OKm-<cqjPo.Vhu)==hr*JRjQ>^m
+mI9iJJcC<$JcDDCrn@I*s7Y1MRK2ZB9n3~>
+kPmmJp@%2&f[7gW]!AB4S<](gIWfXB?s$8u69?tS,TSAhs3r#$)'C=\2a0]+<Es'MF*`FpH'k8&
+YI;0ac.(P/lgsEAs*k.N^OO#krs`m5HZq?*s8R"(HZq?*rVlqK;I]D#/FIG+s8VS.IJs32D1VM:
+?H_cE5C`Y(pA<RW>'p;@(o6cgIfTNC*,C%B7A0VZ%+7/es8V'YIJs32D1V]d%)6L[YlFNQ?H_cE
+5C`M/!T!hUrse]BCO^7kT`>&G:8H_Hr;QfS!<3!/rUfg\g5B^Zn8WmTs6=HPrr3\IBj.b@qh[[_
+Ir@cKs5j<"GB6BPp&G$B!-@b6!Qs9tec=uds/uA1qt9OKm-<cqjPo.Vhu)==hr*JRjQ>^mmI9iJ
+JcC<$JcDDCrmh*ks7Y"HPQ9m28q6~>
+ZMspkh>dM)"96,c^\.U9C-?of0oQ)3C-?of0oQ#1#_,`Uqu=ojIuF:*/FIG+s8VY2IJs32D1V`)
+C1)1!1P>`-jJI9FKBE46LJDo7?3pT*R*u$&IkCX!!FpKUrs.ZdIJs32D1V]d%)6LWWr;t8C1)1!
+1P>N'!T!hUrsndjdf8`b/cYEOF8+Agqu-Nqh>mKR%HOC5HaWG8F++#el>;+OrtN4^<iZ,qa0k.2
+mXHhgiW,Y>mYEUjs8LjTK_)kXf&lqf!:GF<JcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+k5Ra@n)rW]dE08:Z`BmlQ&UNIGAh/'=].jZ4>\W:0\QK[+V,8++t56+5=\IK?"@bmH\.-&R@pL^
+\%]l,e_K6Oo]lJVIfo_cJ%taX&,uNC5'_9+MuW`k5'_9+MuN__rI7aMqu=rkIuF:*/F@;(s8VY1
+I/O$0D1_f*Ch%[)15#W,jJR?GJ`Zq3LJ`2>>mUK'RF;'&JM-s%!rZPQrr3er!.=_El>;.Qs8K`H
+=0)<"_e`h,CGLP<rrLjSrr3N%RF;'&JM-uoATRIp!;ZTmrrLjSr;S)(VgE`ro($gKr;Z&!K)blM
+^1gZLrVFRCkPak#0)sl1U@7Q*0_PJFgAlis[K4b8rS%>>JcDhO$N9elnaGl2lKIEor8n=KkiqC!
+mdTlErIP!"s+13As8LaRK)bQ!"I]>VRSA;~>
+k5Ra@n)rW]dE08:Z`BmlQ&UNIGAh/'=].jZ4>\W:0\QK[+V,8++t56+5=\IK?"@bmH\.-#R@pL^
+\%]l,e_K6Oo]lJVIfo_cJ%t[V%;J%QG;5$Us(X]DG;5$Srs4*P>5S?EIt*CTs"*SVJ,fQ>F++#e
+l>;+P_eNS%C,:MBs5^&(F+`WTs+a?jG?tRTpR'D/mXHherrHVVrr35c!.FhGl>;+OrsZYV<iZ,u
+_eNS%C,:M<rrLsVrr3K&R*u$&IkC]l@WV:t!;l`p!T!hSrse%dH[E0knoK6Xs6=HPrr3\IBi_84
+qo?,.s6b@gs5F$Omd>lcp&G$B!-@b6!Qs9tec=uds/c5-rV?'Tn*TH+ki_.,jpC57l0@X'nFZPT
+JcC<$JcD>Armh*ks7Y"HPQ9m28q6~>
+ZMspkh>dM)!rmb"o`#@;HhZu43WK*rHhZu43W/m^V$QhqS,`O+rVmi)Dh%fepNLu]s5n*Ls6bsl
+$r0EMs8U2A6#5rgrrq7G!#UA#qu6]:#lXc(+hdmT#O_Y>qu>eoKDkfXdT1kps6bsl$r0EMq>UKP
+!;ZX$`X)V-&B=Iq!;HHl!T!hSrsd(N6*9n]pNLu]s5n*LrVluJ<e(#Drs?[Ns5sCNs8U@Mp&G$J
+!/0sW!S6E3h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+k5RaAn*&]_dE9><Z`L!oQB$`MG]@G,>#S*`4Z4rRfDj_\',;E-,qLi55tFgR?=n%rI"R?*R\?[a
+\%fr.e_T<Qp$2SWIffY"J+imQrVIR_oBT[Es8*daoBT[Er;R#!%/9dn!!!l7ru:?BJ,fQAFa<f_
+kA>qQmueq-:J$?As2nD0D<q3$"lD`O*.eb!rrL.Grr3&s+M.RP#O;A8q>]VpL&M#ZdTM.us6l*r
+&5PlQq>UKM!;ZX%`sD_.'Z9Ok!;$*errLjSr;R5K=$j"]s7LM[q>]VpL&M#RdTM.uqu6uC#liob
+n,NF2#ke5sgAlis[K4b8rS%>>JcD_L#6"AkoC;>=rpC*[mdBQ5nacGNrdk*#s+13>s8LaRK)bQ!
+"I]>VRSA;~>
+k5RaAn*&]_dE9><Z`L!oQB$`MG]@G,>#S*`4Z4rRfDj_\',;E-,qLi55tFgR?=n%rI"R?'R\?[a
+\%fr.e_T<Qp$2SWIffY"J+WaM(jl#G=ulW_(jl#G=ulN\#Gh_#s-s&h)#aIRmVdUTs7^_aqu>eo
+KE(A$+Uh+<L]@Cr<^CNirr3/Y63%jU&GuJ.`X)PC!?o/Urs.umHi*j*CP2Tc$dr(*qu?)G+Uh+<
+L\^rNh>mBO$-!8Nk7GZ-ec>ICrrLsVr;R5J<^Ek^s7^_aqu>eoKDkfPdT1kpqu6uB#lj&fn,NF5
+#ke5sec9d_XT?T$rRLu6JcD_L#6"AkoC;>=rpC*[mdBQ5nacGNrdk*#s+13>s8LRMF8tsb"I&oL
+PY-H~>
+ZMspjh>dG'p&>Zrk5b8Vs4.2Mk5b8Vs4.2Mmn3TZ!<D<XrrVV,J,]H]LMPoLc"<@Cmcs]Lc#99T
+YtgDPr;R&Zp](8`6N>?$rr3#=&H;\1XWdWB((b9@s35/CpRJ&Zs*o+]s6f1Ls35JTq>UKP!<3!!
+cCFn6"3(oP^&%d0N;ihXh>mNS"0kU_oDS\$LMPoLc"<@;S>?2bIrk5D[E\^N$-!PVrs7ffs2GWC
+s8LjTK_)kXf&lqf!:GF<JcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+k5RaBnEJocd`]P@[&p3sQ]R#SH#d\2>ZFNh5WV0^s5Z0Z)]^%H.PNbD6q^E\?tXD$I>*W/S"cme
+\A6/2f&#NTpZheWJ+`gXn`'WDs8UONs5O+Rs8UONs6E8Rs8)fVq#:E_D1DQb'8^M`s3>>Hs6o:N
+s3>VYs0>I^nbiCmhtR0NSji\*T)S`j`t\OQ!NmRCrtZ;aiW%2;RJ!#CrV_.anc/(Dqu=r]UA=fi
+gAq6Q!RIA:rr^:Us1\@1!07'Y!S[VQrr]Q'O7E2K&W(;^s3>>HopVWRrI&\UkI/\8rs?^[s8NMj
+s8U+Np&G$G!.sgN!RTm*gApVls/,hrrX/W%qtg*`qYU3hrdk*#s+13:s8LaRK)bQ!"I]>VRSA;~>
+k5RaBnEJocd`]P@[&p3sQ]R#SH#d\2>ZFNh5WV0^s5Z0Z)]^%H.PNbD6q^E\?tXD$I>*W,S"cme
+\A6/2f&#NTpZheWJ+`gSoB-,Js8UXMs5sCVs8UXMs6iSZrrE,_q#:E`Dh%cd'8LA_s35/Cs6f1L
+s35JTs05=\oDJUohY7'MS3m8$SGrNh`Xr.L!NdOCrtZ/]ir@88R.m,Hs8RRioDe7Dqu=oZT_\Tg
+h>mQT!R@57rr^7Ps1S:0!0$pW!T!hTrr]N$ORrGN&Vk/]s35/CpRJ&Zs*o+]k-`J5rs?[Vs8NAf
+s8U(Mp&G$B!-@b6!Qs9tec=uds/,hrrX/W%qtg*`qYU3hrdk*#s+13:s8LRMF8tsb"I&oLPY-H~>
+ZMspjh>[P+!.XS>'GtoShGQ]?rtoh?hGQ]?rt(F`N#;<h!q'uVrr3VA>+G&;?HN5;:9!)kB%lNc
+A'Y&(s8NNgA+.\[[K"eXPjd0`F8l1?;KMd9)KT)Pmtb;ls+aLg]i'dgs-ui`hK*;_s38[_rVloT
+!<3!&ec:s'ei@gLrrLsVr;QfS!<3!#l>'nTrmi4Ws1)='mtb;ls+aLg]i'dgl>'#.n('L?s8QS$
+hVL8.p&G$J!/0sW!S6E3h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+k5RaCn`o,ge',bD[]ZO$R$!8YHZX+:?W^/t6qQ#1kXHjC,:"We0/YgW7o!&g@VTn-Itiu5S><3k
+]"uJ7fAG`Yq<It]IfOujrtkY2*-(0!<C-Z^*-(0!<C-Z^&<cL>)#O+.!psiSrr3VB>FOr7?crD>
+:oN,iB@uH_A'b,*s8NNjAa@MZZN&MZQLEEbFoMCA;/uO6)Kf8Qm>#&krIn+a]MXOas.)ubgN.#[
+s3/LYrVloQ!<3!&f*%E.f/RpNrrLjSr;QfP!<3!#l"OYRrmr:Ys12F'm>#&krIn+a]MXOalYTA5
+n(0OAs8QY)hqL,)p&G$G!.sgN!RTm*gApVls+13$s+13$s0)J%gAup+p=f_=!:-(JJ,~>
+k5RaCn`o,ge',bD[]ZO$R$!8YHZX+:?W^/t6qQ#1kXHjC,:"We0/YgW7o!&g@VTn-Itiu3S><3k
+]"uJ7fAG`Yq<It]IfOuhrtH;kkMB*'s8NpWkMB*'s8NXpmu/+XrrVV,J,]H\\QYNlLgJ4'S5-'?
+F(X.kCLbZgf)PaZ3FhO'(q'Cp!0ls'3HP3"!E+":ru,r^SF;8?ao@,o_7`a)s8STaWSV].gAfF>
+qu-Nqh>mQT#1`d=n('L?r;QfS!;uith>mQT"6sZ3cMlB;lMnCuSF;8?ao@,o_7`a)s6=Al_=,r8
+F8u8M9&ADbC\@`,ec9d_XT?T$rRLu6JcC<$JcC<$JcDqRrmh*ks7Y"HPQ9m28q6~>
+ZMspjh>dM)nc'<S63%9hkPtS563%9hkPtRi+TNt2p\t<_Dh%cd&GrRe#X,`us6bdb$sLpUbte-9
+s8N5Y3<0ndrr3,/.0'p+rVlm([J^%CpT6:Y4h:Umg1q66GN/Z&mY`%n>0[*IIrFcRrrLsVrVm#.
+.0'p+qu6]R!;uith>mQT!R4C;!#L.bqlM^]4h:Umg1q66GN/Z&g2@Z*&:=EV"nu1+#]'2-s8LjT
+K_)kXf&lqf!:GF<JcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+k5RaDo'>Ale]l+K\$2j+RZi\aIWoaF@Tui-9@j.@MeQj:AnYjn6TRJ$92\l!AScF6JVfJ>Su&Qr
+]>D_<g#2&^qs+4]J+<OQf0ofN;<RuZf0ofN;<RuZ[NGQ$a7oT8m;7@Prt,(/2@Mj^s8VPI+:qc$
+s3+47!<<'%h`M#]Rf<<oZ7GtiH2IXAqZsM*ru1X52@Mj^s8Ueg&/KQOs8VPI+:qc$s8RRcmJ[%c
+gAq3P"gTZZ'RBTRrrLjSr;QfP!<3!!bYA!8+FjFgX>UJP])VfaCCh8,j8]/3D\`<eH2IXAo2u>-
+C%q<#rn@F)o<n\Hj8I^4m=G:gs+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+k5RaDo'>Ale]l+K\$2j+RZi\aIWoaF@Tui-9@j.@MeQj:AnYjn6TRJ$92\l!AScF6JVfJ;Su&Qr
+]>D_<g#2&^qs+4]J+<OQej9?B;Wn)[ej9?B;Wn)[[35N!`qTK7mVdUSrt,(02$c@Us8VMF*"6#q
+s34=9!<<'%hDkQQSGrNk[4)(eHi<sF#dsU1)Y^?k#X,`us4V6"'R/R:s6bdb$sLpUs*ntTrVloT
+!<)p#[4)(eHi*gDh>mKR!T!hUrrLA>qu@O_s8/oU#X,`us4V6"'R/R:s4VB*!"aMVrrr.##RG5?
+p&G$B!-@b6!Qs9tec=uds+13$s+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMspjJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+k5Q=so^(\rf$DFR\[&93SX,=mJU2BRAm\\><qcP5Cd:E]:f^h1BlJ6DKSu"GTVo!%]u8.Dg>_Ad
+rIP!3s8LaQK(HDOd,Y)Z!:>@;JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+k5Q=so^(\rf$DFR\[&93SX,=mJU2BRAm\\><qcP5Cd:E]:f^h1BlJ6DKSu"DTVo!%]u8.Dg>_Ad
+rIP!3s8LRLF7ZL7b23*J!:#.8JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMspiJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+k5QM%p?q,%f[7jZ]X4f<T9te"KRJ&`C1COO=OY[Ecd2R8s3DWq7S?QX>@D/]F*`CmNg5<nWj0(K
+`m3,ij6Q;fs,m?\gAlis[K4b8rS%>>JcC<$JcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+k5QM%p?q,%f[7jZ]X4f<T9te"KRJ&`C1COO=OY[Ecd2R8s3DWq7S?QX>@D/]F*`CmNg53kWj0(K
+`m3,ij6Q;fs,m?\ec9d_XT?T$rRLu6JcC<$JcC<$JcDqRrmh*ks7Y"HPQ9m28q6~>
+ZMspiJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jo7R>nEJree',eF\$2j+S<]+iJU;KVBOY7L;bp%W770C.6UXC89i4no?tF+nGCG4'P*h'&XgG^W
+ajAYrk3_qps,m?\gAlis[K4b8rS%>>JcC<$JcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+jo7R>nEJree',eF\$2j+S<]+iJU;KVBOY7L;bp%W770C.6UXC89i4no?tF+nGCG4'P*gs#XgG^W
+ajAYrk3_qps,m?\ec9d_XT?T$rRLu6JcC<$JcC<$JcDqRrmh*ks7Y"HPQ9m28q6~>
+ZMsphJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jo6D!o'>Amf$DFR]!JK8T9te"Kn"AhD.mEc=]J?q9hYIX*DB4)<**=4ASZ7.I"I08Q(3c3Yd_?c
+bgY;)kjSG#s,m?\gAlis[K4b8rS%>>JcC<$JcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+jo6D!o'>Amf$DFR]!JK8T9te"Kn"AhD.mEc=]J?q9hYIX*DB4)<**=4ASZ7.I"I08Q(3Z0Yd_?c
+bgY;)kjSG#s,m?\ec9d_XT?T$rRLu6JcC<$JcC<$JcDqRrmh*ks7Y"HPQ9m28q6~>
+ZMsphJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jo6D#p$V#$g!\'^]sb/EUR[X3MM-G'F)G]&?sHi8<)`co*)fj=>$bZMCN+ECJVT5KR@oSBZb!uo
+cdgh2lLKN+OT5=7!.sgN!RTm*gApVls+13$s+13$s0)J%gAup+p=f_=!:-(JJ,~>
+jo6D#p$V#$g!\'^]sb/EUR[X3MM-G'F)G]&?sHi8<)`co*)fj=>$bZMCN+ECJVT5KR@oJ?Zb!uo
+cdgh2lLKN+OT5=2!-@b6!Qs9tec=uds+13$s+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsphJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jSqC<n`o/ie]u4O]!ST;Tph4+M1^8%F)Pi,@piVJ>$5!3>?kNEASH"$G'eaoN00HuUlqsk^;S4C
+g#(rZpOW@+s8LaQK(HDOd,Y)Z!:>@;JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+jSqC<n`o/ie]u4O]!ST;Tph4+M1^8%F)Pi,@piVJ>$5!3>?kNEASH"$G'eaoN00HuUlM[g^;S4C
+g#(rZpOW@+s8LRLF7ZL7b23*J!:#.8JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMspgJcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+jSp7uo^1euf[@s]^::GKV4X0>Nei=:H?F4EC1h*f@fBdU@Us(bCi=B=I"@$1Od;N3W0Oa%_8spP
+guIYgrIP!1s8LaQK(HDOd,Y)Z!:>@;JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+jSp7uo^1euf[@s]^::GKV4X0>Nei=:H?F4EC1h*f@fBdU@Us(bCi=B=I"@$1Od;N3W04O"_8spP
+guIYgrIP!1s8LRLF7ZL7b23*J!:#.8JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMspfJcCH(rn[X.o=Y1Uk5F-:maD+:IrFcErrVWF!;QQp!8`;,JcC<$JcC<$!<<&T!JLLHh?9>K
+n!m.'~>
+j8U+nnEJuge^)=R]XG#CUn4!<NerF>I!BaQDf'9)rb3<dCi435G'\UhLQ%@]S"Za^RCU)ObgP2%
+k3_nos,[3ZgAlis[K4b8rS%>>df0AuD=-im!q"_Bq#:?pgO]BUs+13$s+11Ms8LaRK)bQ!"I]>V
+RSA;~>
+j8U+nnEJuge^)=R]XG#CUn4!<NerF>I!BaQDf'9)rb3<dCi435G'\UhLQ%@]S"Za^QFXcLbgP2%
+k3_nos,[3Zec9d_XT?T$rRLu6df0AuDsm,p!q+nFq#:?phLY]Xs+13$s+11Ms8LRMF8tsb"I&oL
+PY-H~>
+ZMspfJcCH(rn[X.o=Y1Uk5F-:maD+:IrFcErrVWF!;QQp!8blu"kH!?#ZC,Bs+13$s+13`s8LjU
+K`Cc&"IoJ\S5+S~>
+j8U(ro^1f!g!e3c^q-nUWM?&QP`L`WJq&/nG'%d'E>rq>Fa&.[JV8l>P*VW3VQ@%n]u/">f%oBO
+nG\"=O8o46!.sgN!RTm*gApWhrrR[emI:,WmFqX9rrE,Sb5VXs5m.Hnl[f(es+13$s1SI3gAup+
+p=f_=!:-(JJ,~>
+j8U(ro^1f!g!e3c^q-nUWM?&QP`L`WJq&/nG'%d'E>rq>Fa&.[JV8l>P*VW3VQ@%j]u/">f%oBO
+nG\"=O8o41!-@b6!Qs9tec>!`rrR[gmdU5XmbRs=rrE,Vb5VXr63%9hmt(Lis+13$s1SI3ecBjl
+p=9A2!9]S=J,~>
+ZMspeJcCH(rn[X.o=Y1Uk5F-:maD+:IrFcErrVWF!;QQp!8blu"W1G+hF^Cks+13$s+13`s8LjU
+K`Cc&"IoJ\S5+S~>
+ir;%5n`o2kf?qd\^U^_SWMH/TQ'%&_L4b#*I!U'`G^4U^I=Hg$Ll7=XR%0kIX0K+,_T:$Pg>V5_
+q18R+s8LaQK(HDOd,Y)Z!:A57!e5(SnG`RWgAq$K!<Cltrs&???0C*:8V-nms+13$s1SI3gAup+
+p=f_=!:-(JJ,~>
+ir;%5n`o2kf?qd\^U^_SWMH/TQ'%&_L4b#*I!U'`G^4U^I=Hg$Ll7=XR%0kIX0K+(_T:$Pg>V5_
+q18R+s8LRLF7ZL7b23*J!:&#4!e5.VnG`RXh>m?N!<D!!rrj6CkMAg'JcC<$JcC<$^&S)_!H\;7
+ec_3;kEJSh~>
+ZMspeJcCH(rn[X.o=Y1Uk5F-Um_)$p+cu-lpRj)D&8V%?rrB/EN;rW^&-u2&qu8^R+TN@Ls8Tc$
+#U,;ts*mdQ(_gW6s8/oY$n\.Hs1qG='OI"(s8REW!(,QBrrAQ<#U->Ms.pk=(l\Io('(Hk(_C?2
+s2@kE(i*$!s8/oY$n\.Hr;QidDh%Q^#1`eCs8U@EJcC<$JcC<$^&S)g!JLLHh?9>Kn!m.'~>
+ir;":p$V&'gt'ip`4idhY,S7jS=#P&NJ`LFK7\Z)J:W9(KSG>AO-5ftSt`-aZ*q<Aa3E)dhrX1q
+JcC`0rn@F)o<n\Hj8I^OlafOo,`qEnpS'8G&8Cn=rrB&AMZ<E^&-u;)qu8^S,QJgQs8BMu$m^r%
+s*maO(_gQ2s8/r[$ne:Ks2%VC'O?k%s8.'U"@_)FrrAK9#U$/Is.UV9(lJ=m('(Ko*"li4s2J%M
+)J`9$s8/r[$ne:Kr;QicD1D?\#1ES<s8UCJJcC<$JcC<$^&S)d!J:@FgB<rFl^COu~>
+ir;":p$V&'gt'ip`4idhY,S7jS=#P&NJ`LFK7\Z)J:W9(KSG>AO-5ftSt`-aZ*q<=a3E)dhrX1q
+JcC`0rmh'jo;r&9hYl"ElFfUl+cu-lpRj)D&8V%?rrB/EN;rW^&-u2&qu8^R+TN@Ls8Tc$#U,;t
+s*mdQ(_gW6s8/oY$n\.Hs1qG='OI"(s8REW!(,QBrrAQ<#U->Ms.pk=(l\Io('(Hk(_C?2s2@kE
+(i*$!s8/oY$n\.Hr;QidDh%Q^#1`eCs8U@EJcC<$JcC<$^&S)_!H\;7ec_3;kEJSh~>
+ZMspdJcCH(rn[X.o=Y1Uk5F-UYuZA6Ue.*VW(r`ChD'*Orr=d]n,HQhkMAg'r;Tdc!3Q"'!:RI!
+J)[7qSH"'YORp:\L]=GVSDoc*Uqof<dai.M!<7^$f'cd&s8N'ZkPp2Hs6fr/pUpRqs8N'chX8'G
+LWNS3g>6l^J,cTNSDoc*V#:5oqoR+XrrMlNrr3"h.=qMMs+13$s1SI3h>r<0p>,qB!:QFQJ,~>
+iVshmoBbVtg==Nk`4idhYH+OpSsu(2OcPK[MM_=g)2X60Nf]HjR@KqGW3*A7]YUVldb*C9lL=\%
+s,I'XgAlis[K4b8rS&9o=+T>)8=TXX9pXho0QmEq!&V.Ms'8XbhapE;s&JLjY4K(%n$lGMiM&l4
+s*l#Jn%_SOs/oLpiKQp0_G=gmenlB,s+2fRlWH4Irr>%=qh>[^mf7M%\cD'rrr>@BmCYoDaB*62
+gN+!Ws/oLpiKQp0r;Qio`m"5X!Vb@JrrJQ>JcC<$JcC<$^&S)d!J:@FgB<rFl^COu~>
+iVshmoBbVtg==Nk`4idhYH+OpSsu(2OcPK[MM_=g)2X60Nf]HjR@KqGW3*A7]YUMidb*C9lL=\%
+s,I'Xec9d_XT?T$rRMpi<e',)8Y#gZ:715$0m!Bp!&:nMs&r=`hF^E<s&JLfXnT4'n$uJKihT/9
+s*l#Mo>+%Ss/]7kifm'2_+nUjenQ$%s+DiPmohaOrr>(Bs+Cs`mf7G']`@O$rr>CBm_)&Ea]<01
+hK'6Xs/]7kifm'2r;Qiqaj'V\!VbIMrrJW=JcC<$JcC<$^&S)_!H\;7ec_3;kEJSh~>
+ZMspcJcCH(rn[X.o=Y1Uk5F-VIr!d<o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpUn,<8emf93Ys7cPT
+CYJg[_9N"0?Jb_MDh%Y2GPD.*Dg-h?df9?uXT8AE[K$9iSH&Th^&S,h!<<)Mp]&eEhZ*TU^&S-#
+Dh!j]f)Pd$<e(!nGPD.*Dg1sDrr__:(s[^4JcC<$JcEF`rn[[/s7Y:PS,i#J:4N~>
+i;XYgna#;og=4Hj`4rmkZ)t"%Tq7aAQB[SqrK%kYP*;/tR[p+HVlR#-\@oc"YL1tXiooh+JcC]/
+rn@F)o<n\Hj8I^PI;@R:o>&TGH#;sKs0`pIrrBM-s7ZZ^s8UsVn,<8emf]BZs7?8OCYJg[^s)h.
+?f(hMD1DG2GP2")Dg-nDdf9?sWW<&A[f?BjRfEBf^An5f!<;rJp]&\Bg].9R^An6#D1@[^f)Pd$
+=+C*qGP2")Dg1sDrr__8(s@L1JcC<$JcEF`rn@I*s7Y1MRK2ZB9n3~>
+i;XYgna#;og=4Hj`4rmkZ)t"%Tq7aAQB[SqrK%kYP*;/tR[p+HVlR#-\@oc"X3oPTiooh+JcC]/
+rmh'jo;r&9hYl"FHY_@8o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpUn,<8emf93Ys7cPTCYJg[_9N"0
+?Jb_MDh%Y2GPD.*Dg-h?df9?uXT8AE[K$9iSH&Th^&S,h!<<)Mp]&eEhZ*TU^&S-#Dh!j]f)Pd$
+<e(!nGPD.*Dg1sDrr__:(s[^4JcC<$JcEF`rmh*ks7Y"HPQ9m28q6~>
+ZMspbJcCH(rn[X.o=Y1Uk5F-<DenY:rrVV,J,]HRec>aM!8dbUhYR9Qf)5OR]h/hr[Jt_llMUYf
+IrFcTmVdUCDu9V7CC'5*s6A/8rrCXIru_<us8UpUs8T2U0iA#.s8N)Us8VM*It)8!s8VA"J*q7Q
+!!-m#n,EKS(i/Sks+13$s+13_s8LjUK`Cc&"IoJ\S5+S~>
+i;XYnp@.A.hq?N*b/M0/\$N9>W265]St)7;rKnChR[]k?TqnTdY-GCG^;J"8[+F*mkO%tos,6pV
+gAlis[K4b8rS%BjC[:s!%e"=arVuoL!<<'!g].<2qZ$WJr;R&:9b9:is*nhMr;R%PD=.AjD1D"m
+quH_3#j_Njldl.:!8%,J+9:0rs4[PRs/In0<<1eRrrCgRs6XZQIr"BMs6FHMmr/+(!Gh#irr\Q(
+D<lcQJcC<$JcEC_rn@I*s7Y1MRK2ZB9n3~>
+i;XYnp@.A.hq?N*b/M0/\$N9>W265]St)7;rKnChR[]k?TqnTdY-GCG^;J"8Yh.[ikO%tos,6pV
+ec9d_XT?T$rRV!a!:'O_!q'uVrr38T!<<'!hZ*W4qZ$WIr;R&98e="js*nhLr;R%PDsmYnDh%1n
+quH_3#jVHilIGt8!7q&I+9:9us5!bUs/e"1;?5SRrrCpUs6afTIr"?Ls6=BLmVi"'!Gguhrr\K&
+C[ZiSJcC<$JcEC_rmh*ks7Y"HPQ9m28q6~>
+ZMspbJcCH(rn[X.o=Y1Uk5F-UHY2"3o;T.pHZ/?Ps0W^DrrCpUs7ZNfs8Vi=r;Tdk`rH(H!:PPP
+gAgcD[Jt_pmf2]nJ,=S>qu?QQk)3^"s8UZP!<3nDs8V7ts8N)Us8UpUs6fs5s8N)Us8N)Us8VM*
+Iu@des8UYNJ,=S>qu?QQk3r<O@l`_'s+13$s+13]s8LjUK`Cc&"IoJ\S5+S~>
+hu=Mkp$_2,hqHW-bJqE5]!erKXK&1pUS=I[TG=/qUo()kY-G@D]YMJ-c-j,Wiof_$JcCW-rn@F)
+o<n\Hj8I^OH"Yk2o;]7pH#;sKs0`dErrCgRs766^s8Vi>r;Tdka8c1F!:PPQgAgcE[f:homJlQj
+J,+A8q>^?PkDa!$s8UTK!<3nEs8V8!s8N)Rs8UgRs6g*6s8N)Rs8N)Rs8VJ'Iu@gfs8UYOJ,+A8
+q>^?PkO8EPAN]"(s+13$s+13]s8LaRK)bQ!"I]>VRSA;~>
+hu=Mkp$_2,hqHW-bJqE5]!erKXK&1pUS=I[TG=/qUo()kY-G@D]YMJ-c-iuSiof_$JcCW-rmh'j
+o;r&9hYl"EG@oS/o;T.pHZ/?Ps0W^DrrCpUs7ZNfs8Vi=r;Tdk`rH(H!:PPPgAgcD[Jt_pmf2]n
+J,=S>qu?QQk)3^"s8UZP!<3nDs8V7ts8N)Us8UpUs6fs5s8N)Us8N)Us8VM*Iu@des8UYNJ,=S>
+qu?QQk3r<O@l`_'s+13$s+13]s8LRMF8tsb"I&oLPY-H~>
+ZMspabPr%&63mipkPtS563mipkPY>\`W5`4s+gUR*W)rr$phH(s7`0<$phH(s6>Od":.oos8VOc
+#S;(Vrr@EE!!76ASGN:&hZ*>P2%2d]s8V)&'GPWFs8Vhd/IXqUp\t4)rVlkEr;Zh=rr3@Z&-u2.
+s8VOc#S;(VrtY:$/IXqUs8VAC,mZ)moDdfo'GPWFqu6X-rVm#p@gEWeo`+pI!/0sW!S6E3h@cbb
+KAr[uSH#BWR-3<\F8u7?hZ!O_;Hi8H=ulW_SG3'X#efu7!;Em!KAr[uSH"(Wmf2]nJ,cHJT]_t>
+SA@s4dai=[!<7*pf'cd&s8N)Us8UpUs6fs5s+CC's8N)Us8VM*J&+luhVNGjJ,cHJT]_t>SG`Bg
+qoR+XrrUaO`r4J>s+13$s+13`s8LjUK`Cc&"IoJ\S5+S~>
+hZ"Dip$_2-i7li1c,mo?]t1YZZ*1:1WMlcpV\Z51WiWA-ZF.3S^Ve+8cd^U\iof_#rm:ZSf0orR
+<TjD^f0orR<Tj;[!Q+p3rrW.SM>mMuqlDU_6G!3soq3oG5dpXkl\m"l#Z^3js6EYj&97UIs*=PC
+!d4O7qZ%Jfs7`TO$pqQ*s5S;=(3A@4s7N$;$p_9"q>UKm'`J%3H2R^CFoMCdJeSJjoDejV<<s.U
+qu-QfTIpX<[f-6lN[>)eT(E!BG8:s8hYmHUrVI<-rri()#S;.Ns8LaQK(HDOd,Y)Z&u\]\iM&l4
+s/&GTj4c81s8N)Rrr6A+=l\[N4TGGMoDeCf^@S?-o<_DJiM&l4s*nnQs6XZQs/K.lje>G>_G=gm
+eo)Z2s)g$IlWH4IrrCgRs4[PRlN#9.L&f^&rrCgRs6XZQ_GP7+h00Q_s/K.lje>G>r;Qio`m"5X
+!n..irRZW#JcC<$JcEF`rn@I*s7Y1MRK2ZB9n3~>
+hZ"Dip$_2-i7li1c,mo?]t1YZZ*1:1WMlcpV\Z51WiWA-ZF.3S^Ve+8cd^UXiof_#rm:ZSej9WJ
+;Wn)[ej9WJ;WmuX!QG-5s8RlRruM!=2%2d]s8Vhd/IXqUs8VAC+Tr'Kn,NFV;@!hTrr2tFr;Zn?
+s.&rd(Z,2dXYgMQ\c;]hG8(a4hZ*WMTIgR<\bH+(&H2V/Hi3pEF8l1IKFeDep](9^;@!hTrr3`-
+TIgR<\c;]pN$S`]SFcd?G8(a4hY[<Q&H2V3pL=I?F7fM3ec9d_XT?T$rRMUW;M3u)8Y#gV8sneu
+0m!Bp!8d_T?rC1kk?9nGs.&i`pB\J,XT8+';M3u)8Y#g1DsmYnDh%ec<hSWK8Y!UlB%#7K+TVO`
+1"Pes3WK*ZhZ*W4!<;KfcMrOtf)PaMhZ*WDDh#SuDr0>p'S$.]<hSWK8Y#_Y!rL*aq#:EH!64ug
+JcC<$JcC<$^&S)_!H\;7ec_3;kEJSh~>
+ZMsp`hZ!S*q#CDEq#:dHF6DC`6N@'/F6DC`6N-ock843prri)AHR41@s!"jGLXpZQaoA#+SDJm)
+`W(iVT]4g#9)noX;WlUcN;roUF8j_ln,N.\ef&m%s8Qk0LXpZQao@8o\\1ans8S`aSDJm)`Vf`=
+pWfm5!<)ou;KMig0CSr@N%roH6>QW$6;m!t0oX*OTLta2K3lOsO@lY7S5,aWMb^gr:5AlLpWe+X
+!<)p$CGF\k+dD["rn[X.o=Y1Uk5F-Lm^51`+cu-lpRj)D#]'27rrCpTs'Y;!#RF&cs8N)Us8ST+
+!$SKEs0Xuq+cu-lIrFcTmVdUTpS9ML.@B`,_+kCUCS_%2s(`/G6JhbB!8dbUh>mTUHO(1A64!Vk
+!8dbUmVdUT`DR*]CJoZ^pS9ML.@B`)rrVV,J,'$DSGN;;s+13$s+13`s8LjUK`Cc&"IoJ\S5+S~>
+h>\5fp$_2-iS<&6ccaAI_7mOk[^<?FYl1a?Yd(L?[C<`[^V\"4c-b(qhSSLDoDR\K!.XeE!.XkF
+&,lAJFm%Xb63$g)Fm%Xb62gfbk843prri)AHR++?s!"mJLXgTQb5\21T&56/`;PTVU>t-&8cSfZ
+<ThsjMZ<]VEW4Pkli6STf,Ap's8Qq4LXgTQb5[Gs\@tgqrVrTdT&56/`;KW<pWfp5!<)ou<H8#i
+0C/Z<N\K)F6#HZ%79/O&1lB6OU.q6:KjVdsNCpA6S5#[VNDI'u;2>,MpWe+W!<)p$D)C"n+I;^#
+rn@F)o<n\Hj8I^Fla/h_,a.Wroq!]?$u,J9rrCgQs'Y:u$j]Sjs8N)Rs8SZ-!$nTErNn`q,a.Wr
+Ir4TQm;7@QpS9PO.[ou/^eG4SCSh+3qeZlI7Gn.F!8IPRgAq9RI0^OI71B4r!8IPRm;7@Q`)@-a
+D,l/epS9PO.[ou,rrVS)J,'$DRem)9s+13$s+13`s8LaRK)bQ!"I]>VRSA;~>
+h>\5fp$_2-iS<&6ccaAI_7mOk[^<?FYl1a?Yd(L?[C<`[^V\"4c-b(qhS/4@oDR\K!.XeE!.XeD%
+3]fUhHE8GrulIHhHE8ErrV@#!;ZWtpWe+3J,]Hl[8)M.G?W,gTLta2K3lOsM`IHihF^E?s$BWHe
+hN-`s&*q;ecP=?p\iY]HU@c4CJKZ9G?W,gMb^gr:5AlLTLta2K3lOprri)AX\&TlrrH#=rmiaks
+8S$4f&oA8s8PD`kLMAH`W)T'SDJm)`W)#lXl>jGT`9pF\\1ans8Vi=HV+;:rrm0mhTd:/p&G$B!
+-@b6!Qs9tee78U4U<3mmf3$S/I2Vtp](6nhZ!O_mofu&9'?6S!8dbUS/;5LXoJF/4U<3mmf.cTm
+f2]nJ,f8=0aK4qoDcX%$lEcV!<<(7&-,&Rs8N)Us8UpUs8REO&<&p]s8N)Us8VM*J,dJc$lEbXJ
+,f8=0aK4qoDJUimVdUMrrASd!.k0$s+13$s1SI3ecBjlp=9A2!9]S=J,~>
+ZMsp_h>dM)rVunIq>Uunh>m<Ms4.2Mh>m<Ms4.2KrrPN&!;ZWtlC;04J,]HlLM#ECa^UY3GB`f]
+icgXPCNoOQs3:WEmf;hVs2HMfs!b)Fru9f<n,ND!B&<R0@[Qb.Hi*hmF7]-MGPD-sGEi%*"R;Le
+=oeO$!@b/Js"#>5s8V9%s6fsVs8U(fPkTBGp]'5sPjWI:qu>qsJ+I`.qu;.eoDe*G?<R@-rritI
+s8S<<p&G$J!/0sW!S6E3h>lu5rs.8slMpn<ArD6?JcC<$JcD;@rn[[/s7Y:PS,i#J:4N~>
+h#A)ep$h;1iniD?da$%W`PTF)]XkY`rO;g:'"PWf^VRk.aj&2^f\GEHaR8d$i;`h,rVunIq>Uuo
+hZ3ENs3guJhZ3ENs3guIrr`-aD#jD3"R2F`/:[[!,DTpgs2no@pNLcQs5A0el"P;5s8UCJs6fsR
+s8Ttfs8OXQqt^72gE>h^rt&i"s2no@o5f9UrI&\UpNLcQs5A0er;QoaS7Ph'rVlpMY5A.s/0Mk1
+s6%H&mf;\Rs2-CQpNLcQs5A0emr*RMs646Io5f9UrI&\Us66%\=TJF#"VAEJs->M7s8LaQK(HDO
+d,Y)Z!:?9U#M?oXs8UeeNIh+\s+13$s.02hgAup+p=f_=!:-(JJ,~>
+h#A)ep$h;1iniD?da$%W`PTF)]XkY`rO;g:'"PWf^VRk.aj&2^f\GEH_s[6ti;`h,rVunIq>Uun
+h>m<Ms4.2Mh>m<Ms4.2KrrPN&!;ZWtlC;04J,]HlLM#ECa^UY3GB`f]icgXPCNoOQs3:WEmf;hV
+s2HMfs!b)Fru9f<n,ND!B&<R0@[Qb.Hi*hmF7]-MGPD-sGEi%*"R;Le=oeO$!@b/Js"#>5s8V9%
+s6fsVs8U(fPkTBGp]'5sPjWI:qu>qsJ+I`.qu;.eoDe*G?<R@-rritIs8S<<p&G$B!-@b6!Qs9t
+ec>!)rs.8slMpn<ArD6?JcC<$JcD;@rmh*ks7Y"HPQ9m28q6~>
+ZMsp_h#ID(s8W+KpAYRFK_OqF3WK+&K_OqF3WB$\HW&]#p\u&tDh%feo5f9Us5n*Lo5f-Ms5IO<
+qs*VKrt1bMs5sCNs8U(=s8N?Z!!#pcr;R-bXoJFa!.4VCk%fVJrsR7]MuWBiGPD-s@t4=S!T!hT
+s!A"+!!#pcs6frH&-u2&s5sCNs8U(=J+I`*p]'5_J,bU.^%83uSGiHhdU%k1rrVWF!<3!&k5b8V
+s3:oCs8LjTK_)kXf&lqf!:H?V#JF#blKX""\Ujd3s+13$s.02hh>r<0p>,qB!:QFQJ,~>
+g]%rdp[[_9jP\hHe^Ddfb/_K=_SO%c^Ce8t_o0R9bKeJafA#0AkNgCgh>dM)s8W+Kq#:m'q]LL^
+mpS?Yq]LL^mpS?Xrr[ODgAq!J([Z'hs8V\3H27L%CPDA$GPD-tAV'aCmJd+tROnL%!:Tsf`ruGB
+#W)Ma<U]kc$TtHhs5sB-q>]PlL&V)\rQno.rUY)Sp]'8bJbf<HgAq3P-3uF."BFpjmf84Z#Z^?n
+k5auNs2P7no5f-Ms5R[ArJa[cnYf3Rrr3-"csMY.rr3&egAq6Q#3Q!Xs8U7Np&G$G!.sgN!RTm*
+gApW1rs-8;Ja)?K:q2)VJcC<$JcD;@rn@I*s7Y1MRK2ZB9n3~>
+g]%rdp[[_9jP\hHe^Ddfb/_K=_SO%c^Ce8t_o0R9bKeJafA#0AkNg4bh>dM)s8W+KpAYRFK_OqF
+3WK+&K_OqF3WB$\HW&]#p\u&tDh%feo5f9Us5n*Lo5f-Ms5IO<qs*VKrt1bMs5sCNs8U(=s8N?Z
+!!#pcr;R-bXoJFa!.4VCk%fVJrsR7]MuWBiGPD-s@t4=S!T!hTs!A"+!!#pcs6frH&-u2&s5sCN
+s8U(=J+I`*p]'5_J,bU.^%83uSGiHhdU%k1rrVWF!<3!&k5b8Vs3:oCs8LRLF7ZL7b23*J!:$'R
+#JF#blKX""\Ujd3s+13$s.02hecBjlp=9A2!9]S=J,~>
+ZMsp]g].5%p&>$*rW!',hZ*VhrW!30hZ*V`+nsgnp\trqDh%femVdUTs6afTs-Q6JhM3)#rr3],
+[<ib9s8OfWkLMWns6h\=s5#b6rVlnp3WB$`h>i'*s6afTrr3CV!*7\Ns-Q6JhM3)#q>UKP!<3!G
+mkL[=hDnL6h>gI1hEkEGs"R^?ei<_[s-Q6JhM3)#s5%&^!!IB2rr3(M!*7\LrrVWF!<3!!h>mQT
+!T!hLs8LjTK_)kXf&lqf!:H<U#.[#*$q7T$JcC<$JcC<$ScA]G!JLLHh?9>Kn!m.'~>
+g&EGroC)#.j5A_Gf$i$mc-+8Na2c3>a2c9Cb08/Xdad")hVmS\mIJoas8@H?rrBY0!!ES^s8T\0
+!!ikbs8TMQo@j9>rtOj;J,fQ;Dh%fem;7@QQU[_,LE(gCrtP47Go4a)s"IaAf/Nd1lSPL9h`Op;
+rrJiRrr3el!.Y%Km;7@Qs8@?G<Rh'KQU[_,LE(g>rrLjSrr4V:1oC0-4B;F=!*.q66!=6f0O<kn
+2unI.QU[_,LE(gDgg'm["EEi/s8@?G<Rh!I!q"_Brr3#V!<3!!gAppHrn@F)o<n\Hj8I^4m@4+\
+rO,$"$q.K"JcC<$JcC<$ScA]D!J:@FgB<rFl^COu~>
+g&EGroC)#.j5A_Gf$i$mc-+8Na2c3>a2c9Cb08/Xdad")hVmS\mIJ`\s8@H?rrBb3!!ESas8Te3
+!!ikes8TJMpYGoErtOm>J,fQ:Dh%femVdUTQpm\)LE(gCrtP48HPk'.s"R^?ei<a1mkL[=hDnL4
+rrJrVrr35[!.Y%KmVdUSrsXAW<n@<NQpm\)LE(g>rrLsVrr4A70r=p,3E#n6!)h\16<aEh0j<bk
+3<4R/Qpm\)LE(gDhHg0^"EX#1rr[`N<n@6L!q+nFrr3#U!<3!!h>m6Krmh'jo;r&9hYl"*lC._W
+\NpK07CE#Ds+13$s+13@s8LRMF8tsb"I&oLPY-H~>
+ZMsp]gAh2&o`#gHHhZu43WK*rHhZu43WJ7R`qS$ap]$``!#Y\7)t%Wos8Vh;Hi*j*CP2ZTO<G$-
+8r*HHa]:]Cn,E=jhEh2ZKFn%\!QGEDrrF:Vrr35l!.4VCk%fVJrsR7UJ,B96O<G$-8r*6B!T!hP
+s!#Ggs5sCNs8U@Ms8UqB!#UA#L]?e(+Uh+<L]<9(\auUgSGiHidT1kprr3&fh>mQT#4DQds8U@M
+p&G$J!/0sW!S6E3h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+f`)Q^p[[b;kMtLVgXt*,e'ZOgci23%cd:(fe(*((gu%,Qkj7g5rnH0,s*sbB*<#aSIIlc14TG9u
+IIlc14TFRY_t2=WoD>*Z!#Y\7)sqKls8Vb7H27L'D2&#YOsCT78Vd?Gb#^oHli-nfhaIYfJe7hZ
+!QPKFrrW'?])M^7lMu5+s6"6QrVm8R=b6JMmueq-:J$?;rrLjSq>VYZ#liobn,NF2#ljq^70FT^
+&;U;SOsCT78Vd8&9XsPe9V).^"4C>'qu6TsmFqX?rs%choDej:%/'Z"gAlis[K4b8rS%>>JcC<$
+JcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+f`)Q^p[[b;kMtLVgXt*,e'ZOgci23%cd:(fe(*((gu%,Qkj7g5rmog's*s\@)AmhqmohaOrtp+W
+mohaOk7GZ-ec>IES,`O+rVmi)Dh%fepNLu]s5n*Ls6bsl$r0EMs8U2A6#5rgrrq7G!#UA#qu6]:
+#lXc(+hdmT#O_Y>qu>eoKDkfXdT1kps6bsl$r0EMq>UKP!;ZX=`X)V-!:Tsfc3XIMhEh2ZKFiq=
+mZ8S#:.g<AMb1JNUe.*Trr^\MJ,B6F!q+nFrr32k!;HNnc3X+Crmh'jo;r&9hYl"*l@Jtds+13$
+s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]c2SCIk5b8Vs4.2Mk5b8Vs4.2M^&%d0N;<JTmVdUSrtC0'ir@88R/cU>qu=oZT`;8lORrDM
+#i>=Us-uFUcCFn6!QG]MrrK5Fr;RNDCZ>B=Asi=_V#UIEF7]G"lMLV+DkQq+!T!hUrrLE8rr4If
+&HDb9kPtS%&HDdep](8`6D4AHlMLV+DkQ]CHi*j.COc)KV#UIEF7]D2!q+nFrVm$4`rH(/1%kSG
+h>i6#]`H^HrS@PBJcC<$JcC<$JcDqRrn[[/s7Y:PS,i#J:4N~>
+f)H6Xp@7S9kN1^]hV?i<f[p)Qs47e6g=tH@iT'(bm-jZHs8Uiurt4e]!;HNndff^2!;HNndff]b
+qZ$VVq>UN`D1DQb'8^M`s3>>Hs6o:Ns3>VYs0>I^nbiCmhtR0NSji\*T)S`j`t\OQ!NmRCrtZ;a
+iW%2;RJ!#CrV_.anc/(Dqu=r]UA=figAq6Q!RIA:s!l&'s8NMjs8U+Ns8V!Ns8SZZUAs]Jqu=r]
+U@E5Mqu>nrJb>J+rV_.anc&OimFqX>rrj+Ss8SZIp&G$G!.sgN!RTm*gApVls+13$s+13$s0)J%
+gAup+p=f_=!:-(JJ,~>
+f)H6Xp@7S9kN1^]hV?i<f[p)Qs47e6g=tH@iT'(bm-jZHs8UZprt4kc!;HNnec>a5!;HNnec>``
+qZ$VTq>UNaDh%cd'8LA_s35/Cs6f1Ls35JTs05=\oDJUohY7'MS3m8$SGrNh`Xr.L!NdOCrtZ/]
+ir@88R.m,Hs8RRioDe7Dqu=oZT_\Tgh>mQT!R@57s!l#"s8NAfs8U(Ms8UsMs8STUT`=HFqu=oZ
+T_!5Oqu>qsJ+oJ/s8RRioD\akmbRsBrritRs8STDp&G$B!-@b6!Qs9tec=uds+13$s+13$s0)J%
+ecBjlp=9A2!9]S=J,~>
+ZMsp]bPr"gF6DCX6N@'&F6DCX6N$iah>m<M!q'uVrr3VA>+G&;?HN5;:9!)kB%lNcA'Y&(s8NNg
+A+.\[[K"eXPjd0`F8l1?;KMd9)KT)Pmtb;ls+aLg]i'dgs-ui`hK*;_s38[_rVloT!<3!Nec:s'
+ei@gOs'n[XhDoBOs#FTXc5<tCs-ui`hK*;_s,0=Jig<?2s+aLg]i'derrVWF!<)p$F$fWa.?sN*
+rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+eGfsSp%%S<lK@9iio/hQr8%h=i8N_Wk32-unFlhZrrCfurt#)**-(0!<C-Z^*-(0!<C-Q_!S[VK
+rrVS)J,]H\\m(WjLL84(SPZ9>F(a.iBk,KffDkj[4D!j%*4#Ur"IAN.3-G6#!E!k7ru-#aRdGl;
+b5I#k^q<O$rVrEbW7uB+f`018q>L<ogAq6Q0@p>mn(0OAs8QY)hqL,)s8P2mlcU9Rf`.L=W7uB+
+f_p^tXQ,aBT`'RA^q<O$rVlfumFqX>rrmO2oB.Nfp&G$G!.sgN!RTm*gApVls+13$s+13$s0)J%
+gAup+p=f_=!:-(JJ,~>
+eGfsSp%%S<lK@9iio/hQr8%h=i8N_Wk32-unFlhZrrCWnrs]fdkMB*'s8NpWkMB*'r;QfS!;HKp
+mVdUSrt;kGSF;8?ao@l+WSV].g?NH`cMc>ors^tun'2cXs4.17n('L?rr3!sF8Z%VF'>+&LgJ4'
+LJkt%;N(STS5-'?F(X/+c,ok]rrLsVrr4V%!0ls'3HP6#@nPV73G\Zp3FhO'(q&)tS5-'?F(X/+
+Maac-QqF%OLJkt%;N(MR!q+nFrVm%B6MKXlPkG(Uec9d_XT?T$rRLu6JcC<$JcC<$JcDqRrmh*k
+s7Y"HPQ9m28q6~>
+ZMsp]bPr%&63%9hkPtS563%9hkPY>\h>m<M!q'uVrr3Q,XYgAI\c;]tM]<./c2Z$`qZ-Zr"Pu-=
+(nCU*"LTZY&:=BU!=6+2ru1X62$c@Us8Ueg&/9?Js8VMF*"6#qs8RRemf!.dh>mNS"LTZY&:=EV%
+/3p2#]'27s5#a9(nCU*(%-u"$sLpUs6>Od">-/8s4V6"'R/R8rrVWF!<)p#pL=I7F7fM3h>i6#]
+`H^HrS@PBJcC<$JcC<$JcDqRrn[[/s7Y:PS,i#J:4N~>
+df0[Qq=F.FmHa'$kNDd*$0UO:lKms.o_JI_rrCfsrsdRK":S/js8U\>":S/jr;QfP!;HKpm;7@P
+rt,(/2@Mj^s8VPI+:qc$s3+47!<<'%h`M#]Rf<<oZ7GtiH2IXAqZsM*ru1X52@Mj^s8Ueg&/KQO
+s8VPI+:qc$s8RRcmJ[%cgAq3P'XB7i'RBTUs79A!$u,J9s5,pA*1Hm,(%7,)&6mBYs6G[j#VMY=
+s4V6"(4"s=rrVTB!<)p#pL+I=FnG_5gAlis[K4b8rS%>>JcC<$JcC<$JcDqRrn@I*s7Y1MRK2ZB
+9n3~>
+df0[Qq=F.FmHa'$kNDd*$0UO:lKms.o_JI_rrCWnrsdOG!!lKcs8UY:!!lKcr;QfS!;HKpmVdUS
+rt,(02$c@Us8VMF*"6#qs34=9!<<'%hDkQQSGrNk[4)(eHi<sF#dsU1)Y^?k#X,`us4V6"'R/R:
+s6bdb$sLpUs*ntTrVloT!<)p#[4)(eHiF$RpK@h.C\Rl/hDkQQSGrO'mY`%n>0[*IlAQkh/Y)G4
+g1q66GN/T$!q+nFrVm#p@gE?]o`+pA!-@b6!Qs9tec=uds+13$s+13$s0)J%ecBjlp=9A2!9]S=
+J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ci4[Wq=X@LnF,f5mHs?0n*ol<p\OmarrCf)s+ULPgAlis[K4b8rS%>>JcC<$JcC<$JcDqRrn@I*
+s7Y1MRK2ZB9n3~>
+ci4[Wq=X@LnF,f5mHs?0n*ol<p\OmarrCW$s+ULPec9d_XT?T$rRLu6JcC<$JcC<$JcDqRrmh*k
+s7Y"HPQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:m]c]lmXKffJcC<$JcC?%rn[[/s7Y:PS,i#J:4N~>
+bl@_B$N9o"qY9m_qu$Elo`"pGJcCH(rn@F)o<n\Hj8I^4mBHTkm=0]eJcC<$JcC?%rn@I*s7Y1M
+RK2ZB9n3~>
+bl@_B$N9o"qY9m_qu$Elo`"pBJcCH(rmh'jo;r&9hYl"*lEL9hmXKffJcC<$JcC?%rmh*ks7Y"H
+PQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mbn*GL[NXk"m.iFs+g%/s8U"9rsnP1M2Ae2s8V`1P(T(Fo7?pm
+s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mGS!FL[W^l"lhZDs+g(1rrW2;`;]cHn[j[9\aKLtou</JQd52R
+s+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lJV[CL[NXk"m.iFs+g%/s8U"9rsnP1M2Ae2s8V`1P(T(Fo7?pm
+s+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mbn*G#i=&1"o#S-rs7KMrri5]]iKdbrslMIB5(bZs8TcJBm!s/
+P_&jcs+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mGS!F#i3u0"nfJ,rs7HLrri5]]N0^brslPKB51n^rr0QHC3F33
+P_&jcs+13$s0)J%gAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lJV[C#i=&1"o#S-rs7KMrri5]]iKdbrslMIB5(bZs8TcJBm!s/
+P_&jcs+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-UmbX[jON7(pqp1R\LUI$Zs*rU]`W,h?LP)Q"r;RUl!-d/sJ(Cs+
+iomY&KrF#2p:%!'Kp9p\q#;*-f!1!_W;$>GL\(Q*L[OS[s,-l$gALsOmXP!2(@\_K.=_Btq0ur/
+hI_33p4$Q$nAAKSJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^Om+e=hOiR1qqp:X]LU?sYs*rOZ`;f_?LP)W$r;RUn!-QroJ(1d(
+iTIG#KrEu1p9ps(L6U![q#;*-f!:'`WqZPIM=^c-L[XV[s,@#$f_kaMm=4m1(@\_K."D9sq1*&0
+h.M-0p3pN$n\SKQJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r&9hYl"ElJA7fON7(pqp1R\LUI$Zs*rU]`W,h?LP)Q"r;RUl!-d/sJ(Cs+
+iomY&KrF#2p:%!'Kp9p\q#;*-f!1!_W;$>GL\(Q*L[OS[s,-l$gALsOmXP!2(@\_K.=_Btq0ur/
+hI_33p4$Q$nAAKSJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-Uc\Z+R@Vj$`cZ`iBG>>RGrr?tQ^&P$7HZMrPr;RUl!-d/s!,l_=
+g8%JQF',%2mVb+0F'*M0q#;)XJQdDA:7V@<4dc+f>415Is,-l$gALsOl;%*R(A,kK:4N<Dq743;
+k\ktHp4$`1q8lk]JcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^Ob_TeQ@r0*`cZ`i@F\K7Drr?tQ])Sd9H#lcOr;RUn!-Qro!,l_;
+fVD5NEEA_-m;4n/FBNV/q#;)YK3`bD:RqI=5+;@k>OU;Hs,@#$f_kaMk=t^N(A,kK9n33Cq743:
+k&,VAp3pW-prH\]JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r&9hYl"EbDB\N@Vj$`cZ`iBG>>RGrr?tQ^&P$7HZMrPr;RUl!-d/s!,l_=
+g8%JQF',%2mVb+0F'*M0q#;)XJQdDA:7V@<4dc+f>415Is,-l$gALsOl;%*R(A,kK:4N<Dq743;
+k\ktHp4$`1q8lk]JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-VQsd#bbD!>%P$Z&tmW1hsrr@,op\QP8oBqhhp\b%.!8dbU!->%$
+pT]h4iad-$mVbS.m($5]rVHO/rKLoeoBqhhp]%KUPWdIph>mTU!8dVQ!W1.7rrVV,J,K<T^M-lU
+s8TQ1??oRZMh1nZs+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^PQ=6rcb(R/"OBo]mm;khurr@2qp%pG9naD\fp\b%.!8IPR!-P4&
+orsP0hd^Zrm;5A-mC65[rVHO/rKV&hnaD\fp]%HWP<dRrgAq9R!8IDN!Vst4rrVS)J,TBVrk2uK
+YQ"O/='^&O@#KU9JcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+ZMspUJcCH(rmh'jo;r&9hYl"FP[LT^bD!>%P$Z&tmW1hsrr@,op\QP8oBqhhp\b%.!8dbU!->%$
+pT]h4iad-$mVbS.m($5]rVHO/rKLoeoBqhhp]%KUPWdIph>mTU!8dVQ!W1.7rrVV,J,K<T^M-lU
+s8TQ1??oRZMh1nZs+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-VGAH4<q;CE-Fa*QZs2>EHrrC1@s69T.It)A:ir&fn!8dbU!6O=%
+s59oCQ:c)`mVd7?s7CGVo_SS&oQ<6>It)A:irAmZ(mt@'h>mTU!8d,C!q'uVr;R2?Bi_84s0Pa1
+GuS+.JcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^PF_g":q;:<+FER9Vs2GQKrrC.?s6B`/It)A:j8Aoo!8IPR!6F4#
+rna]APtGo\m;6t;s7:;Sp%n\'ol`E>It)A:j8]!^(mt@'gAq9R!8Ho@!psiSrVm?+^1gZLrVj0'
+>^'.SMh1nZs+13$s0)J%gAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;r&9hYl"FF)0e8q;CE-Fa*QZs2>EHrrC1@s69T.It)A:ir&fn!8dbU!6O=%
+s59oCQ:c)`mVd7?s7CGVo_SS&oQ<6>It)A:irAmZ(mt@'h>mTU!8d,C!q'uVr;R2?Bi_84s0Pa1
+GuS+.JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-VF_Ke7q:+-jFa*QZs2>EHrrCpUs69T2It)fXlMUZ!!8dbU!8d/D
+qke.eTN#jtmVd7?s7CGVo_SS&oQ<<DIt)fXlMpTZ-&;O#h>mTU!8d,C'^fmhs8Vu@dJrEGH2%,a
+@bUXu=r`+nJcC<$JcDqRrn[[/s7Y:PS,i#J:4N~>
+ZMspZJcCH(rn@F)o<n\Hj8I^PF(sY6q:+-jFER9Vs2GKIrrCgRs60N/It)fXlhpc"!8IPR!8Ho@
+qkn4fTN,jrm;6t;s7CDTo_SS&oQ33@It)fXli6WZ-AVX$gAq9R!8Ho@'^]aes8Vr>d/N3DH1pu]
+AD-^s>TeUtJcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+ZMspUJcCH(rmh'jo;r&9hYl"FEG4A3q:+-jFa*QZs2>EHrrCpUs69T2It)fXlMUZ!!8dbU!8d/D
+qke.eTN#jtmVd7?s7CGVo_SS&oQ<<DIt)fXlMpTZ-&;O#h>mTU!8d,C'^fmhs8Vu@dJrEGH2%,a
+@bUXu=r`+nJcC<$JcDqRrmh*ks7Y"HPQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-tO^,'YbB^&bOBf]pmW1hsrrCpUs8+7DoCJo5s8U@@s8N)Qs8N)U
+mf3$*BBJ,[D=$\/7_S6%=H`XZrtYKqBW1OoW.Y-MS405.`W+cps8N)Qqu6]oc1V)NmVdUTs8.t+
+i8/-sq>#MJeF::X+bBZEs+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^nOBf!Yb'Br`O'KNkm;kbsrrCgRs7n.Anaic7s8U==s8N)Ns8N)R
+mJlm(BBA#ZC[:A)7_S6%=ciRXrtYHoBVt=kWeLKQRREr,`;eQls8N)Nqu6]mbk:uMm;7@Qs7q_$
+hV;alp\0,Fe+(7Y,(]cFs+13$s0)J%gAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;r&9hYl"dNEiXUbB^&bOBf]pmW1hsrrCpUs8+7DoCJo5s8U@@s8N)Qs8N)U
+mf3$*BBJ,[D=$\/7_S6%=H`XZrtYKqBW1OoW.Y-MS405.`W+cps8N)Qqu6]oc1V)NmVdUTs8.t+
+i8/-sq>#MJeF::X+bBZEs+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-LbCa2F@Vj$`c#mK>F&'.CrrCpTs!+1?GBZrHs8PjZs8O6XgA_00
+mf30Q<-a6u8@S#*20!bDF3jX](!h;3GBZrHs2d:/s*IB'h>mTU+`#g0rrMC[p&>*]Dh%cd%^98R
+Bk4^Qs1;rWF(03TJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^Fab+#E@r93bc#dB:F%j%BrrCgQs!+7@GB[&Ls8PgVs8O3Wf`(s+
+mJm$N<I'C$8[n)(1iRPBFO0a^(!qA3GB[&Ls2m=.rHh-#gAq9R+D]X-rrM:Wp&>`nD1DTcrif^B
+Bk=aPrjuoYF_#QXJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r&9hYl"<a+IcB@Vj$`c#mK>F&'.CrrCpTs!+1?GBZrHs8PjZs8O6XgA_00
+mf30Q<-a6u8@S#*20!bDF3jX](!h;3GBZrHs2d:/s*IB'h>mTU+`#g0rrMC[p&>*]Dh%cd%^98R
+Bk4^Qs1;rWF(03TJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-Lmb47bON7(pqp1R\K=1UVs*sJ9s!.9>K7fuks8RT:s8SaAgAcZj
+pAb0LTS98LP/6R)A>k3JchmM;(&QC[K7fuks2gN&s5nt!mXP9:TRY\nrrMP;p&>*e\%hqB%d^TY
+M7`9Ws7F9lJX4RPJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^Fm+It`Oi[:sqTb@YKs^aWs*sG8s!.9>KnH8os8RT9s8SaCf`-Hg
+pAb0LTSBDPPJZ^(A>k3Jd/3V<(&QC[KnH8os2pQ&s6#%!m=509TRkbnrrMM:p&>*e[_MhA%d^TY
+MS/KZs7OBoK9jdRJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r&9hYl"<lIqh^ON7(pqp1R\K=1UVs*sJ9s!.9>K7fuks8RT:s8SaAgAcZj
+pAb0LTS98LP/6R)A>k3JchmM;(&QC[K7fuks2gN&s5nt!mXP9:TRY\nrrMP;p&>*e\%hqB%d^TY
+M7`9Ws7F9lJX4RPJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:ma1t8mVdT+s+13$s+13$s5X.Yh>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mEkk7m;7?(s+13$s+13$s5X.YgAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lHoP4mVdT+s+13$s+13$s5X.YecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:ma1t8nr/t7rrMJfqgSWt_1DW;s+13$s+14?s8LjUK`Cc&"IoJ\
+S5+S~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mEkk7nVNV2rrMGeqgSWu_L_`<s+13$s+14?s8LaRK)bQ!"I]>V
+RSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lHoP4nr/t7rrMJfqgSWt_1DW;s+13$s+14?s8LRMF8tsb"I&oL
+PY-H~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:ma1t8qpa9srrMJfqgSWt_1DW;s+13$s+14?s8LjUK`Cc&"IoJ\
+S5+S~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mEkk7qU4!orrMGeqgSWu_L_`<s+13$s+14?s8LaRK)bQ!"I]>V
+RSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lHoP4qpa9srrMJfqgSWt_1DW;s+13$s+14?s8LRMF8tsb"I&oL
+PY-H~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4m=G:gs+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*l@Jtds+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]cMmmZpj[kp_Z0Vl!/0sW!S6E3h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+ZMspZcMmmZpj[kp_Z0Vi!.sgN!RTm*gApVls+13$s+13$s0)J%gAup+p=f_=!:-(JJ,~>
+ZMspUcMmmZpj[kp_Z0Vd!-@b6!Qs9tec=uds+13$s+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsp]cMms\561V2!<@WErtW5&J"Z60mXNZCJ#L]jp:%g:s7Wq:JcF^/rn[X.o=Y1Uk5F-:mXbCh
+s+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZcMms\561V2!<@WFrtbRGM1MDgs6Y<aMh.hPqY%A4s8Vf$^OcFDs8LaQK(HDOd,Y)Z!:>@;
+JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUcMms\561V2!<@WErtW5&J"Z60mXNZCJ#L]jp:%g:s7Wq:JcF^/rmh'jo;r&9hYl"*l@Jtd
+s+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]c2Rj[It.Its*shD(;WmiG>=(rh>hVDCIN<jmVdUTs6afTJcF^/rn[X.o=Y1Uk5F-:mXbCh
+s+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZc2Rj[It.Its*shD(;<[hG>F(qgAlACD+&Bhm;7@Qs6XZQJcF^/rn@F)o<n\Hj8I^4m=G:g
+s+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+ZMspUc2Rj[It.Its*shD(;WmiG>=(rh>hVDCIN<jmVdUTs6afTJcF^/rmh'jo;r&9hYl"*l@Jtd
+s+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]bQ%Tl!rmb"p\u",DsI(iCB*,jN:,td=H`#hJ,fQ:Dh!?<iW&o6!/0sW!S6E3h>luUrrdi>
+s*sJ%rrVo'^OcE9s+13$s-3Q_h>r<0p>,qB!:QFQJ,~>
+ZMspZbQ%Tl!rmb"p\u"+EU3:jC&cofNpl:f=-;fcJ,fQ9D1@-:iW&o3!.sgN!RTm*gApWQrrdi=
+s*sG$rrVo&^OcE9s+13$s-3Q_gAup+p=f_=!:-(JJ,~>
+ZMspUbQ%Tl!rmb"p\u",DsI(iCB*,jN:,td=H`#hJ,fQ:Dh!?<iW&o.!-@b6!Qs9tec>!Irrdi>
+s*sJ%rrVo'^OcE9s+13$s-3Q_ecBjlp=9A2!9]S=J,~>
+ZMsp]b5_HjpAYm>`W,u0c2ZW#lMpnLF`lb`J,fQ:Dh!?<iW&o6!/0sW!S6E3h>luUrr`>YrrCp@
+rs&%USH$L=p@/(_hOa[q#eC!8lC`WZW:tlCJcC<$JcE7[rn[[/s7Y:PS,i#J:4N~>
+ZMspZb5_HjpAYm>`rH)1bl?Dtl2UeHF*6M[J,fQ9D1@-:iW&o3!.sgN!RTm*gApWQrr`>VrrCg=
+rs&"RSH$L=p[J1`h4=Lo#eL'9l_&f]WqCrCJcC<$JcE7[rn@I*s7Y1MRK2ZB9n3~>
+ZMspUb5_HjpAYm>`W,u0c2ZW#lMpnLF`lb`J,fQ:Dh!?<iW&o.!-@b6!Qs9tec>!Irr`>YrrCp@
+rs&%USH$L=p@/(_hOa[q#eC!8lC`WZW:tlCJcC<$JcE7[rmh*ks7Y"HPQ9m28q6~>
+ZMsp]ao;?jp&>d9`W,u0[K#(`lMpnLF`lb`J,fQ2Aq,C3iW&o6!/0sW!S6E3h>luUrr`>YrrCp@
+rs&AQh#E"JmdU5XZ;=HuCC%3Fs*%4ZF&&6Vs+13$s+13[s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZao;?jp&>d9`rH)1[f>(^l2UeJFEHMZJ,fQ1Aq,C3iW&o3!.sgN!RTm*gApWQrr`>VrrCg=
+rs&>Oh#E"ImdU5XZVOKuCC%0ErHV1]F&/6Us+13$s+13[s8LaRK)bQ!"I]>VRSA;~>
+ZMspUao;?jp&>d9`W,u0[K#(`lMpnLF`lb`J,fQ2Aq,C3iW&o.!-@b6!Qs9tec>!Irr`>YrrCp@
+rs&AQh#E"JmdU5XZ;=HuCC%3Fs*%4ZF&&6Vs+13$s+13[s8LRMF8tsb"I&oLPY-H~>
+ZMsp]]`/a9F6`Lm;ZGSRN:-+h=H`/pC$>8t4b&%_iW&o6!/0sW!S6E3hAbn>U4\QJpAb$9Q@jt#
+qu?\Ger[lNqltp/W;$2h+juI%Mp;:WYg`XPa0+RgZ%n%7k5X;4K94.Is6-_CKrF#1rr`>YrrCpN
+rtYF9LP)Q"s4W8"s5Jh%m^KsM76@I7rVlrm\%h_<!hO#;rosd`s6:#goBqP`JcC<$JcC<$\GuQb
+!JLLHh?9>Kn!m.'~>
+ZMspZ]`/a:F6iLl;ZGJON:6.j=ci&kB]o,t4b&%_iW&o3!.sgN!RTm*gDfM7U4n`MpAb$:Q@jt"
+qu?\Ge;qQJqm)!0WqZDj+juL&NQhFWZ./gRaKXgjZA=7;jo4&0KosFLs6$VAKrEu0rr`>VrrCgK
+rtYF:LP)W$s4W>$s5Sn'm^BmM7QRI5rVlrm[_MV;%\IFIlKdd/s5slfoC%VbJcC<$JcC<$\GuQ_
+!J:@FgB<rFl^COu~>
+ZMspU]`/a9F6`Lm;ZGSRN:-+h=H`/pC$>8t4b&%_iW&o.!-@b6!Qs9tef3o2U4\QJpAb$9Q@jt#
+qu?\Ger[lNqltp/W;$2h+juI%Mp;:WYg`XPa0+RgZ%n%7k5X;4K94.Is6-_CKrF#1rr`>YrrCpN
+rtYF9LP)Q"s4W8"s5Jh%m^KsM76@I7rVlrm\%h_<!hO#;rosd`s6:#goBqP`JcC<$JcC<$\GuQZ
+!H\;7ec_3;kEJSh~>
+ZMsp]]`/bX:31VSMuVW6CNjhgF3j`T:i1i53IcV[iW&o6!/0sW!S6E3hAadt@Wc-r`W+8.@X!#k
+[K$7,Dem&dW*4Oh:7V7^.echRHY-%Ib@[";n9]*3Ug.nZ>,'f/@Wc-r`VZH+@WPYCqu?ZrhZ!T4
+q#;)->'k<cSH%;+R/:r.mcJG;`C2kem/?qcoUMfRrsjrSGCPjUp]'Aop](9$'S6:8s+13$s1&+.
+h>r<0p>,qB!:QFQJ,~>
+ZMspZ]`/bW:31VTMuVN3Bm4PfFO0fT;/V)93.HMZiW&o3!.sgN!RTm*gDe@mA9MI!`;e/-@Wcfe
+[f?@-DelraWa0mk:Rq@_.ecqWH"g"Ib%?n:nU,94VI+=_>GBi-A9MI!`;??)@W>J?qZ$Qqg]%9.
+q#;)/?$UKeSH%;,Req53n)\D9`^W"eli$hbo9uQOrsjuVGCPmXp]'>lp&G'!(kM^<s+13$s1&+.
+gAup+p=f_=!:-(JJ,~>
+ZMspU]`/bX:31VSMuVW6CNjhgF3j`T:i1i53IcV[iW&o.!-@b6!Qs9tef2eh@Wc-r`W+8.@X!#k
+[K$7,Dem&dW*4Oh:7V7^.echRHY-%Ib@[";n9]*3Ug.nZ>,'f/@Wc-r`VZH+@WPYCqu?ZrhZ!T4
+q#;)->'k<cSH%;+R/:r.mcJG;`C2kem/?qcoUMfRrsjrSGCPjUp]'Aop](9$'S6:8s+13$s1&+.
+ecBjlp=9A2!9]S=J,~>
+ZMsp]]DiVRLOYubs5!atLP)POqu>ZQK8[4=^OcFDs8LjTK_)kXf&lqf*11-8nB6NmrK:L)oBpZg
+s8N(?g@tIrT_%T9-27B<.dmA:pY'ugmX90?b@Hq3G>urQWk"p5XRODe[/7+if]$F_o)J^ihZ!T4
+q>V3,/YM_'PU6)(Yr.b/df8`RJ,b":mem(drT*,:rt#!`6ZmTV7A0\Xmf3$p>'ki#JcC<$JcE7[
+rn[[/s7Y:PS,i#J:4N~>
+ZMspZ]`/cG[YKF.n,M,BaG5DJd/3k&W.g5?WkX,biW&o3!.sgN!RTm*gDlMfY40Se[/?"k_=?o6
+8H8\iFkZNc0VIt)PU-#%s!mI?W:ekip[3EMkf[P&oQaK_kGl%f@BT+BKXCT[OOrB"EUj)/!8IMR
+g\Ljaq_4]5n!#*ls0+JH5go]"D1DS8D=.9$!rV'>q>V!%M+)Q2>tC^iqsFFX]NKT4s+13$s+13[
+s8LaRK)bQ!"I]>VRSA;~>
+ZMspU]DiVRLOYubs5!atLP)POqu>ZQK8[4=^OcFDs8LRLF7ZL7b23*J*0aj4nB6NmrK:L)oBpZg
+s8N(?g@tIrT_%T9-27B<.dmA:pY'ugmX90?b@Hq3G>urQWk"p5XRODe[/7+if]$F_o)J^ihZ!T4
+q>V3,/YM_'PU6)(Yr.b/df8`RJ,b":mem(drT*,:rt#!`6ZmTV7A0\Xmf3$p>'ki#JcC<$JcE7[
+rmh*ks7Y"HPQ9m28q6~>
+ZMsp][Jp9a!.k1!s8LjTK_)kXf&lqf*-Z2Xs7tU8oQ>BOs8U%Hs8N)@s8V?aGCP*\!93tW.ed7n
+K:LNms.j2?Sn,h;Wb[$D\a"rcirAi4k5XA>QBk-]mf3:ehZ!T4q>V2p!-`pBDZJesqcXi(s8VM*
+J,b":md^;^qo?,.p:#N'rr3,CK6)\-JcC<$JcC<$\GuQb!JLLHh?9>Kn!m.'~>
+ZMspZ[Jp9^!.k1!s8LaQK(HDOd,Y)Z*-H&Vs7tR6oQ56Ks8U(Ks8N)?s8VBdFanmZ!9=%X.ed@q
+K:C<hs.j8AS7T_;XDE<G\*/T_irAi3jo4,;QBb'ZmJm1dg]%9.q>V2q!d0!BDZJhtqct&+s8VJ'
+J,b"8mIC2]qT$&-p:,Z+rr3,DK6)V*JcC<$JcC<$\GuQ_!J:@FgB<rFl^COu~>
+ZMspU[Jp9a!.k1!s8LRLF7ZL7b23*J*-5oTs7tU8oQ>BOs8U%Hs8N)@s8V?aGCP*\!93tW.ed7n
+K:LNms.j2?Sn,h;Wb[$D\a"rcirAi4k5XA>QBk-]mf3:ehZ!T4q>V2p!-`pBDZJesqcXi(s8VM*
+J,b":md^;^qo?,.p:#N'rr3,CK6)\-JcC<$JcC<$\GuQZ!H\;7ec_3;kEJSh~>
+ZMsp][Jp9i0nKARs8LjTK_)kXf&lqf*-GrSs7t0uoQ>BOs8U%Hs8N)Us8V?aH[gNlBBoHq.f7&X
+LNcqrqp/l*GC/cVhQrMtBW-JqirAi(gA@a_MkF$fmf3:ehZ!T4q>V2p!.03FHY;XDpJrSqs8VM*
+J,b":md^;eo%N7+s5M$,s8T?9J$o$%s+13$s+13Zs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZ[Jp9f0S08Qs8LaQK(HDOd,Y)Z*-5iRs7t0uoQ56Ks8U(Is8N)Rs8V<`H%1<jBC#Nr.f7)[
+LNQboqp9#,FaNQThR&StB;gAqirAi(gA@d`MkF'emJm1dg]%9.q>V2o!-s'DHY;[EoiEJqs8VJ'
+J,b"8mIC2do@i@,s5V-0s8TB=ICAg"s+13$s+13Zs8LaRK)bQ!"I]>VRSA;~>
+ZMspU[Jp9i0nKARs8LRLF7ZL7b23*J*-#ZOs7t0uoQ>BOs8U%Hs8N)Us8V?aH[gNlBBoHq.f7&X
+LNcqrqp/l*GC/cVhQrMtBW-JqirAi(gA@a_MkF$fmf3:ehZ!T4q>V2p!.03FHY;XDpJrSqs8VM*
+J,b":md^;eo%N7+s5M$,s8T?9J$o$%s+13$s+13Zs8LRMF8tsb"I&oLPY-H~>
+ZMsp][Jp:%Z%;r(s8LjTK_)kXf&lqf99EJ^nB6*UrK(:%oBpZgs8N)Us8VsFW:TVZKE(trqu?D'
+hYXPXoD.s*3EE$Wqlca\el[3f>d!S>H)UI]BBJ,[D=%<&!8d_UhYI0dq^JK8o;I<As-uNR0ua1\
+Dh%e:D=%3#!r_3Bq>UleOGi&d[=:LBl7meFrp#(7JcC<$JcE7[rn[[/s7Y:PS,i#J:4N~>
+ZMspZ[Jp:#Y^ui's8LaQK(HDOd,Y)Z99<D^nB-$Tr/Y+!na1Bes8N)Rs8VmEVXa8XL&_1sq>^,#
+hYF;UnbD^)3``-XqQ?UZdo^mb>d*Y>H)UF\BBA#ZC[;$#!8IMRg\Ljaq'r93o;[NEs-c?O1;s4[
+D1DS8C[:ou!rV'>q>UlfP)\Di[=:UEkq[hGrp,.8JcC<$JcE7[rn@I*s7Y1MRK2ZB9n3~>
+ZMspU[Jp:%Z%;r(s8LRLF7ZL7b23*J99!2ZnB6*UrK(:%oBpZgs8N)Us8VsFW:TVZKE(trqu?D'
+hYXPXoD.s*3EE$Wqlca\el[3f>d!S>H)UI]BBJ,[D=%<&!8d_UhYI0dq^JK8o;I<As-uNR0ua1\
+Dh%e:D=%3#!r_3Bq>UleOGi&d[=:LBl7meFrp#(7JcC<$JcE7[rmh*ks7Y"HPQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-LbCa2F@Vj$`c#mK>F&'.CrrCpTs#$HQGBZrHs8PjZs8,]/HY6CV
+rVr`F>1NZOVI"=`?DuS1@!,pp`VZ*'H&#?i\,ZI.hZ!T4q#;)%>'G0gOT3E_[JtSGlJul5s,]^E
+m/?qcoUMfSrsSIn>\eIo>.O[D!+YtCJcC<$JcC<$\GuQb!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^Fab+#E@r93bc#dB:F%j%BrrCgQs#$NRGB[&Ls8PgVs7oT/H"U4S
+r;WWF>h8rQVI+@_?`;V0@<H's`VQ!&H&,Km\,ZI.g]%9.q#;)'=a,'iOoNQ`[/G>Cl/HQ0s,TXD
+li$hbo9uQPrsSLp?>Odt=LeC>!+YtCJcC<$JcC<$\GuQ_!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r&9hYl"<a+IcB@Vj$`c#mK>F&'.CrrCpTs#$HQGBZrHs8PjZs8,]/HY6CV
+rVr`F>1NZOVI"=`?DuS1@!,pp`VZ*'H&#?i\,ZI.hZ!T4q#;)%>'G0gOT3E_[JtSGlJul5s,]^E
+m/?qcoUMfSrsSIn>\eIo>.O[D!+YtCJcC<$JcC<$\GuQZ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-Lmb47bON7(pqp1R\K=1UVs*sJ9rt+q+K7fuks8RT:s8U?%Iur7\
+ruo3TL%bQHk,a8lZg.SESqE-FpAa!BKr22>_>jObmf.e)q#;*'XFl/$oDcpsqu>f2lKl!ps3He.
+m/?qcp:%g3rs7u#M1_P9s8U@@It@WNs+13$s1&+.h>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^Fm+It`Oi[:sqTb@YKs^aWs*sG8rt+q+KnH8os8RT9s8UB&J!&7[
+ruo3TLA1`Jk,j>nZg%JBSqN6Ip]'*CL8_JC_Z0XcmJh\'q#;*'XG);(oDcssqu>i3l0Gdms3He/
+li$hbp9qa2rs7r"MM._:rVt+=It@WNs+13$s1&+.gAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;r&9hYl"<lIqh^ON7(pqp1R\K=1UVs*sJ9rt+q+K7fuks8RT:s8U?%Iur7\
+ruo3TL%bQHk,a8lZg.SESqE-FpAa!BKr22>_>jObmf.e)q#;*'XFl/$oDcpsqu>f2lKl!ps3He.
+m/?qcp:%g3rs7u#M1_P9s8U@@It@WNs+13$s1&+.ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mb%O@`F>?gs+13$s+13$s4dSQh>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mF_F?`at]ls+13$s+13$s4dSQgAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lIc+<`F>?gs+13$s+13$s4dSQecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mb.UBo7UW%JcC<$JcC<$JcFL)rn[[/s7Y:PS,i#J:4N~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mFqRCrUGSOd"24Js+13$s+14)s8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lIl1>o7UW%JcC<$JcC<$JcFL)rmh*ks7Y"HPQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mb7[CiaXF9ir9"dq>^L$JcC<$JcC<$K)bi,!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mFqRCiF+.3rT!nXZMFP$%"\G0s+13$s+::MgAup+p=f_=!:-(J
+J,~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lIu7?iaXF9ir9"dq>^L$JcC<$JcC<$K)bi$!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y@Zk3i9;hX5spJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<nkMj6cm6g[0RlJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r5>hWk.+f'7hdJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y@Zk3hYUDsi2VJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<nkMj6c5ND=)oSJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r5>hWjBAC[-KNJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y@Zk2("VDsi2VJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<nkMj4eDND=)oSJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r5>hUZHBC[-KNJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4m=G:gs+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*l@Jtds+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4m=G:gs+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*l@Jtds+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]JcCH(rn[X.o=Y@Zk3i9;hX9A&!T!h2rrLsVJcC<$JcC<$JcGQGrn[[/s7Y:PS,i#J:4N~>
+ZMspZJcCH(rn@F)o<nkMj6cm6g[3u"!S[V/rrLjSJcC<$JcC<$JcGQGrn@I*s7Y1MRK2ZB9n3~>
+ZMspUJcCH(rmh'jo;r5>hWk.+f';5o!T!h2rrLsVJcC<$JcC<$JcGQGrmh*ks7Y"HPQ9m28q6~>
+ZMsp]WrE.tTVUcN!V]4=rrW(jUsK&EIrFb)Dsm5s!cnXTnGiLE!/0sW#1hr)mVd%3iVrrIF5-]u
+mrSO/&DlmU"i_u*'Q`,^s+13$s+138s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZWrE.rTVgoP!V9%<rrW"hVU,8GIr4S&D=-rp!d+dSnGiLB!.sgN#12Dtm;6_-iVrrEFkcp"
+lZN7-&DusV"ii#,(3A>`s+13$s+138s8LaRK)bQ!"I]>VRSA;~>
+ZMspUWrE.tTVUcN!V]4=rrW(jUsK&EIrFb)Dsm5s!cnXTnGiL=!-@b6#0Pffl>(2#iVrrIF5-]u
+mrSO/&DlmU"i_u*'Q`,^s+13$s+138s8LRMF8tsb"I&oLPY-H~>
+ZMsp]WrE7NTZr79mcsfTV4@PshV8&3d\+k2rrmmjmXK0CoD\gk`p`s,h>i6#]a!'MhJWC4m^<&q
+!8d2E"W2p']hX?6s+13$s+138s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZWrE7NTZi18n*9oUVOIMrhqS/4d\+h1rrmmhm=0!?oD\go_sdX)gAlis[Kb+=gMHq-mBurp
+!8HuB"rr6)^/9[aJcC<$JcC<$QN-s=!J:@FgB<rFl^COu~>
+ZMspUWrE7NTZr79mcsfTV4@PshV8&3d\+k2rrmmjmXK0CoD\gk`p`s,ec9d_XTlr)enY8$lF$Wm
+!8d2E"W2p']hX?6s+13$s+138s8LRMF8tsb"I&oLPY-H~>
+ZMsp]^&Rj-p\tDqT_EqSmcsfT;XaVchV8&3W1`n2rrmmjmXK0CoD\gkhXCLDh>i6#]`H^HrSAL]
+]gW2MORE/CTIgE\C\Rl/!3IE's7^"7#ZC-hrt!rds8N)$+]cS$;@FCS:4N'=(&P*n$n\.Hg1#F#
+s2GW,h>mQm!"cR9rrLsVq#:T^!;HBjIrk44s+13$s+139s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZ^&Rj-p\tDsT_3eOmHX]S<U9YbgY;`0WhB%2rrmmhm=0!?oD\gkg[G1AgAlis[K4b8rS&:W
+\jd)ROR<)BU+Q]_C%qZ-!3.0!s7^(9#Z^?krt!ias8N)!+B?@u;\0jY9n2s<(&P-p$ne:Kg1>^(
+s2P].gAq6n!"cI6rrLjSq#:T^!;HBhI<"e.s+13$s+139s8LaRK)bQ!"I]>VRSA;~>
+ZMspU^&Rj-p\tDqT_EqSmcsfT;XaVchV8&3W1`n2rrmmjmXK0CoD\gkhXCLDec9d_XT?T$rRMqQ
+]gW2MORE/CTIgE\C\Rl/!3IE's7^"7#ZC-hrt!rds8N)$+]cS$;@FCS:4N'=(&P*n$n\.Hg1#F#
+s2GW,h>mQm!"cR9rrLsVq#:T^!;HBjIrk44s+13$s+139s8LRMF8tsb"I&oLPY-H~>
+ZMsp]]`.s3r;Q`sp\ulCTVRJS#\)M;8lc?\K2N+@\c;)9;I0b\;XaYcpIbH&!"cR<!3IE's.pk=
+(l\Io,C9t%6Jh/1qlMje/YMk<dUNgs>0[*ETVVU;8lc?\K2N*`F8l1BV',gUN;ih`!3IE's.pk=
+(l\Io*!!)q(_C?2s8/oY$n\.Hs*ntTIrFcLTIgR8Z2=Fu'HmGf[K#\n#S:eGs8VOc#S:eGs8W)T
+!/0sW!S6E3hA`_#J)[7qSH#N_R-3<\F8u7?0t$KM>#OP?8kT$]&)I<drr=d]d_/Ojdai.AJ,'$X
+XB(kNPY.bO[9B6t+f54q!<<'!hY[<RpRLmU!n(D5JcC<$JcC<$Q2gj?!JLLHh?9>Kn!m.'~>
+ZMspZ]`.s3r;Q`sp]"7jTVRPW#[uA88QQHcKiJUF\Gtr5;dU"a;="8^pIYB)!"cI9!3.0!s.UV9
+(lJ@nqfrkY7GI50qlVsg/u&+?dUa%$>Km-ETVVU;8QQHcKiJTgEW5t@U*'FQMZ3V^!3.0!s.UV9
+(lJ=m*!!,u*"li4s8/r[$ne:Ks*nnQIr4TIU+Qj:Yl"=t'HdAeZN'An#S:_Es8VOf#S:_Es8W)Q
+!.sgN!RTm*gDd:sJ`3=oS,]E]QK-^RFoVIA1q)`M>ufqB8P/j[&).*arr=mad(E:idai7FJ,'$X
+Y$%:RPY%\NZs0:!,c:Ur!<<'!g\_!Oo:#@P"T?\SM>`#*JcC<$JcD&9rn@I*s7Y1MRK2ZB9n3~>
+ZMspU]`.s3r;Q`sp\ulCTVRJS#\)M;8lc?\K2N+@\c;)9;I0b\;XaYcpIbH&!"cR<!3IE's.pk=
+(l\Io,C9t%6Jh/1qlMje/YMk<dUNgs>0[*ETVVU;8lc?\K2N*`F8l1BV',gUN;ih`!3IE's.pk=
+(l\Io*!!)q(_C?2s8/oY$n\.Hs*ntTIrFcLTIgR8Z2=Fu'HmGf[K#\n#S:eGs8VOc#S:eGs8W)L
+!-@b6!Qs9tef1_lJ)[7qSH#N_R-3<\F8u7?0t$KM>#OP?8kT$]&)I<drr=d]d_/Ojdai.AJ,'$X
+XB(kNPY.bO[9B6t+f54q!<<'!hY[<RpRLmU!n(D5JcC<$JcC<$Q2gj7!H\;7ec_3;kEJSh~>
+ZMsp]]Dhj2rr2rupA]!\TZR4`DsmXT/Z@6(/Z@6(F7\g<+ctE53E#nWXd&kc!8dbU!&:nMmf7G'
+]`@O$KIPL@=ui,QXB(kNPY.bGG?3/C>'K_lTZR4`/Z@6(/Z@7.!9aCN!-@nJ!:Tsf!&:nMmf7G'
+]`@O$ru;#*hX8'GL]=GVSDoc*V#Pp_mXK0CW(r`>LJk\Zrt>Chs8PthkM@q7s8PthkM@q7s8W)T
+!/0sW,1boEs6e`nCYJg[_9Mk(DsmZ*[2ArD!4Dk,pAj[^s5!bErVmDb!<<'![K$8gA((DWelI:r
+rtYEXGPD.*Dg1sQN%$Jbs8UpUs8N)UmJd9<!*7[%s+13$s+138s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZ]Dhj2rr2rupA]!\TZI._D=.@Q/umK,/?%-(F7\d9,*L]93)T_UY*/hb!8IPR!&V.Mmf7M%
+\cD'rJh5O>=ZDoNY$%:RPY%\FH!/MD>BfhmTZI._/umK,/?%..!9aCN!-RnE!:0[b!&V.Mmf7M%
+\cD'rru;#)hsJ'GL]=M[SDf](V#Pp]m=0!?W(iT8Ki5MYrt>Ces8Pqfj4c81s8Pqfj4c81s8W)Q
+!.sgN,1,B;s6\QhCYJg[^s)V"D=.B'[N,>I!4Mq-pB9g^s5*hFrVmD_!<<'![f?AgA((DWe5_"o
+rtYEZGP2")Dg1sQN@HVfs8UgRs8N)Rmf*FeI/m9sJcC<$JcC<$Q2gj<!J:@FgB<rFl^COu~>
+ZMspU]Dhj2rr2rupA]!\TZR4`DsmXT/Z@6(/Z@6(F7\g<+ctE53E#nWXd&kc!8dbU!&:nMmf7G'
+]`@O$KIPL@=ui,QXB(kNPY.bGG?3/C>'K_lTZR4`/Z@6(/Z@7.!9aCN!-@nJ!:Tsf!&:nMmf7G'
+]`@O$ru;#*hX8'GL]=GVSDoc*V#Pp_mXK0CW(r`>LJk\Zrt>Chs8PthkM@q7s8PthkM@q7s8W)L
+!-@b6,0Jd-s6A0^CYJg[_9Mk(DsmZ*[2ArD!4Dk,pAj[^s5!bErVmDb!<<'![K$8gA((DWelI:r
+rtYEXGPD.*Dg1sQN%$Jbs8UpUs8N)UmJd9<!*7[%s+13$s+138s8LRMF8tsb"I&oLPY-H~>
+ZMsp]])Mg3rrD`l-ENm3s*ntTs*nhLs*nhLs*ntTmVcn+s6A/8p]"F[s8N)Us8N),rr3kep]&eE
+hZ"b,s8V8Pc22j3p]'Z"GOK`RcMm\[s/_mbs*nhLs*nhLs8N)Us8U[Es4.2,s8N),rr47pp]&eE
+hZ*TU^&S-#Dh%Y2GPD.*Dg1r*Dsi*nl?dI;s4V(CqYq3/hZ*<MhZ*V`)#s=1hZ*V`)#sX8h>i6#
+]`ZjJmdC'm!Gh!!rrVV,J,]HRec>aM!8dbUhYR9Qf)>UZh>mTU!8dbUIr"?Ls6=BLq>UK`Du9SF
+C[1rA8c[HBs5!bUrrCpBrr^\MJ,=fsJcC<$JcD&9rn[[/s7Y:PS,i#J:4N~>
+ZMspZ])Mg3rrD`lENGc%s*nnQs*nbIs*nbIs*nnQm;6Y)s67u4p]"CVs8N)Rs8N)-s8VuJp]&\B
+g]&D)s8V8Nbklg4p&FK!GOKfUbkq53s/_g^s*nbIs*nbIs8N)Rs81FBs3gu&s8N)-s8VuJp]&\B
+g].9R^An3Mm;7@MI<YAamr*FEIr4S&D<H1]mJkmSNV`Yg!8IPF!8IPR[N,>=!8IPR[N,>Irn@F)
+o<nbJj6c75D#nG<rVmArDghTas478NrrCgRs53\R!8%2L&).*arrCgRs*nhMs8VD#J,0*Fmr/+(%
+VtD1b"D``s8UgRs8N)Rm/I19=b6I$s+13$s+139s8LaRK)bQ!"I]>VRSA;~>
+ZMspU])Mg3rrD`l-ENm3s*ntTs*nhLs*nhLs*ntTmVcn+s6A/8p]"F[s8N)Us8N),rr3kep]&eE
+hZ"b,s8V8Pc22j3p]'Z"GOK`RcMm\[s/_mbs*nhLs*nhLs8N)Us8U[Es4.2,s8N),rr47pp]&eE
+hZ*TU^&S-#Dh%Y2GPD.*Dg1r*Dsi*nl?dI;s4V(CqYq3/hZ*<MhZ*V`)#s=1hZ*V`)#sX8ec9d_
+XTQ`&lK\=`!:'O_!q'uVrr38T!<<'!hZ*W4qZ$WIrVmDb!<<'!hZ*V*C[1s"l>(nFrrMP+qu@4B
+lMnsu!7q2Mh>mTU!8d)B"4C5"qgncus+13$s-E]aecBjlp=9A2!9]S=J,~>
+ZMsp]\c2X0p&>g)S=oo^IrFcTIrFcTIrFcTIrFcCDh%`c!s%3P6N6ug!8dbU!8d_T#d#g9;?5SR
+!7q)J!Uan(!$c:EhLdC*GM;qaT`>%ADsmXTDsmZ*!8dbUXYDP.!8dbU!8d_T&?RZA;?5SRrrCpU
+s6afTmVi"')JeVfDsi*nhJ[oDs6=BLbt\6=)#sU9hZ)F4rr3,P!<:mUrr3)O!<;fmh>i6#]ckth
+hJWC4HY2"3o;T.pHZ/?Ps0W^DrrCpUs7ZNfs8Vi=r;R;a!<<'!hZ*V6@b1SZelI:rrtYEXHi*j?
+io^:8K/#tYs8UpUs8N)UnG`OX9)ehlIrk44s+13$s+139s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZ\c2X0p&?*1Stc8bIr4TQIr4TQIr4TQIr4T?D12B_rVHTPpI5)]"T[<WrrCgQrs5V]0NA,-
+rrC[KrrMS,qu@sWle[=J,^%c:Stc8bIr4TQIr4TQrrCgRs/In0<<1eRrrCgQrt)1e0NA,-s8N)R
+s8VJ'J+%=R!%D^LIr4S&D;B,YrVu2!J'Lgi!#Yb9!8IP2!;lfrf)Yj.!;lfrf)YjFrn@F)o<ogh
+j4eDND0]dJs7<8!q0?iEs8TMEs8N)Rs8VZjoDejbci!eRgAq9R!8IPRMdb-8s3t%uq>V3*H$T5c
+qr?l>omnkm4TGH9!<<'!g[P4JlUh!PrI&\UJcC<$JcC<$QN-s=!J:@FgB<rFl^COu~>
+ZMspU\c2X0p&>g)S=oo^IrFcTIrFcTIrFcTIrFcCDh%`c!s%3P6N6ug!8dbU!8d_T#d#g9;?5SR
+!7q)J!Uan(!$c:EhLdC*GM;qaT`>%ADsmXTDsmZ*!8dbUXYDP.!8dbU!8d_T&?RZA;?5SRrrCpU
+s6afTmVi"')JeVfDsi*nhJ[oDs6=BLbt\6=)#sU9hZ)F4rr3,P!<:mUrr3)O!<;fmec9d_XWbjD
+enY8$G@oS/o;T.pHZ/?Ps0W^DrrCpUs7ZNfs8Vi=r;R;a!<<'!hZ*V6@b1SZelI:rrtYEXHi*j?
+io^:8K/#tYs8UpUs8N)UnG`OX9)ehlIrk44s+13$s+139s8LRMF8tsb"I&oLPY-H~>
+ZMsp]XT'?qTZ-s2IrFcTIrFcTIrFcTIrFcCDenY<lIGt0[>b+bB`R#irrCpUs6fs5s8N)Urtr0D
+s6"1*qg3\es81g<qqg?4g0/^KTZ-s2IrFcTIrFcTrrCpUmf:Z5rrCpUrrCpUs6fs5s8N)Us8N)U
+s8VM*J,=S>qu?QQk5TpLmXK0?HZ/?Pg1H9>rt>Chs7ZNMs8TJDs7ZNMs8TJDs0_j_!/0sW!S6E3
+h@cbbKAr[uSH#BWR-3<\F8u7?hZ!Nn;Hi8H=ulW_SG3'?!<<'!hZ*Vh8S6E%C(,UertMD4T]_t>
+SH#Bk\c4+;s5!bUrrCXIrrMkap\tC.Pek%2Mh1nZs+13$s-<W`h>r<0p>,qB!:QFQJ,~>
+ZMspZXT'?oT#C[/Ir4TQIr4TQIr4TQIr4T?D/8J;ldl..ZASY]B`QofrrCgRs6g*6s8N)Rrtr3E
+s6"7-q0@8]s81j>qqpH6fNEFFT#C[/Ir4TQIr4TQrrCgRmf^i6rrCgRrrCgRs6g*6s8N)Rs8N)R
+s8VJ'J,+A8q>^?PkPp$Km=0!9H#;sKg1Q??rt>Ces766Fs8TMEs766Fs8TMEs0DXY!.sgN!RTm*
+gCgG_KAiOqS,]?YQK-^RFoVIAg]%3k<E\AF>s//eRe-R6!<<'!g].;f8nZT'D%;'jrtMJ7T&l\?
+Sc>Kk[ehJ1s4[PRrrCOFrrM_[q#:Tr&<aiA;2P7&s+13$s+139s8LaRK)bQ!"I]>VRSA;~>
+ZMspUXT'?qTZ-s2IrFcTIrFcTIrFcTIrFcCDenY<lIGt0[>b+bB`R#irrCpUs6fs5s8N)Urtr0D
+s6"1*qg3\es81g<qqg?4g0/^KTZ-s2IrFcTIrFcTrrCpUmf:Z5rrCpUrrCpUs6fs5s8N)Us8N)U
+s8VM*J,=S>qu?QQk5TpLmXK0?HZ/?Pg1H9>rt>Chs7ZNMs8TJDs7ZNMs8TJDs0_jW!-@b6!Qs9t
+ee4cVKAr[uSH#BWR-3<\F8u7?hZ!Nn;Hi8H=ulW_SG3'?!<<'!hZ*Vh8S6E%C(,UertMD4T]_t>
+SH#Bk\c4+;s5!bUrrCXIrrMkap\tC.Pek%2Mh1nZs+13$s-<W`ecBjlp=9A2!9]S=J,~>
+ZMsp]XT'?CSF6FWIr"?LIrFcTIrFcTIrFcCD]t5!M`F]8>2K8YB`Q`arrCpUs6fs5s+CC's)TpG
+moh`As/8tkkFbD:qgW)/dT1^nSF6FWIrFcTIrFcTrrCpUmf:Z5KE0U'rrCpUs6fs5s+CC's8N)U
+s8VM*J,cHJT]_t>SH"(WmXK0CUe7$6LJk\Zrt>Chs8P\`kM@q7s8P\`kM@q7s'#EY!/0sW!S6E3
+h@f7a4U<3mmf3$S/I2Vtp](6nhZ!Ndmofu&9'?6S!8db4!<<'!hZ!NZ]h&VH?:o_BrtY:(0aK4q
+o>t=#qu=qIf%pE,s$?^nr;QfS!;HKs[36(qGN+2RJcC<$JcD#8rn[[/s7Y:PS,i#J:4N~>
+ZMspZXT'?ET'u^ZIqe0IIr4TQIr4TQIr4T?D'4qrM`al:?/PY]B`QW^rrCgRs6B[2qh>+"s)g$I
+lWH3:s/K.lje>G>q0cc*c<#@kT'u^ZIr4TQIr4TQrrCgRlN#9.L&f^&rrCgRs6B[2qh>+"s8N)R
+s8VJ'J,cNMT&l\?Sc=1Vm=0!?VG!64Ki5MYrt>Ces8Pebj4c81s8Pebj4c81s'>WY!.sgN!RTm*
+gCihZ4piQun,N'P/-lYup](6ng]%3kmo^&):$;QV!8IP.!<<'!g].<P]LiSH?V>nDrtY:(1(#M"
+o?(F$qu=tJe(Xm&s$6dnr;QfP!;HKs[NH+sH/jJUJcC<$JcD#8rn@I*s7Y1MRK2ZB9n3~>
+ZMspUXT'?CSF6FWIr"?LIrFcTIrFcTIrFcCD]t5!M`F]8>2K8YB`Q`arrCpUs6fs5s+CC's)TpG
+moh`As/8tkkFbD:qgW)/dT1^nSF6FWIrFcTIrFcTrrCpUmf:Z5KE0U'rrCpUs6fs5s+CC's8N)U
+s8VM*J,cHJT]_t>SH"(WmXK0CUe7$6LJk\Zrt>Chs8P\`kM@q7s8P\`kM@q7s'#EQ!-@b6!Qs9t
+ee78U4U<3mmf3$S/I2Vtp](6nhZ!Ndmofu&9'?6S!8db4!<<'!hZ!NZ]h&VH?:o_BrtY:(0aK4q
+o>t=#qu=qIf%pE,s$?^nr;QfS!;HKs[36(qGN+2RJcC<$JcD#8rmh*ks7Y"HPQ9m28q6~>
+ZMsp]XT/<nrr3h.+^3TLDsmXTDsmXTDsm%38l?'L;XaWPrVm$f!4Dh,hZ!NrHO(1A64!VkCCgJ4
+hX:F<UbN-(R.L@&=ptsTetA]8rt^*&mf.cTmf3:ehZ*V&#S;q]#ljo)hZ!O#HO(1A64!Vk!8dbU
+mVdUTpS9ML.@B`,IrFb)Dsm@m/I4AAqtg=+!8dbUmnsDsC\Rl/mnsDsC\Riqrn[X.o=Y@Zk3i9;
+hX8nn!q'uVJcC<$JcC<$JcFX-rn[[/s7Y:PS,i#J:4N~>
+ZMspZXoAJ$StQ)_(n`'WfRIc*s*nnQs*nnQm;5El$nbQKqa(2\"[N9srrCgQruQRo'TPTjs8-XE
+"@_5:s7`<E$7_M9s3=gW&nfXaT`4s,Ir4TQIr4TQrrCgRs*Y.eN^XBVrrCgQs!3!u'TPTjs8N)R
+s8VJ'J,f8=1(#M"oDa;Wm=0!?oq!]A3jAMXrt>Ces8VC^#RkGAs8VC^#RkGAqa(59!.sgN#12Dt
+s6\S.eGfU;D1@-:JcC<$JcC<$huE]1!J:@FgB<rFl^COu~>
+ZMspUXT/<nrr3h.+^3TLDsmXTDsmXTDsm%38l?'L;XaWPrVm$f!4Dh,hZ!NrHO(1A64!VkCCgJ4
+hX:F<UbN-(R.L@&=ptsTetA]8rt^*&mf.cTmf3:ehZ*V&#S;q]#ljo)hZ!O#HO(1A64!Vk!8dbU
+mVdUTpS9ML.@B`,IrFb)Dsm@m/I4AAqtg=+!8dbUmnsDsC\Rl/mnsDsC\Riqrmh'jo;r5>hWk.+
+f':cb!q'uVJcC<$JcC<$JcFX-rmh*ks7Y"HPQ9m28q6~>
+ZMsp]R/[6UDh!?<nc/UF!/0sW#1hr)mVd%3eGfU<Dh!?<JcC<$JcC<$huE]4!JLLHh?9>Kn!m.'~>
+ZMspZR/[6TD1@-:nc/UC!.sgN#12Dtm;6_-eGfU;D1@-:JcC<$JcC<$huE]1!J:@FgB<rFl^COu~>
+ZMspUR/[6UDh!?<nc/U>!-@b6#0Pffl>(2#eGfU<Dh!?<JcC<$JcC<$huE],!H\;7ec_3;kEJSh~>
+ZMsp]R/[6UDh!?<nc/UF!/0sW#1hqnDZF_DeGfXFWJk$X!!*4TJcC<$JcC<$JcFs6rn[[/s7Y:P
+S,i#J:4N~>
+ZMspZR/[6TD1@-:nc/UC!.sgN#12DbD#eG?eGfXDVMSIQ!!*:XJcC<$JcC<$JcFs6rn@I*s7Y1M
+RK2ZB9n3~>
+ZMspUR/[6UDh!?<nc/U>!-@b6#0PfRCB//8eGfXFWJk$X!!*4TJcC<$JcC<$JcFs6rmh*ks7Y"H
+PQ9m28q6~>
+ZMsp]R/[6^WNh$Snc/UF!/0sW!S6E3h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+ZMspZR/[6\VQbXOnc/UC!.sgN!RTm*gApVls+13$s+13$s0)J%gAup+p=f_=!:-(JJ,~>
+ZMspUR/[6^WNh$Snc/U>!-@b6!Qs9tec=uds+13$s+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4m=G:gs+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;r&9hYl"*l@Jtds+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMsp]JcCH(rn[X.o=Y@Zk3i9;hX5spJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<nkMj6cm6g[0RlJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r5>hWk.+f'7hdJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y@Zk3hYUDsi2VJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<nkMj6c5ND=)oSJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r5>hWjBAC[-KNJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y@Zk2("VDsi2VJcC<$JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<nkMj4eDND=)oSJcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r5>hUZHBC[-KNJcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:ma;%:\NO9QpAY3^Dh!?<JcC<$JcC<$nc/UF!JLLHh?9>Kn!m.'~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mEtq9\isEPpAY3]D1@-:JcC<$JcC<$nc/UC!J:@FgB<rFl^COu~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lI#V6\NO9QpAY3^Dh!?<JcC<$JcC<$nc/U>!H\;7ec_3;kEJSh~>
+ZMsp]JcCH(rn[X.o=Y1Uk5F-:ma;%=Iq.L<LNi1^rrVr"\`*Pl_+G+fV#,`CJcC<$JcD):rn[[/
+s7Y:PS,i#J:4N~>
+ZMspZJcCH(rn@F)o<n\Hj8I^4mEtq<JRd[=LNi4_rrVkt]&EYm^e5.iV"oTAJcC<$JcD):rn@I*
+s7Y1MRK2ZB9n3~>
+ZMspUJcCH(rmh'jo;r&9hYl"*lI#V9Iq.L<LNi1^rrVr"\`*Pl_+G+fV#,`CJcC<$JcD):rmh*k
+s7Y"HPQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Y@Zk3i9;hX8ek#(LRZs*ntTfDc&6?A%+!<jdMYJcC<$JcD):rn[[/s7Y:P
+S,i#J:4N~>
+ZMspZJcCH(rn@F)o<nkMj6cm6g[3Dg#(LLWs*nnQfDc&8?\@0t=13\[JcC<$JcD):rn@I*s7Y1M
+RK2ZB9n3~>
+ZMspUJcCH(rmh'jo;r5>hWk.+f':Z_#(LRZs*ntTfDc&6?A%+!<jdMYJcC<$JcD):rmh*ks7Y"H
+PQ9m28q6~>
+ZMsp]JcCH(rn[X.o=Z<uk3hrGVXE<8K94.Is81-.K86l3s8RT"ON%7sZ%mt1p\Xt+dZAs:c2[h@
+c^'9Vf_ri]4/fGR4/hNBrt"h4^]2&uer[lN`J]55c%#Wj!UbI3rruM<ZgP_sbCT\Es+13$s-Ncb
+h>r<0p>,qB!:QFQJ,~>
+ZMspZJcCH(rn@F)o<oghj6cQBV!Qm2KosFLs810/K86i2s8RSuO2V(qZA4(4p\Xt+dZK$=bl@_?
+d$BBVfDW`[3iB;R3iD<?rt"h3^]2&ue;qQJ`/T>7b^]Ni!UYC2rruP<ZL5Srb^oeFs+13$s-Ncb
+gAup+p=f_=!:-(JJ,~>
+ZMspUJcCH(rmh'jo;s1YhWja5T^(C.K94.Is81-.K86l3s8RT"ON%7sZ%mt1p\Xt+dZAs:c2[h@
+c^'9Vf_ri]4/fGR4/hNBrt"h4^]2&uer[lN`J]55c%#Wj!UbI3rruM<ZgP_sbCT\Es+13$s-Ncb
+ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[X.o=Z<uk2rg*DpO8LF^f1+s3GmuGBZfis8N(;CVBbH>'k<cSG`C'pJPXNAkr*t
+cZ`iB@Y*7R83<cU76@I7qYq)oDh%e:!,lYd`DU;lG?P"DrrMC[q#:Tn&6tTVOLsk1s+13$s+13:
+s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZJcCH(rn@F)o<oghj5d=#D9RfHG%5@,s3GmuF`gBds8N(;CV'PG?$UKeSG`C'pJkpQBhe@!
+cZ`i@@=d.Q7lmQS7QRI5qYq)nD1DS8!,lYa`_gGqG?Y(ErrM:Wq#:Tn&6kNVOM't3s+13$s+13:
+s8LaRK)bQ!"I]>VRSA;~>
+ZMspUJcCH(rmh'jo;s1YhVbCkCWhQDF^f1+s3GmuGBZfis8N(;CVBbH>'k<cSG`C'pJPXNAkr*t
+cZ`iB@Y*7R83<cU76@I7qYq)oDh%e:!,lYd`DU;lG?P"DrrMC[q#:Tn&6tTVOLsk1s+13$s+13:
+s8LRMF8tsb"I&oLPY-H~>
+ZMsp]mf*=ejamH#s8LjTK_)l$f&khdDl/n0XRODe[/H.o_t3;;7K<AfF5$Bc/YM_'PU6)&rtb&'
+WV>+np\BtY_sjm8UAo^]mf.cTmeQknmVdUTIfOQDpJtVSpYK?Zqu6]oc1q;Djo@>]F^B:>JcC<$
+JcC<$QiI'A!JLLHh?9>Kn!m.'~>
+ZMspZmf*=ejamH#s8LaQK(HDpd,WlVD5<J+Y40Se[/?"k_=?o68H8\iFkZNc0VIt)PU-#%rtb&+
+W:ekip\9hU_=+U6U]5g\mJhZQmJ6bmm;7@QIfOWFoiGMSpYKB[qu6]mbkV2Ck5[G_G$fI@JcC<$
+JcC<$QiI'>!J:@FgB<rFl^COu~>
+ZMspUmf*=ejamH#s8LRLF7ZLXb21^BCS6o"XRODe[/H.o_t3;;7K<AfF5$Bc/YM_'PU6)&rtb&'
+WV>+np\BtY_sjm8UAo^]mf.cTmeQknmVdUTIfOQDpJtVSpYK?Zqu6]oc1q;Djo@>]F^B:>JcC<$
+JcC<$QiI'9!H\;7ec_3;kEJSh~>
+ZMsp]nc&aka'pCGJcD2=rn[X.o=Y1Uk5F-VGAH4<q;CE-Fa*QZs2>EHrrC1@s69T.It)A:ir/lm
+pKi&rSC[`4Fa*QZib4&GIrFcTIrFcNrsJ14J,auuaoDAP^&J$4_#X!)#N>_[a6pQER">9gs+13$
+s-Ncbh>r<0p>,qB!:QFQJ,~>
+ZMspZnc&aka'pCGJcD2=rn@F)o<n\Hj8I^PF_g":q;:<+FER9Vs2GQKrrC.?s6B`/It)A:j8Jun
+pL/8uS'q?/FER9VibF5JIr4TQIr4TKrsJ.1J,auuaT)8O^Ae-5^]<m(#N5Y[aR?]EQ\#0fs+13$
+s-NcbgAup+p=f_=!:-(JJ,~>
+ZMspUnc&aka'pCGJcD2=rmh'jo;r&9hYl"FF)0e8q;CE-Fa*QZs2>EHrrC1@s69T.It)A:ir/lm
+pKi&rSC[`4Fa*QZib4&GIrFcTIrFcNrsJ14J,auuaoDAP^&J$4_#X!)#N>_[a6pQER">9gs+13$
+s-NcbecBjlp=9A2!9]S=J,~>
+ZMsp]o`#-pa'oo!"gXHo!UbGls8LjTK_)l$f&l,_k2(5oirAi(g@TN3pAb03%0->-hZ*W@!.03F
+HY;XBrtbLJUka.tp[E<LpAa,cL&ZX@mf.cTmeQkimVdUTIfS@*rsZaCrrKq9nG`ab"F'P=jD0I#
+s+13$s+13:s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZo`#-pa'oo!"gXHo!UYAks8LaQK(HDpd,X3SjP+`iirAi(g@TK0p&G'3%0->-g].<<!-s'D
+HY;[CrtbLKVMB:sp[E9Ip&F#cL&ZX>mJhZQmJ6bhm;7@QIfS7'rsZ^BrrKn8nG`a`#'fh@jD'C"
+s+13$s+13:s8LaRK)bQ!"I]>VRSA;~>
+ZMspUo`#-pa'oo!"gXHo!UbGls8LRLF7ZLXb22(Ai7;m]irAi(g@TN3pAb03%0->-hZ*W@!.03F
+HY;XBrtbLJUka.tp[E<LpAa,cL&ZX@mf.cTmeQkimVdUTIfS@*rsZaCrrKq9nG`ab"F'P=jD0I#
+s+13$s+13:s8LRMF8tsb"I&oLPY-H~>
+ZMsp]p\tNua'oo"!!!O]^]4>Kg&D*0!:Tph_n5W3s8LjTK_)l?f&lDoY,7=dY40V[W;Vf__t3;;
+7K<AfhZ*WQ.B)k0W.Y-Mc27P8BAWNj!;#rH>f6'8>b_7JDsmXTD=%)u&+4@cs*k%*s8PZ"g@sH5
+!;lcsqp"m8"uU&2m^HMoJcC<$JcC<$QiI'A!JLLHh?9>Kn!m.'~>
+ZMspZp\tNua'oo"!!!O]^]4>Kg&D*-!:Tph_n5Z4s8LaQK(HE6d,XNeXe_%`YOK\[W;M]]_=?o6
+7fWJgg].<L.]2b-WeLKQbk_;3BAWHe!qGrE>f#m5>b_7JD=.@QC[:fr&++4`s*k%'s8P]"g@sH6
+!;lcsq98U5"up>8m^?GmJcC<$JcC<$QiI'>!J:@FgB<rFl^COu~>
+ZMspUp\tNua'oo"!!!O]^]4>Kg&D*0!:Tph_n5W3s8LRLF7ZLsb22FUWh>>VY40V[W;Vf__t3;;
+7K<AfhZ*WQ.B)k0W.Y-Mc27P8BAWNj!;#rH>f6'8>b_7JDsmXTD=%)u&+4@cs*k%*s8PZ"g@sH5
+!;lcsqp"m8"uU&2m^HMoJcC<$JcC<$QiI'9!H\;7ec_3;kEJSh~>
+ZMsp]q>UQ<@MojX!!*@'^Ae7a5JPqP!T!hFrrRgom[O7Uh>i6#]bo>_k,pX]bCa2F@Vj$`c#mK>
+F&'.CrrCpTs!"+>GBZrHs8PjZs8,]/HY6CVrQTIoF^TdSs*ntTs,]^Em/$_mmVdUTIfS@*s1M!9
+GB6dbqu6]^:A=bmXaaf$@Y*0_s+13$s+13:s8LjUK`Cc&"IoJ\S5+S~>
+ZMspZq>UQ<@MojX!!*@'^Ae7a5JPqP!S[VCrrRgnm[O7UgAlis[M[BOjK1=Wab+#E@r93bc#dB:
+F%j%BrrCgQs!"1?GB[&Ls8PgVs7oT/H"U4Sr69=lFC9[Rs*nnQs,TXDlh^Vlm;7@QIfS7's1Cs:
+GB6mequ6][:&"YlXFF`$@Y!']s+13$s+13:s8LaRK)bQ!"I]>VRSA;~>
+ZMspUq>UQ<@MojX!!*@'^Ae7a5JPqP!T!hFrrRgom[O7Uec9d_XVf4;i2SYMa+IcB@Vj$`c#mK>
+F&'.CrrCpTs!"+>GBZrHs8PjZs8,]/HY6CVrQTIoF^TdSs*ntTs,]^Em/$_mmVdUTIfS@*s1M!9
+GB6dbqu6]^:A=bmXaaf$@Y*0_s+13$s+13:s8LRMF8tsb"I&oLPY-H~>
+ZMsp]qYpo=DClV?$NL/-0)<6]"+NOb^\%O4^SIl`SAD.XT"4k#(&+YZLUI$Zs1sVCPdpeos80'V
+K;eP>ruo?M4/g9*e,THgY26XdY(`+dqu?WGS:uTop](9AOFN25\c;Zc!/0sW(tRj+VJi@"g7EqY
+a7fQ1c^'39[JU"(J+!=9,580kK;A,=s*sJ:s36IOOOjI3qp1R\SCmf?^UNq:c]G6pqYpcn\%hsX
+J+!=9"hfhDPdpekrrMP;p\tHpe!PcXf_pC$JcC<$JcD):rn[[/s7Y:PS,i#J:4N~>
+ZMspZqYpo=DClV?$NL/-0)<6]"+NOb^\%O4^SIocS\hC]S[e\!(&+_\LU?sYs2'bFPI:Jks80*W
+K<"\@ruoBO3iC'(eGoQiYhcaeYD/:eqZ$NFS:uTqp](9AOaiA7\c;Z`!.sgN(sq<tUhupofq*kZ
+aS5`2cBX$9[/9n'J*m78,580mK;S8?s*sG9s3?OPOjsF2qTb@ZSCd`>^UEk9c]G9pqYq*"[_MjW
+J*m:9rP"2>PILVirrMM:p\tHnd[,WWfDU:#JcC<$JcD):rn@I*s7Y1MRK2ZB9n3~>
+ZMspUqYpo=DClV?$NL/-0)<6]"+NOb^\%O4^SIl`SAD.XT"4k#(&+YZLUI$Zs1sVCPdpeos80'V
+K;eP>ruo?M4/g9*e,THgY26XdY(`+dqu?WGS:uTop](9AOFN25\c;Z[!-@b6(s:^dTPL4cg7EqY
+a7fQ1c^'39[JU"(J+!=9,580kK;A,=s*sJ:s36IOOOjI3qp1R\SCmf?^UNq:c]G6pqYpcn\%hsX
+J+!=9"hfhDPdpekrrMP;p\tHpe!PcXf_pC$JcC<$JcD):rmh*ks7Y"HPQ9m28q6~>
+ZMsp]p\tHsIMDh_)sY-:s*k*bJ%t[V,(D\(ECs>]ED/Cas8S`eGBZfis1qHBGB6dbs8T$$HZMrP
+q#;PW76@H]AsE8`HZ.AO3HoOHF3jm8JSTIN:7V@Y;J1>g:A;@"rn[X.o=Y1Uk5F-:m^2uph>i-,
+JcC<$JcC<$rr;uS!JLLHh?9>Kn!m.'~>
+ZMspZp\tHsIMDh_)sY-:s*k*bJ%t[V,(D\)F%]YbE_AC`s8S`fF`gBds2%QGGB6gcs8T*)H#lcO
+q#;PX7QRHZAsE8aHuIDL3d>aLER+U6K55XO:RqIZ<G?_m:%u7!rn@F)o<n\Hj8I^4mBllogAlg)
+JcC<$JcC<$rr;uP!J:@FgB<rFl^COu~>
+ZMspUp\tHsIMDh_)sY-:s*k*bJ%t[V,(D\(ECs>]ED/Cas8S`eGBZfis1qHBGB6dbs8T$$HZMrP
+q#;PW76@H]AsE8`HZ.AO3HoOHF3jm8JSTIN:7V@Y;J1>g:A;@"rmh'jo;r&9hYl"*lEpQlh>i-,
+JcC<$JcC<$rr;uK!H\;7ec_3;kEJSh~>
+ZMsp]q#:QU6[V9%'[s_ps*k.N^OO#ls!*"eam*_:am*^CirAm)Pk4<a7K6+hg@sH5!<;pJT_%T9
+-2737+b+FunpPTCb@Hq*DaqG,\QG$lP\/&,mZ]$lmf9?]g3`S*s8LjTK_)kXf&lqf!:J&1!UQob
+IfY,:o`"sS0nK@Us+13$s+14Ls8LjUK`Cc&"IoJ\S5+S~>
+df0=Hir9#5q#:QU6[V9%'[s_ps*k.N^OO#ls!*"eam*_9aQdUBiW&^%P4@p\8H2Oog@sH6!<;pM
+T^hK8,kq*6+b+@rnpGNBb@Qt(D+D>-\6"giQ"\8.n!#*lmf]T^g3NG(s8LaQK(HDOd,Y)Z!:@u0
+!UHiaIfY/<o`"sP0S07Ts+13$s+14Ls8LaRK)bQ!"I]>VRSA;~>
+df0=Hir9#0q#:QU6[V9%'[s_ps*k.N^OO#ls!*"eam*_:am*^CirAm)Pk4<a7K6+hg@sH5!<;pJ
+T_%T9-2737+b+FunpPTCb@Hq*DaqG,\QG$lP\/&,mZ]$lmf9?]g3`S*s8LRLF7ZL7b23*J!:%c-
+!UQobIfY,:o`"sS0nK@Us+13$s+14Ls8LRMF8tsb"I&oLPY-H~>
+ZMsp]q>UYh29Gk=&?`YFs*k.N^OO#lrtU$#m/MQPm/MP8hZ)j@mf3=+%0$aLrr3>A!<;<aGCP*\
+!93eR+Fe=ts.j2?Sn,h.Dft^PoQ><AFZXr"Ir>>HpKi&rSCY7Nrn[X.o=Y1Uk5F-:m`YV2m&^)6
+!J/)ZrrMl!JcC<$JcC<$JcG`Lrn[[/s7Y:PS,i#J:4N~>
+gA_?Ur;6?dq"sdgq"adarp'L`g\LjRS2JFg*>#Bcs8RQNs1a&upAYkWC[;"MC[;"M!8IP<!:0[b
+`X`"Y^Ae->^]=E#!d0!BDZJhmrucf.mJito^RSlTm;6t;s7:;SlZP@9It)A:j7cu+K:C<"s8LaQ
+K(HDOd,Y)Z!:@u0!UHiaIfY/<o`"sbY^uh*s+13$s+14Ls8LaRK)bQ!"I]>VRSA;~>
+gA_?Ur;6?dq"sdgq"adarp'L`f(o=MS2JFg*>#Bcs8RQNs1a&upAYkWD=%:PD=%:P!8db@!:Kme
+`=2bT^&J$=_#XN#!-`pBDZJelrucf0mf0(n^ReuTmVd7?s7CGVl?,18It)A:iqHc'K:LN's8LRL
+F7ZL7b23*J!:%c-!UQobIfY,:o`"sdZ%;q+s+13$s+14Ls8LRMF8tsb"I&oLPY-H~>
+ZMsp]qu6oa9lB\)p&]]Ss8RQM^OO#krtU$%mf.cTmf.b:hZ)j@mf3=+%0$aPrr3>A!<;<aH[gNl
+BBo9l+b+Fus3G;.GC/cGDft^PoQ><AFZk/&IsYhnqn](`G?XaPs8LjTK_)kXf&lqf!:GF<JcC<$
+JcC<$YQ+UY!JLLHh?9>Kn!m.'~>
+h>[c[qt^!ZoCDG@r9s[T#4_9Vp@nF^mJd1@qu6oa9lB\)p&]]Ss8RQM^OO#krtU$#mJhZQmJhY9
+g]-L<li7")%0$gQrr3>@!<;9`H%1<jBC#?m+b+@rs3PG0FaNQDD05FMoQ53>F?Fr#IsYhoqnf4c
+F]nIMs8LaQK(HDOd,Y)Z!:>@;JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+h>[c[qt^!ZoCDG@r9s[T#4_9Vp@nF^mJd1;qu6oa9lB\)p&]]Ss8RQM^OO#krtU$%mf.cTmf.b:
+hZ)j@mf3=+%0$aPrr3>A!<;<aH[gNlBBo9l+b+Fus3G;.GC/cGDft^PoQ><AFZk/&IsYhnqn](`
+G?XaPs8LRLF7ZL7b23*J!:#.8JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]r;Qhu1;3\e!Q\ESrr[a8J%tXU,(FP!s*ntTs*k%*s8++,oBpZgs%[%WpYKN_s8+7DoCJo5
+p\uCdD=%;nI5t?*s6aep^$`L7P5CDUc1CP*KE([YhYXPXo=Fu$h>i6#]`H^HrS@PBJcC<$JcC<$
+JcDqRrn[[/s7Y:PS,i#J:4N~>
+hu=)^q=aINn*TK,l0.@0k6pM<lKdg)nFH5GqYp!a!8IGO!ie#hrr3#?=h4P7Im8Fto`$+bD=.@Q
+D=.@Q!8IPL-BdodF%61,@G:J4AH;c+.]2b-WeL3I+b+:ns7:\#<i5oaD+;5,]316kO_Dr/o;[NE
+ok3.WXoe.)s8LaQK(HDOd,Y)Z!:>@;JcC<$JcC<$YQ+UV!J:@FgB<rFl^COu~>
+hu=)^q=aINn*TK,l0.@0k6pM<lKdg)nFH5GqYp!a!7q)J!ie#hrr3#?=h4P7Im8Fto`$+bDsmXT
+DsmXT!8dbQ-'\#hF%-+(@bUS5B)qu/.B)k0W.XjE+b+@qs71Ru<i5obDaqG.]3(6nP%`,3o;I<A
+pLi@[YlOC,s8LRLF7ZL7b23*J!:#.8JcC<$JcC<$YQ+UQ!H\;7ec_3;kEJSh~>
+ZMsp]rr3)g>%$n!rrLF?\c2_\5JQgi,(FP!s*ntTs*k%*s8STaGB6Nes1qHBGB[Nss8S`qGBZrH
+p\uCu7\]8LVCPj#s6ae_EHPN-ci;=>BQnYuOT52UC3sSoqmuh,h>i6#]`H^HrS@PBJcC<$JcC<$
+JcDqRrn[[/s7Y:PS,i#J:4N~>
+ir9MfqtTjTn*K?'k2bR]i8FRk%H-4)j5oFelg=35pA4dZrrCgQrr_[m@.F3q!RCJNrrR[7^[qIL
+Ir4TQIr4TQIfS7's-uf+F%j%B_G+ZeG@LXQs.WY?G?'e"rumFmU?hiV/6pd+m;4\!FBs"7s3Q1-
+GB[&Ls7oT/H"U4S])Vca!.sgN!RTm*gApVls+13$s+13$s0)J%gAup+p=f_=!:-(JJ,~>
+ir9MfqtTjTn*K?'k2bR]i8FRk%H-4)j5oFelg=35pA4dZrrCXLrr_[m@.F3q!RCJNrrR[7^[qIL
+IrFcTIrFcTIfS@*s-ui.F&'.C_+nTdG@LXQs.EP>G>aOsrumInU?qoW.pCL'mVat&F^0"6s3H+,
+GBZrHs8,]/HY6CV])Vc\!-@b6!Qs9tec=uds+13$s+13$s0)J%ecBjlp=9A2!9]S=J,~>
+ZMt*bs8TS`Yd+6.^[hCK^UNq:^UNq:^OP\Os7`IEK=1UVs1sVCR*pKas7`UIK;A,5rufXLXR,u'
+:keWCmVcX7KpL'^s8132K7fuks8U?%Iur6ls8LjTK_)kXf&lqf!:GF<JcC<$JcC<$YQ+UY!JLLH
+h?9>Kn!m.'~>
+j8TYeq"4+ElKI?hi838Dg=b-XfDjJ5g"P3:hr3VXkj.[-p%n[[rrq0Ws0sefZ2aj=o)BoK[eBa9
+[eBa9J*m:9or*Ls[/9n'^l*]/dXV;spT0($VXsQ^+O?.Oli4dtLA1`8D.KT!QI,O/qpCdaK;S8?
+s3?OPOjprArn@F)o<n\Hj8I^4m=G:gs+13$s+13Rs8LaRK)bQ!"I]>VRSA;~>
+j8TYeq"4+ElKI?hi838Dg=b-XfDjJ5g"P3:hr3VXkj.[-p%n[[rrq!Rs0sefZ2aj=o)BoK\+]j:
+\+]j:J+!@:pS`^s[JU"(_2Ef1dXV;spT0""V"=?\+O?.Nm/OmuL%bQ7De,f#QI#I.qpCd`K;A,=
+s36IOOOguBrmh'jo;r&9hYl"*l@Jtds+13$s+13Rs8LRMF8tsb"I&oLPY-H~>
+ZMt'aoOq.fJcG0<#l19*\,ZKrDh"V`rn[X.o=Y1Uk5F-:mc"0HmXO'm!IsP1rrMP;JcC<$JcC<$
+L&_//!JLLHh?9>Kn!m.'~>
+jo6\+q=X:FlK7-bhV6`8e^Msod*U+bd*U1geCE1(gtq#NkNhU-pAFU`"P`Q^;X/i5n,E^npnhT2
+s8VJ'J#32EgAlis[K4b8rS%>>iVrrGJ)1,*J*lq/!UYAfs+13$s+13(s8LaRK)bQ!"I]>VRSA;~>
+jo6\+q=X:FlK7-bhV6`8e^Msod*U+bd*U1geCE1(gtq#NkNhU-pAFU`"P33Y;X/i5mf*RgUggh5
+s6afTV>pPG!-@b6!Qs9tec>!orrMP;h>[M*me-S\mXKffJcC<$JcCH(rmh*ks7Y"HPQ9m28q6~>
+ZMt!+1STI#qYpQLqL8Ns_>aH@n>fTDkl:\RN0pIArn[X.o=Y1Uk5F-:mc"0Hh>lC3!<D!Orre,F
+s5l>lrrq\\ItO]oJcC<$JcC<$\,ZHa!JLLHh?9>Kn!m.'~>
+k5Q%jp[dh<kMtITg"+[#ccs\Vao'3lai_fNcHt"hf@o'=jQPt"o_J4\!iRoLJcGTH!8.-t!J82f
+rsA.n=+o`9s7(r4V>pPL!.sgN!RTm*gApX"rrLjSh>[KUg\CdOL[Y9'3n=66l_&f]WqCrCJcC<$
+JcE4Zrn@I*s7Y1MRK2ZB9n3~>
+k5Q%jp[dh<kMtITg"+[#ccs\Vao'3lai_fNcHt"hf@o'=jQPt"o_J4\!i.WHJcGTH!8@:!!J/)d
+rsA1q<e]c;s72,9V>pPG!-@b6!Qs9tec>!orrLsVh>[KUhY@*RL[P3)3S"-5lC`WZW:tlCJcC<$
+JcE4Zrmh*ks7Y"HPQ9m28q6~>
+[/U7(G<Ou;s7uZpgA6:"J\h?c"7WR[e,K@Kqpa8ps8LjTK_)kXf&lqf!:JhG!T!h4rrE,Vq#:I&
+hZ*>\ec,es:31JOS:U]ks+13$s0r%-h>r<0p>,qB!:QFQJ,~>
+kPl4lp$qD4jP\hHe^Ddfb/hT@_nj1f^_=Q$_o0R9bK\D_f%Ss=jlu4(q#:-i"8R.'j+77+rrC^J
+IfY/<rr3;oY`mN7s8VrDf;8NHgAlis[K4b8rS%>>iVrr5!8[YU!8I;K":3i`ot&`S#5rgCF`U?I
+JcC<$JcC<$\,ZH^!J:@FgB<rFl^COu~>
+kPl4lp$qD4jP\hHe^Ddfb/hT@_nj1f^_=Q$_o0R9bK\D_f%Ss=jlu4(q#:-i"8R.&j+77+rrCdL
+IfY,:rr3)iZ'<`:rrW)IfVSWIec9d_XT?T$rRLu6iVrr8!8[YU!8dMN":3lapUSiS"a<^_F&&6V
+s+13$s+13Zs8LRMF8tsb"I&oLPY-H~>
+[Jp?U2jE-Ls+ULPh>i6$h?':Gk5F-UmbX[jON7(pqp1R\LUI$Zs*rU]`W,h?LP)Q"r;S/$!<<)8
+ORDi@esqG[chmaWWjA_b^T+c$LU6:GrRRKmQI#I.rrCpOrt((gGM;J7s8RSjMgr:ZLP*/:rs\kW
+S;!9Tqu=F2Z`<$`rrVo'^\Ig5l3sK[mYiHCs+13$s+13Zs8LjUK`Cc&"IoJ\S5+S~>
+l2MLtq=O.Ak2P4Me^DadaMl$3^:_(h\c'#P\[oDd^VRh-air)[f%T$AkNqa4rVZZtco73CJcCH(
+rn@F)o\'A8UZ;=-)sl@SKosFLs810/K86i2s8RSuO2V(qZA4(4p\b%=gAq9R_N40[rRRKmQI,O/
+^T+T>iP2G'NJOn)s8CN=KpL*_s8N)Rq>V"c!-Qr]J,fOuaGkb^b)(b\rr3E*esqG[d/3jXWj8Y`
+rVlrm[_MV;#3QJloC%VbJcC<$JcC<$\,ZH^!J:@FgB<rFl^COu~>
+l2MLtq=O.Ak2P4Me^DadaMl$3^:_(h\c'#P\[oDd^VRh-air)[f%T$AkNqa4rVZZtco73>JcCH(
+rmh'jo[X)0T&0Fs)sZ:SK94.Is81-.K86l3s8RT"ON%7sZ%mt1p\b%=h>mTU_3"*YrRRKmQI#I.
+^T+W?ikMM&MheY(s8CN=KpL'^s8N)Uq>V"a!-d/bJ,fOuabtYZabPMZrr3E*esqG[chmaWWjA_b
+rVlrm\%h_<#3lVmoBqP`JcC<$JcC<$\,ZHY!H\;7ec_3;kEJSh~>
+\,QX0Kg+5jhLY]\s8LjUK`Cc6"5[X6k5F-Uc\Z+R@Vj$`cZ`iBG>>RGrr?tQ^&P$7HZMrPr;S/$
+!<9l5K^SQ_JSTI;Fj9r92f4f9Ili.4Alc)7dt):Y@!0`orrCpOrud4"GM:mRs8N(CLKZ]^K3gS0
+q>\opCNj0/c2W8PD3WoUrrVh_VYL/qk&:"os0WPls+13$s+13Zs8LjUK`Cc&"IoJ\S5+S~>
+lMhY!q=O+>jl"nFe'H4X`501"\[SuQZEaD5s03QL['dBR]YD>&aNW#\f\PNKlgXTGs8W"N52-%k
+JcCH(rn@I*s7Yg^gh(]hrS&:8Lh([=CrHA"G@G];9Xb!$!,lYas/K@MF&/>(s!QP$s1hWcn+Y=a
+CNa-/c2W8PD3E\(4+Mus<NcAOK55X=Fj9sd!8I>L+H6ADf\6E+rr@8">rm1`?T@ZQs3u[:G%#O<
+s*ltEP2-$9!qVkXq#:Q[D>!r/Zl"AoJcC<$JcE4Zrn@I*s7Y1MRK2ZB9n3~>
+lMhY!q=O+>jl"nFe'H4X`501"\[SuQZEaD5s03QL['dBR]YD>&aNW#\f\PNKlgXTGs8W"N52-%f
+JcCH(rmh*ks7Y^[g159]rRMq2M.1U:CrQG#G@Gc?:::-%!,lYds/9+JF&&8's!QY's1qTdme5+\
+CNj0/c2W8PD3Wn,4+Dlp<j)JOJSTI;Fj9sd!8dPO+H$5Dg>2i0rr@7u=ugeZ?9.WQs3lO7G@5R<
+s*ltEPhuB=!q`"[q#:Q\Dtj;3[1n2lJcC<$JcE4Zrmh*ks7Y"HPQ9m28q6~>
+\Glce5)&q7s5&>,L&_//!JLLHh?1GdGNSk\*11-8nB6NmrK:L)oBpZgs8N(?g@tIrT_%T9-27B<
+-f+j:6?i&$rKLp9nA/@iqgUW'kkfio\+\?UKDh$Hamd,ONq`PRhY@*m!8db4!<<'!R/>S;R/>S;
+ipco2B$'PY>`S]23Mu$;rVlrtjQ?7;#5digpUsaWJcC<$JcC<$\,ZHa!JLLHh?9>Kn!m.'~>
+li0!Eq=F%=jPS\Ad*0SL^qI:e['?g:XK&8!W2Q\qX/rJ.ZF%*P^;7e1c-k1ti8s7mp&3T.L&CuN
+gO]BYs8LaRK)bQ!"1h3Lj8I^PQ=6rcb(R/"OBo]mm;khurr@2qp%pG9naD\fp\k+>gAnlPGOb_3
+Q"\8._-DusIlaLjqL:`=p=*8urKV';nA/@hp\t6Jq#;E9g]-".s8N(dqq;%9qq;&/nGSVcaRI#N
+NVe2dVs!pTrrW,XjnSi[qsFFX]NKT4s+13$s+13Zs8LaRK)bQ!"I]>VRSA;~>
+li0!Eq=F%=jPS\Ad*0SL^qI:e['?g:XK&8!W2Q\qX/rJ.ZF%*P^;7e1c-k1ti8s7mp&3T.L&CuN
+eq*jTs8LRMF8tsb"1:aBhYl"FP[LT^bD!>%P$Z&tmW1hsrr@,op\QP8oBqhhp\k+>h>k5UGOtk5
+P\/&,_-E#tIlXCiqgUi>p=3?!rKLp9nA/@ip\t6Mq#;E9hZ)F4s8N(dqq;%;qq;&0nGSS`amd,O
+Nr+;dVWdpUrrW/[k4nr\qsOLY]ioc6s+13$s+13Zs8LRMF8tsb"I&oLPY-H~>
+])Mm3OuLbdrrCo,s+ULPh>r<0p>,nb:3Yk!hAg`TirAi4k4Ee?pAb03%0->-aoDD+!-`pBDZJeq
+s!QY'=s8k)s7CFqH[g5uEU\HgjT#70B'0-]Dh%D%4*uI$2f[jW!8dMN*<=srh>mTU!8@JQ!8@JQ
+!8d/9FZXr"G;jO2Iq7X-rrgGrF+`V+s+13$s+13Zs8LjUK`Cc&"IoJ\S5+S~>
+li.dso^:r'hV$E)b/V92\[JfIXK&1qUna[_TbsN!V5C2lXg#.@]>)8(bg=nohrX.lNAo5_rrCf)
+s+ULPgAup+p=f\\9m,LpgDk?OirAi3jn*Y;p&G'3%fcP/aT);+!d0!BDZJhrs!QP$=sAk(s7LOs
+H@L,tEUeNhj8]./B'''[D1D5%4*lC#2f[mX!8I;K*<=jogAq9R!8%8N!8%8N!8Ho6Fut#"G;jO3
+Iq7U,rrgJsF+NG(s+13$s+13Zs8LaRK)bQ!"I]>VRSA;~>
+li.dso^:r'hV$E)b/V92\[JfIXK&1qUna[_TbsN!V5C2lXg#.@]>)8(bg=nohrX.lNAo5_rrCW$
+s+ULPecBjlp=9>R8orkfef8aHirAi4k4Ee?pAb03%0->-aoDD+!-`pBDZJeqs!QY'=s8k)s7CFq
+H[g5uEU\HgjT#70B'0-]Dh%D%4*uI$2f[jW!8dMN*<=srh>mTU!8@JQ!8@JQ!8d/9FZXr"G;jO2
+Iq7X-rrgGrF+`V+s+13$s+13Zs8LRMF8tsb"I&oLPY-H~>
+]Dhum7X+\+rrCo,s+ULPh>r<0p>,nb:3Yk!hAgZOirAi(g@TN3pAb03%0->-hZ*W@!.03FHY;XB
+s!QY'R$9&Js7CFsI=HZbW:YRXmf3<:DsmYnDh%D%4ahg.EN&1&!8dMN*<=srh>mTU!8dbU!8dbU
+!8d/9FZk/&I;u4XIrFcCrrfT=J$o$%s+13$s+13Ys8LjUK`Cc&"IoJ\S5+S~>
+m/Iq!o^:u(hUp<&ai(s+\$N9=W268^St):=rL"IjS"61FUSb#lYdCpQ_8XRCe_8p(6#cAlrrCf)
+s+ULPgAup+p=f\\9m,LpgDk9KirAi(g@TK0p&G'3%0->-g].<<!-s'DHY;[Cs!QP$R?T2Ls7CCq
+I"-QaWV(aXmJm39D=.AjD1D2"4FDX,EN/:(!8I;K*<=jogAq9R!8IPR!8IPR!8Ho5F?Fr#I;u7Z
+Ir4T@rrfWAICAg"s+13$s+13Ys8LaRK)bQ!"I]>VRSA;~>
+m/Iq!o^:u(hUp<&ai(s+\$N9=W268^St):=rL"IjS"61FUSb#lYdCpQ_8XRCe_8p(6#cAlrrCW$
+s+ULPecBjlp=9>R8orkfef8[CirAi(g@TN3pAb03%0->-hZ*W@!.03FHY;XBs!QY'R$9&Js7CFs
+I=HZbW:YRXmf3<:DsmYnDh%D%4ahg.EN&1&!8dMN*<=srh>mTU!8dbU!8dbU!8d/9FZk/&I;u4X
+IrFcCrrfT=J$o$%s+13$s+13Ys8LRMF8tsb"I&oLPY-H~>
+]`/&,1WB4j!8`;,L&_//!JLLHh?1GdGNSk\8<I/[nB6*UrK(:%oBpZgs8N)Us8VsFW:TVZKE(tr
+qu>LQqt!Qdp\Btcc1B2G_>f"'mf3<:DsmYnDh%_KB[-.nQGNV$!8dMN*<=gnh>mTU!8dbU!8dbU
+!8d/BP%`,3c'H3GIrFcPrrW/[k4nrYl7meFrp#(7JcC<$JcE4Zrn[[/s7Y:PS,i#J:4N~>
+mJf*Ap@%;-hUp<%aMYa&[BQa2V4jKMR?s2&P*1riP*;,qQ^XG:U8FolZF7B\`6-EUMCl+!nbE(_
+!8E))L&_/,!J:@FgB5#]FlWGT8<@)[nB-$Tr/Y+!na1Bes8N)Rs8VmEVXa8XL&_1sq>]1LqsdNh
+p\9kabOWrF_Z,+&mJm39D=.AjD1DJGBZotlQbre&!8I;K*<=^kgAq9R!8IPR!8IPR!8Ho=O_Dr/
+cBlEJIr4TMrrW,XjnSiXkq[hGrp,.8JcC<$JcE4Zrn@I*s7Y1MRK2ZB9n3~>
+mJf*Ap@%;-hUp<%aMYa&[BQa2V4jKMR?s2&P*1riP*;,qQ^XG:U8FolZF7B\`6-EUMCl+!nbE(_
+!7l`$L&_/'!H\;7ecW<PF5HlH8<$lWnB6*UrK(:%oBpZgs8N)Us8VsFW:TVZKE(trqu>LQqt!Qd
+p\Btcc1B2G_>f"'mf3<:DsmYnDh%_KB[-.nQGNV$!8dMN*<=gnh>mTU!8dbU!8dbU!8d/BP%`,3
+c'H3GIrFcPrrW/[k4nrYl7meFrp#(7JcC<$JcE4Zrmh*ks7Y"HPQ9m28q6~>
+^Ae<#;J5XtrrCo,s+ULPh>r<0p>,nb:3Yk!h@e"a@!,pp`W+2*@Wulg[K$7,hZ!O1TNZP`;NUqY
+:?ql9!<<)@,c&i6I;!h8EQA*/DsmZ*IrFcTmVdUTc[BJNA9#ZirrCpNruE7ug>2i0rrCpUrrCpU
+rrCpDs3H+,G@Y^6s*ntTqu6`iS>Q)]!kA;@rG-uaJcC<$JcE4Zrn[[/s7Y:PS,i#J:4N~>
+mf,9Fp[RS2hq?K'aMY^$Z`^=*U7Rg?P`_#dN/ELLM2I4MNf]EhR%'_CVlR&0]"c1o6W_^pkO%m=
+rr2uQJcCH(rn@I*s7Y1L\kR>-rS%t,K4/n4D8lP"FCB<59Xb!$!8IMQ187oqG?'e*s%V\VgAq9R
+asO"6d!]SOAol&nIr4TQs*nnQs6XZQs3Q1-G@kp;s8N)Rq#;?WCY7AAs8N)Rs8N)Rs8N)RmJkO]
+BQn'0aT$a,mJHnbo9uQOrrTV/A,U1os+13$s+13Zs8LaRK)bQ!"I]>VRSA;~>
+mf,9Fp[RS2hq?K'aMY^$Z`^=*U7Rg?P`_#dN/ELLM2I4MNf]EhR%'_CVlR&0]"c1o6W_^pkO%m=
+rr2uLJcCH(rmh*ks7Y"G[7YMsrRMV%K4&h2CrQG!F^fQ9:::-%!8d_T18%fpG>aP&s%_kZh>mTU
+aX!\0c[BJNA9#ZiIrFcTs*ntTs6afTs3H+,G@Y^6s8N)Uq#;?XCYIVFs8N)Us8N)Us8N)Umf1U]
+BQn!,a8^X-med"coUMfRrrT_2A,U1os+13$s+13Zs8LRMF8tsb"I&oLPY-H~>
+^]+A>0t?uX!8`;,L&_//!JLLHh?1GdGNSk\'(4JFK94.Is81-.K7gT/s8RT:rr3E$XFl/$oDei?
+mf2^)rr414XO[3qR"LXHq>\4=pAb0-\+]jq\%ht?d?oQNbPD2<J+!+3*M@o9mXP9:J+!@:J+!@:
+J+!%1qpCd`Pfrn&^UNq6rrVo'^\Ig/c23!As+13$s+13Zs8LjUK`Cc&"IoJ\S5+S~>
+mf+4$oBk\ug=4Eh_nERcXf/%fS!T>#NJ`OHKS05T)2!TsLl7:UPaIu7V5g`+\V);md+7"3kjJ-C
+rrCf)s+ULPgAup+p=f\\9m,LpgCil+SqN6Ip](*8Q%Odtqu?\GmJd+opT0($VXsifJ*m:'J,]Hl
+S$(?>d?oTObk_:R[eBb$^UEk9p9qa9qpCdaPg&t's*sG2ruIb`f^41gs*sG9s*sG9s*sG0s8132
+KTs^Vs1c#9qu6`k[_MV;!6k=iJcC<$JcC<$\,ZH^!J:@FgB<rFl^COu~>
+mf+4$oBk\ug=4Eh_nERcXf/%fS!T>#NJ`OHKS05T)2!TsLl7:UPaIu7V5g`+\V);md+7"3kjJ-C
+rrCW$s+ULPecBjlp=9>R8orkfee79%SqE-FpAb$9Q@jgtqu?\Gmf*4ppT0""V"=WdJ+!@)J,]Hl
+S?19<d?oQNbPD1Q\+]k%^UNq:p:%g:qpCd`Pfrn&s*sJ3ruIb^g?sIjs*sJ:s*sJ:s*sJ1s8132
+K9XRTs1c&:qu6`k\%h_<!6tCjJcC<$JcC<$\,ZHY!H\;7ec_3;kEJSh~>
+_>aW-?s<!lrrCo,s+ULPh>r<0p>,nb:3Yk!h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+n,F@)p$_,(gt'fn_nNXdXf/"dR?`noM2$Y5IXHM@H6%?\It<9.MN3jcS"HLUUdRPT`QQZ\hW3tl
+qZ$TMJcCH(rn@I*s7Y1L\kR>-rS%>>JcC<$JcC<$JcDqRrn@I*s7Y1MRK2ZB9n3~>
+n,F@)p$_,(gt'fn_nNXdXf/"dR?`noM2$Y5IXHM@H6%?\It<9.MN3jcS"HLUUdRPT`QQZ\hW3tl
+qZ$THJcCH(rmh*ks7Y"G[7YMsrRLu6JcC<$JcC<$JcDqRrmh*ks7Y"HPQ9m28q6~>
+_>aPBX7ZDlhLY]\s8LjUK`Cc&"2.HRk5F-:m^iDugA6:!K7X&Rs+13$s+14Ms8LjUK`Cc&"IoJ\
+S5+S~>
+n,F@%o'>Anf[7m]^U^\QVkT`LPE(NTJq&/nGBJ!+EZT:DFa&.ZJ:iW8OHc0*Uj$sg]"lA2e(N[A
+mI^DXgO]BYs8LaRK)bQ!"1h3Lj8I^4mCN;tf_U'tKn98Ts+13$s+14Ms8LaRK)bQ!"I]>VRSA;~>
+n,F@%o'>Anf[7m]^U^\QVkT`LPE(NTJq&/nGBJ!+EZT:DFa&.ZJ:iW8OHc0*Uj$sg]"lA2e(N[A
+mI^DXeq*jTs8LRMF8tsb"1:aBhYl"*lFQuqgA6:!K7X&Rs+13$s+14Ms8LRMF8tsb"I&oLPY-H~>
+ZMsp]JcCH(rn[[/s7Y:O]hWe6rS@PB])McaqL8KtJcC<$JcC<$JcGcMrn[[/s7Y:PS,i#J:4N~>
+nGb]Lp$V#%g=+<e^q-nUW1oiLP)Y9NIsZE^EGo]1CMIU"Ci434Fa8@cKo1qUR@^4SYdV3]aj8Mm
+j6?(/s4`,)L&_/,!J:@FgB5#]FlWGT!:@At!8.-t!/6"(qu?]q!r`#mr:pHkqu$DDs+13$s-*K^
+gAup+p=f_=!:-(JJ,~>
+nGb]Lp$V#%g=+<e^q-nUW1oiLP)Y9NIsZE^EGo]1CMIU"Ci434Fa8@cKo1qUR@^4SYdV3]aj8Mm
+j6?(/s42c$L&_/'!H\;7ecW<PF5HlH!:%/q!8@:!!/#k&qu?]q!r`#mr:pHkqu$DDs+13$s-*K^
+ecBjlp=9A2!9]S=J,~>
+ZMsp]JcCH(rn[[/s7Y:O]hWe6rS@PBJcC<$JcC<$JcDqRrn[[/s7Y:PS,i#J:4N~>
+nGb]Io'>Amf$MOV]XG#CURdd8NJE+6H$++DC1q0h@q&nWA7fLjDK9oHItWZ=PaS/?X0K1K`66T]
+hra=urnE#(L&_/,!J:@FgB5#]FlWGT!:>@;YQ#"0r;-3^p%7hGnaZ,JnH\XVo_/%Tr;M9IJcC<$
+R/d0?!J:@FgB<rFl^COu~>
+nGb]Io'>Amf$MOV]XG#CURdd8NJE+6H$++DC1q0h@q&nWA7fLjDK9oHItWZ=PaS/?X0K1K`66T]
+hra=urmlZ#L&_/'!H\;7ecW<PF5HlH!:#.8YQ#"0r;-3^p%7hGnaZ,JnH\XVo_/%Tr;M9IJcC<$
+R/d0:!H\;7ec_3;kEJSh~>
+ZMsp]JcGWI!>++Is8LjUK`Cc&"2.HRk5F-:mXbChs+13$s+13Rs8LjUK`Cc&"IoJ\S5+S~>
+nc(iOp$V#%g=+9b^UUSMV4X0>NJE+5GB7Y:An,4T>[(B9>?tTEA7o[rFEr=fM3!mjTr5$"]"uG4
+e_K3MnbV!ks82fs&DrKIrn@I*s7Y1L\kR>-rS%>>JcE"T$iKhoo^_M>mHa'%l2KoHkmH_Am-a?4
+oChtWrdk*#s+13>s8LaRK)bQ!"I]>VRSA;~>
+nc(iOp$V#%g=+9b^UUSMV4X0>NJE+5GB7Y:An,4T>[(B9>?tTEA7o[rFEr=fM3!mjTr5$"]"uG4
+e_K3MnbUgfs82fs&DiEHrmh*ks7Y"G[7YMsrRLu6JcE"T$iKhoo^_M>mHa'%l2KoHkmH_Am-a?4
+oChtWrdk*#s+13>s8LRMF8tsb"I&oLPY-H~>
+ZMsp]XoABNq#CDEg&D'QhMqR7h>r<0p>,nb:3Yk!h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQ
+J,~>
+nc'X+oBbSqf?hXV]<n`=Tpq:,Lk:"uEc#K"AS,F\?iF@Q?X?f;?"%;YDKC&OKSkkWS>3'f[_9W&
+db3RAme5D;rr@QE!!%N%rrE,SNW9"4!J:@FgB5#]FlWGT!:>@;[/UU7qY0XPn*K?'k2bR^iV_UC
+iSrnYjlbmomdTiAqYl'GJcC<$ScA]D!J:@FgB<rFl^COu~>
+nc'X+oBbSqf?hXV]<n`=Tpq:,Lk:"uEc#K"AS,F\?iF@Q?X?f;?"%;YDKC&OKSkkWS>3'f[_9W&
+db3RAme556rr@QE!!%N%rrE,VNW9"/!H\;7ecW<PF5HlH!:#.8[/UU7qY0XPn*K?'k2bR^iV_UC
+iSrnYjlbmomdTiAqYl'GJcC<$ScA]?!H\;7ec_3;kEJSh~>
+ZMsp]XT/<MrVunIq#:ZtXZ6eAT_GBkC]=>R0nfT$@h8oDn,NCfXYBf!XoB4<&@MP7+TMpSc'A>.
+h>r<0p>,nb:3Yk!h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+o)BX-p[IG,gXOKf^UUPKUn*g5MM$>$EboAt?+p(6*Tg0s<a&g>BPqm:It`iER%L7WZb!uocdpq5
+lgic2s8RTIs8RTDrsAS*3XdX8pS_A3rr3rlLB%!Z&-u;)s8N)%1^"r$ru;"MZN$dI!"N5WQ2gj<
+!J:@FgB5#]FlWGT!:>@;[f7WPqY'OMm-3]oio&\KgY1?5f[na-f\,!6h;@2Ok32.!o(DkYJcC<$
+JcDABrn@I*s7Y1MRK2ZB9n3~>
+o)BX-p[IG,gXOKf^UUPKUn*g5MM$>$EboAt?+p(6*Tg0s<a&g>BPqm:It`iER%L7WZb!uocdpq5
+lgiT-s8RTIs8RTDrsAS)3=IL4pS_D6rr3rmK`CdV&-u2&s8N)$0`WB!rtk_I[K!'H!"<&UQ2gj7
+!H\;7ecW<PF5HlH!:#.8[f7WPqY'OMm-3]oio&\KgY1?5f[na-f\,!6h;@2Ok32.!o(DkYJcC<$
+JcDABrmh*ks7Y"HPQ9m28q6~>
+ZMsp]X8i3Ls8W+Kp\u_E<h/068u1$E&HDd]!9aAc;Wln/9)nnk6Jh`h&HDb1hZ*$EXnUCMGP@F'
+rn[[/s7Y:O]hWe6rS@PBJcC<$JcC<$JcDqRrn[[/s7Y:PS,i#J:4N~>
+o)B^.p$V##f[7jZ]X=o?TUD"&L4=JiD.d9^=1eM1qtV8k8PDr[=C#EMDKL5VLQ7XiU8bB+^;\=F
+g>_Adf;nrOJ,fQKJ+rsmY$%:RPY%\%@2/V=f)Y"6>ufqB8P/s^!(#N>I1ZGY!8IPB"Kq@G>Bfh-
+s8LaRK)bQ!"1h3Lj8I^4m=G;Hrt5/&oC)&0jl51Qg=Y!+da?FgrQc&%dF-Lof@ep8iT01emdg&I
+JcC<$JcDDCrn@I*s7Y1MRK2ZB9n3~>
+o)B^.p$V##f[7jZ]X=o?TUD"&L4=JiD.d9^=1eM1qtV8k8PDr[=C#EMDKL5VLQ7XiU8bB+^;\=F
+g>_Add]<EJJ,fQKJ+rsmXB(kNPY.b&?4d/:ec=n5>#OP?8kT-`!(,QBHP$5W!8dbE!3Q"H>'K_,
+s8LRMF8tsb"1:aBhYl"*l@JuErt5/&oC)&0jl51Qg=Y!+da?FgrQc&%dF-Lof@ep8iT01emdg&I
+JcC<$JcDDCrmh*ks7Y"HPQ9m28q6~>
+ZMsp^WrN$Ip\uW<H[#5amVd=@IgEafHW'n<!:Tsfh>m$E!58F4h>mTU!8dbE!2]Ghqj%3\h>r<0
+p>,nb:3Yk!h>ltps+13$s+13$s0)J%h>r<0p>,qB!:QFQJ,~>
+o)CuOoBbPof$DCP\[&93SX,=nJpVWXBOY4I;7QY75s@Cm4?Ynp77g6Q=C,NQE-H_`MijC!VQI5;
+_TL9YhrjFVWrN$Ip\u`?I<YAamr*FAJIK-iGu=V9"RH*fhZ3-F!5AL5gAq9R!8IPB"JYYfq>$<U
+rn@I*s7Y1L\kR>-rS%>>JcE:\')hXunEfB"iSE5>eC)^hbf\&Kr5TGkai_fOcdC4mg"bKFkN_L,
+p\f[CJcC<$UAt5I!J:@FgB<rFl^COu~>
+o)CuOoBbPof$DCP\[&93SX,=nJpVWXBOY4I;7QY75s@Cm4?Ynp77g6Q=C,NQE-H_`MijC!VQI5;
+_TL9YhrjFQWrN$Ip\uW<H[#5amVd=@IgEafHW'n<!:Tsfh>m$E!58F4h>mTU!8dbE!2]Ghqj%3\
+ecBjlp=9>R8orkfec=uds1/.BrV?*Tm-*Nhh:gK1da6:`b/qa&`tHJ8b0/&UdF6\"gu%/TlL+9<
+rIP!"s+13Es8LRMF8tsb"I&oLPY-H~>
+ZMsp^WW3!JpAY0]Du9SAC[/07A,dCRs5*VQ'A!0`hZ*W4!<<'!hZ*Vh8e<7lg6M^;h>r<0p>,nb
+:3Yk!h>m!%rrE\fdJj4YhVeG6L]7;Wicc(N.D>`\"kH!G#ZBi:s+13$s+13\s8LjUK`Cc&"IoJ\
+S5+S~>
+o)CuNn`o/heBPtH\$2g*RZi\aIX#jIA6i869Xau-3B&fP1c73Q5!qk8;d!I>CiaoQLQ7XjUoUf3
+^rOdPh<""MWW3!JpAY0^Du9SAC[89;AcEaYs53\R'A*6ag].<.!<<'!g].;f9b8RmfTlL9gAup+
+p=f\\9m,LpgApX!rrE\gdJj4Yhr4S:rJ-7/rrqG,()A=4rr3/R70j<%kJ[B7qtK[Kl/gm[g"+Wu
+c-",H`59@+^](tI^Cn?!_o9[<bg+Vdf\GBEkNq^2r.4m!s+13Fs8LaRK)bQ!"I]>VRSA;~>
+o)CuNn`o/heBPtH\$2g*RZi\aIX#jIA6i869Xau-3B&fP1c73Q5!qk8;d!I>CiaoQLQ7XjUoUf3
+^rOdPh<""HWW3!JpAY0]Du9SAC[/07A,dCRs5*VQ'A!0`hZ*W4!<<'!hZ*Vh8e<7lg6M^;ecBjl
+p=9>R8orkfec>!nrrE\fdJj4YhVeG6L]7;Wicc(N.D>`\"kH!G#ZBj(rtPA)o'P]'iSE2<e'H:]
+aMl*7_8*hb^Akq\^r"".a2uQNdFHn)hrEndnFc^1s+13$s.fVnecBjlp=9A2!9]S=J,~>
+ZMsp^SGt,:H[GYiqr6c<il2PC)#sX1!;HNnpWig=!8dbUh>mTU!8dbM`rH(m>'K_,s8LjUK`Cc&
+"2.HRk5F-:mbn*G!8c-'!<D!:rri)AHR41@rrn<U\\3q5rr3-FF6DC`6@o/fs+13$s1/1/h>r<0
+p>,qB!:QFQJ,~>
+o)D#MnEAibd`]P@[B6<uR$!8YHZX.<?s-E&8$r<$1G:=2/1rV53'BW":K:V.BlJ9FKoD4aTr>3)
+^;eFIguI\Grgj'>q0@8]s81j>s5Cj,^)[1Qo)SC^s7ak>rrCgRs4[PRrrCgRpW*=6fNEFmQN-s=
+!J:@FgB5#]FlWGT!:A_E!<Cm%rrE,Sj8T8Vc?ggdrr3If:Un-!'`7q-+Ecl)=[C%,(&IUmlf[9a
+g=F]tbK.Z>^qI@k\@8sG[M63\\\#Pi_8OC:c-b%ngu7A[mdp7*s+13$s.o\ogAup+p=f_=!:-(J
+J,~>
+o)D#MnEAibd`]P@[B6<uR$!8YHZX.<?s-E&8$r<$1G:=2/1rV53'BW":K:V.BlJ9FKoD4aTr>3)
+^;eFIguI\Crgj'>qg3\es81g<s5M$0]bpeLpAjsfs7ah=rrCpUs5!bUrrCpUpW!75g0/^pQN-s8
+!H\;7ecW<PF5HlH!:&MB!<D!(rrE,Vj8T8Vc?gjerr3.[::\&s&H;\5+`li'>!g4.(&IUmlf[9a
+g=F]tbK.Z>^qI@k\@8sG[M63\\\#Pi_8OC:c-b%ngu7A[mdp7*s+13$s.o\oecBjlp=9A2!9]S=
+J,~>
+ZMsp^S,W\k<hSWK8Y#e[!Z3)-rr3m7>3G'P3WK*ZhZ*W4!<<'!f)PIM^%]rUHi'-/rn[[/s7Y:O
+]hWe6rSAL]]gW2MORE/CTIgE\C\Rl/!3IE's7^"7#ZC-hrtlRQ&@MN<X_1\RdUNgs;T8\(Dc0mM
+.A6G1ru1d:@h8oDn,NCfXYBf!XoB4<&@MN<XW`XE;Z?[t+e6gUrrVV,J,'$ZlC;04J,fQ?F*mfa
+rrD6^h>m<Ms4.1$s+13$s+13\s8LjUK`Cc&"IoJ\S5+S~>
+oD_/Vp?q,%f[7gX]!JK7SX,=lJ9c0NA6i538OB`_Xt2%K,U=]c/M]:L6qU<Y?Y4.sH\.-;R%L:Z
+[CsN%e(WgGcMa:5#-(arje>G>rr3$>,^o[l)HBr#k?U4MrrCgRs4[PRrrCOJo*E)%c<#AgQN-s=
+!J:@FgB5#]FlWGT)sb()$m^r%s7`6?#S:_Es8N)!+H$3nAIo,In,32&)upPUrrB'1<Q*6m&.DFS
+s6XZ%?OeQWp%\P*qlXKA#Z^?nrrB2Y"<a`E)upPUrrB&AMK)YqrrOI;cMdbEm;7@Jrtajh?S$^,
+s7:;Yqu-Blj8\!:p](9B!6>*orqZ3TlK-sZf@/'ha2>^+]"#/SZEUO8Y-"k0YHY:<[C<]Z^V\"4
+c-b(qhW*heo([e9JcC<$V>pPL!J:@FgB<rFl^COu~>
+oD_/Vp?q,%f[7gX]!JK7SX,=lJ9c0NA6i538OB`_Xt2%K,U=]c/M]:L6qU<Y?Y4.sH\.-;R%L:Z
+[CsN%e(WgGb5Ik1#,kRqkFbD:rr3$:+aa4g)H'c%k?9nGrrCpUs5!bUrrCXMpB\J,dT1_lQN-s8
+!H\;7ecW<PF5HlH)sY+*#U,;ts7`0<#S:eGs8N)$+cQHq@h8oDn,32&(]Y,TrrB06<lNKs&.DIU
+s6af'?489Up\=b,qlO?>#ZC-krrB/U!$SKE(]Y,TrrB/EN,qnrrrO@6c2IYDmVdUMrtami?7g[,
+s7:;Yqu?ZrkPsB=p](9E!6>*orqZ3TlK-sZf@/'ha2>^+]"#/SZEUO8Y-"k0YHY:<[C<]Z^V\"4
+c-b(qhW*heo([e9JcC<$V>pPG!H\;7ec_3;kEJSh~>
+ZMsp^S,W]eUbN-(R.L=W!daq1rr3l)=pPC+kPtP^hZ*W4!<<'c!4Dis(]Y+[es6:7h>r<0opc(Y
+GNSk\)mNFnihT/9s/8\[kM@q7s8N'R[I=-!;Wln/9)JW)!8dbU!&8QCmrpe"g0T!tmVa81g4r+q
+q#;J<<`8,;8kT-`!(,QBHP$5W!8dbU!&:nMc3X1E`X)>9rVlrraj'PZ!q'uVqu6`GV&943"X/Qn
+mpeA/s+13$s+13\s8LjUK`Cc&"IoJ\S5+S~>
+oD_/Up$Lnuf?_OS\[&61S<T"fIWoaE@9QT'76[sUkN;d;esJB@-S7,85Y"RL>[qMhH%:^3QCaqS
+[(F5udb3UCcMX44#5=oK$7_M9rr3%F!9=(Y)=L]:#YjL^rrCgRs4[PRs$6dns.1&-&nf^Zs8LaR
+K)bM4!_mgtrS&9o=+T>)8=TXX9pXho0QmEq!&V.Ms'8XbhapE:rtb[is8N'UFjTN"3jdIDFnP-=
+,*L]97&]n\+KejIj53F"s8N'bhtqg5s8N)Rs8N'U[d2*Bp]&8>oD/@b!r9j[pAY3]D1DK`%/nPM
+)#O@1+G04R@6DX21]I4Amcifig==QoaMbm,\[AcJXfJG"Vl$>fV5C/gWN3/)Z*_!P^;@n4cdUP&
+iof\!plGITrW<&qqY^-lqYU3hrdk*#s/5nrgAup+p=f_=!:-(JJ,~>
+oD_/Up$Lnuf?_OS\[&61S<T"fIWoaE@9QT'76[sUkN;d;esJB@-S7,85Y"RL>[qMhH%:^3QCaqS
+[(F5udb3UCao%\/#5=oJ#Uu/4rr3%H!9a@])=L`7#YO:[rrCpUs5!bUs$?^ns-so+&80RZs8LRM
+F8tot!_ROjrRMpi<e',)8Y#gZ:715$0m!Bp!&:nMs&r=`hF^E;rtb[ls8N'RF40N$3ORRIGPCND
++ctE57B$"]+KSUAkMAg's8N'chZ%p6s8N)Us8N'R[I;BHp]&5=p\Xph!rL*apAY3^Dh%Za!n*n^
+rr3-FK_OqF3QV4VrqZ0Rl/^aUe^2O]`5'$r[Bm*>X/W%qVP^2dVPg>kX0&S1[(!Z]_T'aEe(EL9
+kNqd7O8o7Z!r`#mr:pKlqu$ElJcC<$VuQbI!H\;7ec_3;kEJSh~>
+ZMsp_JcCH(rn[X.o)Jf8k5F-VIr!d<o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpUn,32&!8dbU!4CP\
+s6AbDl>(>+mVcn+s6=BHqtg=/qg3PUs8UpUn,EC$s8UpUs8N)Us8N),rr3*EXoE0?mJd7UDh%]b
+"+L:NXoA>#^&A!4#i:.4JcC<$JcE:\rn[[/s7Y:PS,i#J:4N~>
+oD]d-o^1bsf$DCP\?W$-RZi\`I<BF>?W^/s69DCIru^c:+t50'4[_tB>%),aGCP@-Q(=_OZb"#q
+dFdC?c2*"kLB%8-!.seB!HmH$gDkWWgAgc[bkZO$mJm3p*<6$=[f?C%"RH*fhZ3-Crtkajs8N)-
+gAh-9kPOLXD=-_-C[;#bBm]aRrtkQ\GO,;/hZ3-F!5AL5gAq9R!8IPR!4Mn,"<alIBjL-+!psiS
+rVm$!I/j8Irr2u0rVus)gW9C3q=O+=j5/G;ccX5C]t(PUY,eLuUS=ERT)P;\SedrlUSXlgXg#.@
+]>);*c-k5!iTBLspltddrr)]gp\"1Mo'u8>rp^6aoCV_Mq>C5Cs+13Ns8LaRK)bQ!"I]>VRSA;~>
+oD]d-o^1bsf$DCP\?W$-RZi\`I<BF>?W^/s69DCIru^c:+t50'4[_tB>%),aGCP@-Q(=_OZb"#q
+dFdC?aSLJfLB%8(!-@`3!H[,ref9$PgAgc\c22j+mf3<p)#sU9[K$:$!:Tsfh>m$Brtkams8N),
+gAh3<k54FZDsm%3C[1rbCO>sTrtkQZGOPS3h>m$E!58F4h>mTU!8dbU!4Dh+"<joICKg-*!q'uV
+r;QkK!!'/#rrBb3!!*A^aT!+Qo^:r'hUp<'b/M31\[A]FX/MnjU7e-Mrgj(\(8%:qV5L>qYd:gN
+^Vn4<db!:5k3VX5PlD-jrVH<`p%7kHnaZ,JnH\XVo_%tSr;M9IJcDeNrmh*ks7Y"HPQ9m28q6~>
+ZMsp_JcCH(rn[X.o=Y1Uk5F-<DenY:rrVV,J,]HRec>aM!8dbUhYR9Qf)5O\!8dbU!8d/Ds42*C
+5q-a?mVdUSrrR[gmeZqamVht&&(^a\hZ*W4!<<'!hZ*TUhZ!NXF&N#L^$Yh$mVdUPrsR8O#l"B!
+(jl#G=uh06JcC<$JcE:\rn[[/s7Y:PS,i#J:4N~>
+oD_/So^(Ype]u1L\$2g)RZ`S]Hus4:?<0im5WP*s;D9%AH1:k-6mXB@4$lP:=^Yl\G(,.)PanML
+ZF[lod+I7=bkZhiLB%8-!.sgN!RTm*gB)5-li$hnmr*XQs8U[Ns8N)Rs8V!R!!(XKrtkajs8N)R
+mJm49D_aX/D=-_-IJs3EI;eTNrrMS,qZ%/YrrCgRs4[PRrrCgRrrCgQrrdIEq[gL/rrVS)J,B6R
+d\[HIs8*daoBT[Eao<4So^:r'h:U0#aMYd([^*'9Vk]oVS!fY0r08+bQ^O>6T;&0]XK](A]u%e4
+dFR(2k3V[7Qi@Hkq=jOPnF#]0lKRR3kR6Y?lg4$-nalGKqu20HJcDnQrn@I*s7Y1MRK2ZB9n3~>
+oD_/So^(Ype]u1L\$2g)RZ`S]Hus4:?<0im5WP*s;D9%AH1:k-6mXB@4$lP:=^Yl\G(,.)PanML
+ZF[lod+I7=a8(;dLB%8(!-@b6!Qs9tf)KLclM^_amVdUSrs70Us8N)Us8UsQ!!(UJrt5=gs8N)U
+mf3=<D_XO,Dsm%3J,]HLIrFcOrrMP+qZ%/XrrCpUs5!bUrrCpUrrCpTrrdC@rt)m2rrVV,J,B6R
+d\R6Ds8Np_p[;9Gao<4So^:r'h:U0#aMYd([^*'9Vk]oVS!fY0r08+bQ^O>6T;&0]XK](A]u%e4
+dFR(2k3V[7Qi@Hkq=jOPnF#]0lKRR3kR6Y?lg4$-nalGKqu20HJcDnQrmh*ks7Y"HPQ9m28q6~>
+ZMsp_JcCH(rn[X.o=Y1Uk5F-UHY2"3o;T.pHZ/?Ps0W^DrrCpUs7ZNfs8Vi=qu7K5hZ*TUhX:F<
+GA$(<IrFcCDenY<l>(bDqYqB/H[GMes7ah=rrCpUs5!bUrrCpUrrCpTrr^OPXWd'2#OZM[s8Vh`
+V#LB#!9aCF!;HNnec::$JcC<$JcE:\rn[[/s7Y:PS,i#J:4N~>
+oD_/SoBbPoe]u1L\$2g)R?EG[HZX(8>uj]j5<(>G+W:t$"YT?F\Ki[\3^H>7=C5]YG(#('PaeGJ
+ZFRfmd+@1;bkQbhLB%8-!.sgN!RTm*gDbENgAgcE[eY2cmJm3p)#sU9g].<F!;$6jpWra:(]`=j
+rrCg@s7^eOjo9gImHnb+li69dH27=:(\r?%oDejbci="Fg].<.!<<'!g].9Rg]%3TcNpNnm/Ide
+D1DTcopVWRrVHTTs5O+Rs8UONb5WCWp$_/*h:U0#a25O"Z`gF-US"'EQBRGmNfF$s)NBc<Ocu&t
+S"?=MWNEJ7]>2D/d+6t1kO%m<S,WrsqtTjTn*K?'k2kX_iV_X6i="Z+jlbmomI9`@qYl'GJcDtS
+rn@I*s7Y1MRK2ZB9n3~>
+oD_/SoBbPoe]u1L\$2g)R?EG[HZX(8>uj]j5<(>G+W:t$"YT?F\Ki[\3^H>7=C5]YG(#('PaeGJ
+ZFRfmd+@1;a7t5cLB%8(!-@b6!Qs9tef/gFgAgcD[JP;hmf3<p)#sU9hZ*WM!;HNnpWi[9(]`Fm
+rrCpDs7^_Mk5TpLmd>"/lMp-bHi*[>(]/Q+p](9fcN!nEhZ*W4!<<'!hZ*TUhZ!NWc3UNqm/I=Y
+Dh%fepRJ&Yrs8\gs5sCVs8UXMb5WCWp$_/*h:U0#a25O"Z`gF-US"'EQBRGmNfF$s)NBc<Ocu&t
+S"?=MWNEJ7]>2D/d+6t1kO%m<S,WrsqtTjTn*K?'k2kX_iV_X6i="Z+jlbmomI9`@qYl'GJcDtS
+rmh*ks7Y"HPQ9m28q6~>
+ZMsp_JcCH(rn[X.o=Y1Uk5F-LW)A9-Ue.*VUe7$;hD'*OrrCpTs!(EFkN?#/s8SV`s8N)Ms8N)U
+mf3$*BBI#sC[1>++ctQ=7B$"](8t8;kN?#/s8N)Us8UpUs8N)Ms8N)UrVlpB&:=9R!rL*apAY3^
+Dh%cd"c$!l]o3g-rrj6\kMB*'JcC<$JcC<$\c;Zc!JLLHh?9>Kn!m.'~>
+oD_/SoBbPoe]u1L\$2g)R?EG[HZX(8>uaWi5<(>G+W:t$"U9tdp*M:F3^H>6=C5]YG(#('PaeGJ
+ZFRfmd+@1;bkZhiLB%8-!.sgN!RTm*gCgG_KAiOqS,]?YQK-^RFoVIAg]%3t<E\AF>s//eRe-RZ
+!7UuJ!8Ho@olXp/^dDi#m;3u-h2=b$q#;,0='=SH>s//e!8IPRgAq9R!7UuJ!8IJP![JJ.qYpWm
+`m"/V'^]aes8W%O;8Bi%)#O@1*-(0!<C+h.)u]O#lK$gSd`ohL]XP2KW2-)VR$<_nN/<=EL&HZC
+KnkMCNKB?jR\$7OX0B"C^r=LDf%f9Kme$LMs!7U@p[dnAlK@9gi838Dg=b-2f@S[-g"P3:hr3VW
+kj.[,p%\N;s+13Us8LaRK)bQ!"I]>VRSA;~>
+oD_/SoBbPoe]u1L\$2g)R?EG[HZX(8>uaWi5<(>G+W:t$"U9tdp*M:F3^H>6=C5]YG(#('PaeGJ
+ZFRfmd+@1;a8(;dLB%8(!-@b6!Qs9tee4cVKAr[uSH#BWR-3<\F8u7?hZ!O";Hi8H=ulW_SG3'`
+!7q2M!8d/DpNL94_*Vr&mVa81hMXh$q#;,.<a+\L=ulW_!8dbUh>mTU!7q2M!8d\S![/,%qYpWo
+aj'PZ!q'uVrr3.W;Sg&*)#jO=(j"ls;F8S,)u]O#lK$gSd`ohL]XP2KW2-)VR$<_nN/<=EL&HZC
+KnkMCNKB?jR\$7OX0B"C^r=LDf%f9Kme$LMs!7U@p[dnAlK@9gi838Dg=b-2f@S[-g"P3:hr3VW
+kj.[,p%\N;s+13Us8LRMF8tsb"I&oLPY-H~>
+ZMsp_JcCH(rn[X.o=Y1Uk5F-Lm^51`+cu-lpRj)D#]'27rrCpTs!-u9#RF&cs8N)Us8PCc[Jp6`
+mf3=#5n$M$-%kW(8l?'LT_J6](AFV.#RF&cs8N)Us8UpUs8PCc[Jp6`rVlqG!8dSP!q'uVpAY3^
+Dh%cd"km`''Ih'$rrpt?!!lKcJcC<$JcC<$\c;Zc!JLLHh?9>Kn!m.'~>
+oD_/ToBbPoe]u1L\$2g)RZ`S]Hus4:?<0im5WLPK,9.F/$k-/9s$&%k4$lP:=C>c[G(,.)PanML
+ZF[lod+I7=bkcnjLB%8-!.sgN!RTm*gCihZ4piQun,N'P/-lYup](6ng]%3tmo^&):$;QV!8IPR
+5m4Ln!8Ho@s1Uf0;/%G4m;5El$ne:Kq#;-(Ufe*3:$;QV!8IPRgAq9R5m4Ln!8IJP!dOe'qYpWa
+D1D9Z!psiSrr3/UCCh74a8Z)Bf0ofN;<Q.&3r/@5k24k@c,[]6[]up3U7I^;Oc>3PKRnW%I!g9g
+I!pKpK8#,?O->p#TV\Zl[(=&lbL+qtj6H..TDoN#p[mtAl/gp^h:gN4eC2gld/D9%d*^:je^rL/
+hVdGVlL"-7qLSZts0Mb)gAup+p=f_=!:-(JJ,~>
+oD_/ToBbPoe]u1L\$2g)RZ`S]Hus4:?<0im5WLPK,9.F/$k-/9s$&%k4$lP:=C>c[G(,.)PanML
+ZF[lod+I7=a81AeLB%8(!-@b6!Qs9tee78U4U<3mmf3$S/I2Vtp](6nhZ!O"mofu&9'?6S!8dbU
+63+Fn!8d/Ds1L],:1kl*mVb]q$n\.Hq#;-(Ufn$09'?6S!8dbUh>mTU63+Fn!8d\S!daq(qYpWb
+Dh%K\!q'uVrr3/UCCh1/`r>uAej9?B;Wl7'3r/@5k24k@c,[]6[]up3U7I^;Oc>3PKRnW%I!g9g
+I!pKpK8#,?O->p#TV\Zl[(=&lbL+qtj6H..TDoN#p[mtAl/gp^h:gN4eC2gld/D9%d*^:je^rL/
+hVdGVlL"-7qLSZts0Mb)ecBjlp=9A2!9]S=J,~>
+ZMsp_JcCH(rn[X.o=Y1Uk5F-:ma1t8mVdU-rrJ'=JcC<$JcC<$NrT+8!JLLHh?9>Kn!m.'~>
+oD_/To^(\qf$;=N\?W$-RZiY_I<BF>?W^,r69@"U-6O3B',4RKs$SLu4[_qA>%))`GCP@-Q(=_O
+Zb"#qdFdC?c23(lLB%8-!.sgN!RTm*gApWfrrVS)J(Xc%N]a$8*;fEski(:HcH*l8\$<!2Tq%I4
+Nf&RCIscNcF`dV(*-?=HG^FmjKSYSLQ(">@WNW\?^rFUHg#(oXo),6^')q_"na,K$iSN>Ae^Dgi
+bf\&Kr5\iY&B`2@cdC4mg"bKEk3DC*pAKRBJcE.Xrn@I*s7Y1MRK2ZB9n3~>
+oD_/To^(\qf$;=N\?W$-RZiY_I<BF>?W^,r69@"U-6O3B',4RKs$SLu4[_qA>%))`GCP@-Q(=_O
+Zb"#qdFdC?aSUPgLB%8(!-@b6!Qs9tec>!^rrVV,J(Xc%N&dU3*;fEski(:HcH*l8\$<!2Tq%I4
+Nf&RCIscNcF`dV(*-?=HG^FmjKSYSLQ(">@WNW\?^rFUHg#(oXo),6^')q_"na,K$iSN>Ae^Dgi
+bf\&Kr5\iY&B`2@cdC4mg"bKEk3DC*pAKRBJcE.Xrmh*ks7Y"HPQ9m28q6~>
+ZMsp_JcCH(rn[X.o=Y1Uk5F-:ma1t8mVdU.rrV@,V1JYts+13$s,R-Yh>r<0p>,qB!:QFQJ,~>
+oD_/Up$Lnuf?_OR\[&61S!8ndIWo^D@9QT'76WXb.jZ;Y)]Oe:qD'ie5Y"RL>[qMgH%:[2QCaqS
+[(F5udb3RBc2<.mLB%8-!.sgN!RTm*gApWfrrVS)J(jo)qr]6!UAl85p[RP0h:L#r`4`XbXJVY[
+QB@,]K78/kFE)59D#J,hD/O<6G'SLeKo1qUR@^4RYI2!YaNi;iiTT_&rhTQ.r:fgNlK.!\g=Fa"
+c-",I`59@+^](tI^Cn>u_o0R:bKeMbfA#3CkNhX0qLSZts0ht,gAup+p=f_=!:-(JJ,~>
+oD_/Up$Lnuf?_OR\[&61S!8ndIWo^D@9QT'76WXb.jZ;Y)]Oe:qD'ie5Y"RL>[qMgH%:[2QCaqS
+[(F5udb3RBaS^VhLB%8(!-@b6!Qs9tec>!^rrVV,J(ai'k96[rruM+5n`o2kf?h[Y]sk8JVP'EE
+Oc5'JIX?9\EGo]1rG*BiDK'Z?H$t6tMN=!iStr?h[Ca8rcICV-kjJ-CV#M/,p[dh<jl,%Lf$i!j
+b/hT@_SO%&rkAEI'#;?$`5]pBcI(.ngY_&SlgXQCJcC<$[f??X!H\;7ec_3;kEJSh~>
+ZMsp^JV8`1rn[X.o=Y1Uk5F-:ma1t8pSkFrrrLhWqZ$X"KBW=:`W/nfs+13$s+130s8LjUK`Cc&
+"IoJ\S5+S~>
+oD_/Vp?q,$f[.aW]!JH5SX,:kJ9c-L@pE#084#Bq0InLr,<kMpa"]M96V:3W?=dqpH\.*:R%L:Z
+[CjH$e(WgGc?t1kL40'U!.sgN!RTm*gApWfrrVkjYl4S&fNJ(O!="8Arr^.=;>[*f55Y!>k2=qA
+bf7E.Z`U.!S!B(nKn4VrF)Yr0B4YU`@U`hXAnc$uEcubYKSb_QR@g=UYd_<`b0\brjQl@5V>h;-
+p@7M4j58SAe'H4Y`PTF)]XkY_\,E`M\%&u\]Y;5"`lZKPeC`R7jQZ+'q#5jEJcE7[rn@I*s7Y1M
+RK2ZB9n3~>
+oD_/Vp?q,$f[.aW]!JH5SX,:kJ9c-L@pE#084#Bq0InLr,<kMpa"]M96V:3W?=dqpH\.*:R%L:Z
+[CjH$e(WgGa`;rRL3*@F!-@b6!Qs9tec>!^rrVqoZ2O\'g04@R!<e&=rrU1?;PF+Sqt0:<i7ZT'
+`kT'jXf%k^Q&poXJUD]`E,96$ARo:[@Uiq\BkqU,G'\XkM2mdfT;AQl\%T]%d+@+7lgakKrtYG)
+na,H!hqHZ1ccaDK_SEmu]",;ZrO*HM\@K5a^;7_,aj&2^f\GEGl0e-;rdk*#s1&+.ecBjlp=9A2
+!9]S=J,~>
+ZMsp^JV8`1rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjUK`C_8!s%e[:4N~>
+o)D#Mn*&``d`]P@[B6<uR#m/VHZX+:?Wg9#LVeC01+kM0l2UZi2`sDt:/kG+BQ&'BKSu%_Tr>0(
+^;\@HgZ.SFI"?^#IK%t$K(HDOd,Y)Z!:>@;`;^nXq!mY0gt'fm_Rm4YW1ofJOG\aAH?F4DBOtX[
+?!I;3*EucT@:X"dDfg5PK8>PPR\6OZZFR`ibgY;)kO/&@s"XBCnE]5qgt:*%bK.W<^:Un`['Hp>
+Y-+n0Y-5(7ZF%'N]YD>&aj&5`g"t`Om.'iLJcC<$\c;Z`!J:@ERKEQURSA;~>
+o)D#Mn*&``d`]P@[B6<uR#m/VHZX+:?Wg9#LVeC01+kM0l2UZi2`sDt:/kG+BQ&'BKSu%_Tr>0(
+^;\@HgZ.SBEe/:dF8j_jF7ZL7b23*J!:#.8`;^nXq!mY0gt'fm_Rm4YW1ofJOG\aAH?F4DBOtX[
+?!I;3*EucT@:X"dDfg5PK8>PPR\6OZZFR`ibgY;)kO/&@s"XBCnE]5qgt:*%bK.W<^:Un`['Hp>
+Y-+n0Y-5(7ZF%'N]YD>&aj&5`g"t`Om.'iLJcC<$\c;Z[!H\;6PQLpKPY-H~>
+ZMsp^JV8`1rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjTK_#0Fn!m.'~>
+o)BU&n`o,geBGnG\$)a(RZi\aIWoaG@pN,4MuN_WqtC$h*r(1F4[MY5;HR:;CiXfOLQ7XiUT1T0
+^rOaOh;mqMJUN6#rn@F)o<n\Hj8I^4m=G;UruV(1mcWN]d`]VD\$;s/SX5IsKn"DjDe`m3P`h,h
+NrG"ZNfT9/>[V)UD/slLK8GYSS"Zd`[Ca;td+7%6lgk"Qs"jNDn*8ukg=FZraMbm-\[JiKY,nY%
+Vl$>fV5C,fWN*&'Z*_!O^;@n4cI:D#iTBIrpATXCJcE=]rn@F)o)JjXRSA;~>
+o)BU&n`o,geBGnG\$)a(RZi\aIWoaG@pN,4MuN_WqtC$h*r(1F4[MY5;HR:;CiXfOLQ7XiUT1T0
+^rOaOh;mqHJTHNdrmh'jo;r&9hYl"*l@JuRruV(1mcWN]d`]VD\$;s/SX5IsKn"DjDe`m3P`h,h
+NrG"ZNfT9/>[V)UD/slLK8GYSS"Zd`[Ca;td+7%6lgk"Qs"jNDn*8ukg=FZraMbm-\[JiKY,nY%
+Vl$>fV5C,fWN*&'Z*_!O^;@n4cI:D#iTBIrpATXCJcE=]rmh'jo)JjTPY-H~>
+ZMsp]JV8`1rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjTK_)kYn!m.'~>
+o)B^,oBYJnf$;=O\[&93SX,=mJU;KVB45"FB<BbWrr4,#X'%VO6qC$M=']<ME-?Y^MNO9uVQI5;
+_TC3Xhra@WJUN6#rn@F)o<n\Hj8I^4m=G;Uru(Y'lf?mQccEr6[&p3uR?NSaJ9l<TBk1SQpAZ(>
+<EWU:B5DU5IY<T?Q^sqPZ+.QgbgY;)kjS>HrttV)n*/oig!n?k`kf@![Bcs9W2?AbTV%hSSJRli
+Tq\B]WN<;0\%9>la3;r^gYh5[nb7V7JcE=]rn@F)o<n_dRSA;~>
+o)B^,oBYJnf$;=O\[&93SX,=mJU;KVB45"FB<BbWrr4,#X'%VO6qC$M=']<ME-?Y^MNO9uVQI5;
+_TC3Xhra@RJTHNdrmh'jo;r&9hYl"*l@JuRru(Y'lf?mQccEr6[&p3uR?NSaJ9l<TBk1SQpAZ(>
+<EWU:B5DU5IY<T?Q^sqPZ+.QgbgY;)kjS>HrttV)n*/oig!n?k`kf@![Bcs9W2?AbTV%hSSJRli
+Tq\B]WN<;0\%9>la3;r^gYh5[nb7V7JcE=]rmh'jo;r)WPY-H~>
+ZMsp]JV8`1rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjTK_)kYn!m.'~>
+o)CuRp$Lo!f[7jY]<n]<TUCt%Kn">fCh@'Z<`2Xa7mo^26:41492AJf?".JbFF&ImNg-$-WNWbE
+`QZfbiTTdaJUN6#rn@F)o<n\Hj8I^4m=G;Vru_77nEAibe',eF\$2j,S<].kJpVWYBk(IPJZYuP
+W2KWl*r,c\8kr8c>[_8^F*W7iN0B^'VlmG?_ogBZhra>!WrEt6p$_/+hV$B'ai(s+[^*'9Vkg#X
+S=5h3QMm'cQC"#.SY)XQW3!2/\@fYtbL"eni9'@qpjrHrs1A=1gAlis[K>c`9n3~>
+o)CuRp$Lo!f[7jY]<n]<TUCt%Kn">fCh@'Z<`2Xa7mo^26:41492AJf?".JbFF&ImNg-$-WNWbE
+`QZfbiTTd\JTHNdrmh'jo;r&9hYl"*l@JuSru_77nEAibe',eF\$2j,S<].kJpVWYBk(IPJZYuP
+W2KWl*r,c\8kr8c>[_8^F*W7iN0B^'VlmG?_ogBZhra>!WrEt6p$_/+hV$B'ai(s+[^*'9Vkg#X
+S=5h3QMm'cQC"#.SY)XQW3!2/\@fYtbL"eni9'@qpjrHrs1A=1ec9d_XTI[M8q6~>
+ZMsp]JV8`1rn[X.o=Y1Uk5F-:mXbChs+13$s+13Rs8LjTK_)kYn!m.'~>
+nc(iJnEJoce',eF\$;s.SX,=nK7.r`CM%![=B&-m9M7uM92/2[<EWX;B5M^7IYE]BR%L4VZamll
+cIL_2lgrk^I>*+KgAlis[K4b8rS%>>JcE^h6N$NDk24h=b/:m!Xf%h[P)G!BGB%A.?<C-$8OPj-
+4#o<5s8RF57ncc\>[hAaFaJ^sO-Z?4X0T:Oa3N5kjQlC8XT(9Xp@.A.hV$B&aMYa&['6U/US+-F
+QB[PoNfB$WN/`jYOHPlqR[p.KW3*>5]>)>-cdgb-k3V[7JcC<$]`7uc!.sgN!pc:LJ,~>
+nc(iJnEJoce',eF\$;s.SX,=nK7.r`CM%![=B&-m9M7uM92/2[<EWX;B5M^7IYE]BR%L4VZamll
+cIL_2lgr\YF+n]7ec9d_XT?T$rRLu6JcE^h6N$NDk24h=b/:m!Xf%h[P)G!BGB%A.?<C-$8OPj-
+4#o<5s8RF57ncc\>[hAaFaJ^sO-Z?4X0T:Oa3N5kjQlC8XT(9Xp@.A.hV$B&aMYa&['6U/US+-F
+QB[PoNfB$WN/`jYOHPlqR[p.KW3*>5]>)>-cdgb-k3V[7JcC<$]`7u^!-@b6!p>e?J,~>
+ZMsp]JV8`1rn[X.o=Y1Uk5F-:m^rK%!8d_UhLY]Xs+13$s+14Hs8LjTK_)kYn!m.'~>
+nc'X+o'>Amf$DFR]<n]<TUM+)LOjhrEGT8t?X$W4<;oc:;cHe#>[V)UD/slLK8GYSS>*!d[_9W%
+dFd@=mJ,FeI>*+KgAlis[K4b8rS%>>]Di!6g]%9.OT.ZDoBbPof$DFQ\[&93SX,=mJU2BSAmeb?
+:.R`93ArZJ0Xh#F3]o\t92SbrA86+/It`iFR\?[`\%]i*e(`mHnGKEg)ufX&lfI$We'?%O]stDO
+WMQ8XR$EhqN/EFGL&HZCKnkJANK99hR\$7NX08n@^Vn:@e_B'GmIU:-s+13`s8LaQK(HDPl^COu~>
+nc'X+o'>Amf$DFR]<n]<TUM+)LOjhrEGT8t?X$W4<;oc:;cHe#>[V)UD/slLK8GYSS>*!d[_9W%
+dFd@=mJ,7`F+n]7ec9d_XT?T$rRLu6]Di!6hZ!T4OT.ZDoBbPof$DFQ\[&93SX,=mJU2BSAmeb?
+:.R`93ArZJ0Xh#F3]o\t92SbrA86+/It`iFR\?[`\%]i*e(`mHnGKEg)ufX&lfI$We'?%O]stDO
+WMQ8XR$EhqN/EFGL&HZCKnkJANK99hR\$7NX08n@^Vn:@e_B'GmIU:-s+13`s8LRLF7ZL8kEJSh~>
+ZMsp]JV8`1rn[X.o=Y1Uk5F-:m^rK%!8d_UhWXt@LNi1Hrr@EE!!mZGs40L:#ZC,Bs+13$s+13e
+s8LjTK_)kYn!m.'~>
+nc(iPp$V#$g!\*`^::GKUn3s:N.un2GB.P7AR]"P>?Y04>$P?@@qKIoF*N+cLlR^gTVeit]"lA3
+eD'!InGV*mI>*+KgAlis[K4b8rS%>>]Di!6g]%9.kl1^>GOOSl!."MC#^-1If0KNF<U8<;6M^0:
+j4r//`kJpdWM5lHN.l_)E+rfe<DQ1R4Z>/L.k*RUs,o)p4$Z80;d!L@DKU>ZMNO9uVQI8=_ogE\
+i90S)XoCHYoBk`!g=4Eh_S*FaXf%qcR['"pMMHk:J:;ooH[C-gIXm$(Ll7=XQ^aYDWNNV=^Vn:A
+f%f9Ln+M>4JcEF`rn@F)o<n_dRSA;~>
+nc(iPp$V#$g!\*`^::GKUn3s:N.un2GB.P7AR]"P>?Y04>$P?@@qKIoF*N+cLlR^gTVeit]"lA3
+eD'!InGUphF+n]7ec9d_XT?T$rRLu6]Di!6hZ!T4kl1^>GOFMk!.4YE#]p%Gej9?B;X`9<6M^0:
+j4r//`kJpdWM5lHN.l_)E+rfe<DQ1R4Z>/L.k*RUs,o)p4$Z80;d!L@DKU>ZMNO9uVQI8=_ogE\
+i90S)XoCHYoBk`!g=4Eh_S*FaXf%qcR['"pMMHk:J:;ooH[C-gIXm$(Ll7=XQ^aYDWNNV=^Vn:A
+f%f9Ln+M>4JcEF`rmh'jo;r)WPY-H~>
+ZMsp]JV<?B!klR3pk/^^`JggMrn[X.o=Y1Uk5F-:m^rK%!8d_UhWXt@IrFc8rrH#=rmhADs8Np>
+kMAg'JcC<$JcC<$_Z0Vl!/0sW!q2XSJ,~>
+nGb]In`o/jf$DIT]X=rBURda6N.un3G][n@BkLsd@UW\S@qB:fD/j]DIY3H9PF8&>Wj0%H`66Q\
+hrX4ts4`*Ql[8iG_M.c5!kQ7&WdXm$!.sgN!RTm*gApWQrr`>VrrCg;rrR[emGn3I<H8#i#j_Nf
+**qab8P.S76MU'7iS)c(`4`U^VkBH?MM$;!DJ*<Z;G0DA3&3$4,9`!Fq)BiX2*=2s:KCb3CN=]N
+Ll[jmV6%#7_TC0Vhra>$Y5]L>p@%8*gt'fn_nEObXJ_e`R$3PfL4au'H?XOSrc9'$F`r"UI=R!+
+N0'9lSti6e[(3rjbL+u!jQl@5JcC<$^An2e!.sgN!pc:LJ,~>
+nGb]In`o/jf$DIT]X=rBURda6N.un3G][n@BkLsd@UW\S@qB:fD/j]DIY3H9PF8&>Wj0%H`66Q\
+hrX4ts42aBlZ3-8]mKNq!k#^gWcS0j!-@b6!Qs9tec>!Irr`>YrrCp>rrR[gmc4<J;KMig#k.fn
+(g?+Z8kRb96MU'7iS)c(`4`U^VkBH?MM$;!DJ*<Z;G0DA3&3$4,9`!Fq)BiX2*=2s:KCb3CN=]N
+Ll[jmV6%#7_TC0Vhra>$Y5]L>p@%8*gt'fn_nEObXJ_e`R$3PfL4au'H?XOSrc9'$F`r"UI=R!+
+N0'9lSti6e[(3rjbL+u!jQl@5JcC<$^An2`!-@b6!p>e?J,~>
+ZMsp]JV<?B!l<!;pk/^bac*6Qrn[X.o=Y1Uk5F-Um_)$p+cu-lpRj)D&8V%?rrB/EN;rW^&-u2&
+qu7h9+TN@Ls1)U;s8S0ec-g)5$sLpU]gW2MORE.s@h9&H`W#l?!8d_UhY@*mpL=a?;XaYc!3IsU
++g'=R$j^=rIo^2_Iq#AVs,^R3rVlreDh%N]!@b/Krs%$Sn,NF5!.k0$s+13$s2+g8h>i6#]`RYm
+:4N~>
+nGaL,o^:o#g=+9c^q$eRVkT]JOc5'JIX63ZE,KK,rb3EgCMe!0FEi1`KSb_QR%C(PYI2!ZaNi>j
+ip#t1s4`*Ql[8iK`eF29!ku[.WdXm$!.sgN!RTm*gDfIi7LUQ(mJlpT/dN#&p](6nWZ[3!pLOmA
+<U]hb+f6Lb*1Ho;A#fS/O^ZP`AJ,JWbl,+B$m^r%s3P0c$rOtBrr`>VrrCgKru^uH&-u;)s8N)%
+1^"r$e;XqD@G$'0AQ=.gWrN*]@F"iO!psiSp\t:GY5A1t#1ES<s8UCJf`+;4n*&]_d`TJ?[&p3t
+Q]R&TH?3n5>uj`l5rpeR-QsHLk5VP*,qC]05"/.E>%22bGCP@,Q(4VLZFRclcdpt7mIm^_*;K*j
+jkeY;bJh3*ZE0stS<f:rLkC2(G][tED/B/d*,KM3F*;hVJ;&i?PF.r:WNNV>^rO^Kg>M/]o_sFA
+JcELbrn@F)o<n_dRSA;~>
+nGaL,o^:o#g=+9c^q$eRVkT]JOc5'JIX63ZE,KK,rb3EgCMe!0FEi1`KSb_QR%C(PYI2!ZaNi>j
+ip#t1s42aBlZ3-<_0bru!kH-oWcS0j!-@b6!Qs9tef3nf70k&umf3$S/I2o'p](6nXW`Z'pL=a?
+;XaM_+f-=^(nCW:@]9>,OC$2[@h9&Pc2YIG#U,;ts3bBg$rY(Drr`>YrrCpNru^uF&-u2&s8N)$
+0`WB!er'qB@bQ<4B3'LkW;lmZ?HrHK!q'uVp\t7CXo/2'ec>1=s3:Vss$HJKkht.Bb/:m!Xeq_W
+OGSO7F)5Am<_l7P3\r?8+WMKas/d@h.ks"I78-Za@VKe*ItirJS>3*i\\Q;4f&#NUp9+E8q"!b4
+hUp6!`P/jfXJ_b^QB@,^K7A5mFE2;:D#J,hCi435G'SIcKo(hRR%C(PY-bdUa3E)ei90M"rdk*#
+s1eU5ec9d_XTI[M8q6~>
+ZMsp]MM)7ocM.@iN.g'5re)'M]nD?ip]&g'KS71mb4GMYR(`Cod[9la#/0p2d_4)2re)*V[?U]n
+p]'*/KS5<0p]&g'KS6Jrs7`qBK`9g.K_)kXf&lqf)mNFnihT/9s/8\[kM@q7s8N'R[I=-!;Wln/
+9)S]=mf9Ka[/f[PCOc6@B7KMs<moQ&GI^b(ihT/9pNJX*g0T!ts8N)UrrCpNruYEBkMAg's8N'c
+hZ%p6L];jBmf.bRF4/o\J,A5<J,B3E!rL*ap\tL)0`V2On,N.=rr3"h.=qMMs+13$s2+g8h>i6#
+]`RYm:4N~>
+n,F@%n`o2kf?qaZ^::JMVkKWIP)Y<PJUVrjF`_[&E?0+BG'SFaJqf/DPaS,<W33M=^rFUHg#(rY
+pAb0IML>b^chI=cL4.[srd>RF\p]1Vp\WEoI=8iX`q/rKPIUGccB7sO#.XL+cF2'!rd>UOY)`O^
+oD@-oI=6^np\WEoI=8-as7<P;IK%t$K(HDOd,Y)Z)m37niM&l4s/8YXj4c81s8N'U[d3s!<TDt.
+8c8T<mf]fb[K,dPBn-$?B79;q=jYZ&GIU_*iM&l4pNJ[*em3Fks8N)RrrCgKruYNHj53F"s8N'b
+htqg5L];j@mJhYSFjSlWJ,A8=IJNjA!r9j[p\tL)1]RYYn,N.:rr3"f/D:%jrq>gDi7QH"_Rm.U
+V4O!6LOaYiC1CII9h%?+0I\1c(17+A8/`Tu/i>aY8lAf"B5_sAKoD4bU8bE-^rOaOh;mqpYQ$fa
+p$V#%g=4Bf^q-nTVkT]IOc+sFI<]jQD/*]pA7K(X@q91bCMn-7H@CL&NKT[#UoCQ+]Y_e:f%f<N
+nG.Y8JcELbrn@F)o<n_dRSA;~>
+n,F@%n`o2kf?qaZ^::JMVkKWIP)Y<PJUVrjF`_[&E?0+BG'SFaJqf/DPaS,<W33M=^rFUHg#(rY
+pAb0DMK9&McM.@aHZRcXrc8k<[<$]?p]&NcF*"n:_=REDN3W-SabT_6#-mq"ag'-erc8nEXb?_N
+p]&fkF)u]Rp]&NcF*"2Hs7`Y:F8j_jF7ZL7b23*J)m*.jihT/9s/8\[kM@q7s8N'R[I=-!;Wln/
+9)S]=mf9Ka[/f[PCOc6@B7KMs<moQ&GI^b(ihT/9pNJX*g0T!ts8N)UrrCpNruYEBkMAg's8N'c
+hZ%p6L];jBmf.bRF4/o\J,A5<J,B3E!rL*ap\tL)0`V2On,N.=rr3"h.G=_grq>gDi7QH"_Rm.U
+V4O!6LOaYiC1CII9h%?+0I\1c(17+A8/`Tu/i>aY8lAf"B5_sAKoD4bU8bE-^rOaOh;mqpYQ$fa
+p$V#%g=4Bf^q-nTVkT]IOc+sFI<]jQD/*]pA7K(X@q91bCMn-7H@CL&NKT[#UoCQ+]Y_e:f%f<N
+nG.Y8JcELbrmh'jo;r)WPY-H~>
+ZMsp]MM2#\s-3Q?)hb?fKS5lqP_@W=Pa(%]KS725]o8fE]nF5DN;/&L_9%Xtc,GL#SH"P4s5'!)
+kLP<>f%-(MhVNpEs/h6^s,>'Qrn[X.o=Y1Uk5F-VIr!d<o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpU
+n,<7umf93Ys7cQnOD!.P@]]<J;U5:='p*4bs7=(Os6AbDl>(>+s8N)UrrCpOru^t8n,NFE!:Tpf
+^&S,h!.Y#uDsmXT>2'#VOD!.P@]])!#4F:Cs5#b6rVlugHPk%Zs+13$s+13es8LjTK_)kYn!m.'~>
+n,F@*p$V&&gXXWl_nEObXJ_e`R$<\kLkUG1I=$;=Go_3YIXm'*M2dX_R\$:QY-Y[R`6-KZh;dei
+rr<#QML?Yodu'1?gO5snI=7:YMLEh"MN6HGI=8iu[YUU1\p_<4L%p'>^;bkbb.`@`Req\ss4`Qs
+j4A^-cdRc3gY7.2s/(OFs+\XDrn@F)o<n\Hj8I^PI;@R:o>&TGH#;sKs0`pIrrBM-s7ZZ^s8UsV
+n,<89mf]BZs7?9jO([%NA$5QO;p>.7q2]=Fs7=%MrTWMBl"P#%s8N)RrrCgLru^t<li7"B!:Tpf
+^An5f!.Y#uD=.@Q>MB,WO([%NA$5>$#4"+CqqjM9rVlugGo4`Xs$QeZmcWK[dE08:Z`KsnQB$`M
+G]@G,>#S*`4Z4o?+;kg.s3;,j*@*0l3^QD8=C5]YFa\q%PFA5FYdhHfcILb3lgq=[*Vo9ljPAG7
+ahtd"YGn:fQ][2\J9uHZD/!Qj?X6q9=rggP?=78UC2S*;I=d66PF8&>X0K1K`QQ]_i9'G!JcC<$
+^]4;f!.sgN!pc:LJ,~>
+n,F@*p$V&&gXXWl_nEObXJ_e`R$<\kLkUG1I=$;=Go_3YIXm'*M2dX_R\$:QY-Y[R`6-KZh;dei
+rr<#LMK9rdeqA_-eoR\^F*!<?KQGGiKS7q-F*"n[Z$Vkl[<&mpHh_Y*\\WWFah;nNPlH)`s5&Ef
+hUZahcIRZ%f%+nhs."G+s*Mk/rmh'jo;r&9hYl"FHY_@8o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpU
+n,<7umf93Ys7cQnOD!.P@]]<J;U5:='p*4bs7=(Os6AbDl>(>+s8N)UrrCpOru^t8n,NFE!:Tpf
+^&S,h!.Y#uDsmXT>2'#VOD!.P@]])!#4F:Cs5#b6rVlugHPk&]s$QeZmcWK[dE08:Z`KsnQB$`M
+G]@G,>#S*`4Z4o?+;kg.s3;,j*@*0l3^QD8=C5]YFa\q%PFA5FYdhHfcILb3lgq=[*Vo9ljPAG7
+ahtd"YGn:fQ][2\J9uHZD/!Qj?X6q9=rggP?=78UC2S*;I=d66PF8&>X0K1K`QQ]_i9'G!JcC<$
+^]4;a!-@b6!p>e?J,~>
+ZMsp]MhE:5s,;VaPlH]$s.tCghLpjfN.ckKs,;cMdZfEDah`YHac-"J+Ml0YKY>g$WQs(JPlI8,
+KUi($N;niiKTuLqN;p;EKT+!*rn[X.o=Y1Uk5F-<DenY:rrVV,J,]HRec>aM!8dbUhYR9Qf)5O`
+]h/hr[K$9;@]5&ohZ)Gb/L5PoIr"?IrsdOt0gR7,mf3:ehZ!T4q>UHOqZ%JarrCpUs5!a*s*ntT
+s*ntTs8TW=W/#!Ali."*#lai+PSe3)JcC<$JcC<$_>jMk!/0sW!q2XSJ,~>
+mf,9Co'GMsg!e3e_S!@`XJhndR[0+tN/<=DK7\Z)JUrE*KnkPFOHc*$TVSQiZad`faj8MliTT_)
+rr2uQMgZe$s,)5QNrOicpS*)Rf6r8NMLBo5s+Z*=cAd7-aM*):`eF29+MPjLIC@:\Us%)4NrP8j
+I?snbK)^^VI?+>^LB"E.I=fOgrn@F)o<n\Hj8I^6D/8J9rsnL9IJs3Gf)YjN!8IPRhtmBRfDPXa
+^.f.uZN's9AZ1;qhZ)Gd/gPSlIr"BJrsdIr1.!I-mJm1dg]%9.q>UHPqZ%JbrrCgRs4[O's*nnQ
+s*nnQs8TZAW.em@li."+#lai+Q5FK)f`+><p?q,$f[7gX]!JH5SX,:kIs>pH@Tl](6p3F\-Qa0c
+s8Q[@'cePM1HIio:fq(:DKUA\Mj'U(WN`nI`m3,jjQlEAs$6PVn*&`ae',hH\?`03SsY\"L4FSm
+E,0&p?<_BC]>;(OCfFG<>[LuSCiOZHJr#GOR\6R\[(=)pcdgh2lLFe's+13cs8LaQK(HDPl^COu~>
+mf,9Co'GMsg!e3e_S!@`XJhndR[0+tN/<=DK7\Z)JUrE*KnkPFOHc*$TVSQiZad`faj8MliTT_)
+rr2uLMfU(hs*Jg.K`?C?pRH<<eoQ3<HZO7]s*Jt#c%g@i`OU'#_0bru+M#=8F0WlHSAriqK`@!P
+F,^-GHiJG6F+jR?HiKphF*kuLrmh'jo;r&9hYl%*CB3YurrVV,J,]HRec>aM!8dbUhYR9Qf)5O`
+]h/hr[K$9;@]5&ohZ)Gb/L5PoIr"?IrsdOt0gR7,mf3:ehZ!T4q>UHOqZ%JarrCpUs5!a*s*ntT
+s*ntTs8TW=W/#!Ali."*#lai+PSe3)f`+><p?q,$f[7gX]!JH5SX,:kIs>pH@Tl](6p3F\-Qa0c
+s8Q[@'cePM1HIio:fq(:DKUA\Mj'U(WN`nI`m3,jjQlEAs$6PVn*&`ae',hH\?`03SsY\"L4FSm
+E,0&p?<_BC]>;(OCfFG<>[LuSCiOZHJr#GOR\6R\[(=)pcdgh2lLFe's+13cs8LRLF7ZL8kEJSh~>
+ZMsp]MhE:9s2Dgjao@T]k.-0%`Is?Q`PKC4s-/JYc&dU;ah`YHac-"J+Ml0YKX&muZf8ZOPlHhu
+KTQ4qOT3;9_9)_ALsjD][@G<krn[X.o=Y1Uk5F-VF_Ke7q:+-jFa*QZs2>EHrrCpUs69T2It)fX
+lM^`4qn](`G?Xb<cXq`PHg^jhZ^-)SW.AXAs7t0uqke.eTN#jts8N)UrrCpOru^M+H[gNlBBoKs
+hZ*W4!.Y#uDsmXTDsmZ*cXq`PHg^D'!TqZ+rs6UQs8T?9J$o$%s+13$s+13ds8LjTK_)kYn!m.'~>
+mf,9Gp[IJ/hUp9$a25KuZEC1'Tq.U;PE:f`Mi!:HLl%"INK93dQ^XM?VQ-i,\\>u'cICS+k3V^=
+rr2uQMgZe*s2;Xc`rD!Ij1'Nl]R>V9`4it*s,;WFbDL_&a1cu9`eF29+MPjLIB1M^Yi3$=NrOl_
+I>n2^M#YE-^;g23J^23HYa!4Wrn@F)o<n\Hj8I^PF(sY6q:+-jFER9Vs2GKIrrCgRs60N/It)fX
+li$i5qnf4cF]nJ9ctIrPHg^jh[$H/RW.A[Bs7t0uqkn4fTN,jrs8N)RrrCgLru^J*H%1<jBC#Qt
+g].<.!.Y#uD=.@QD=.B'ctIrPHg^D'!U%c-rs6XTs8TB=ICAh$s$QeZmcWN\dE08;Z`L!oQB$`N
+G]@J->?"9b4uY,C+W@!Qm1g3M*[NBp4$lP:=C>cZG(#%&PFJ;GYdhHgcILb3m.@O^)uB0mjkeV9
+ahkZtY,@t^P`:HLHZa7AARJ_I^A@jM]i7j.=C#?ICiOZIK8GYTS>3'f\%]i)db3RAme;;4JcEOc
+rn@F)o<n_dRSA;~>
+mf,9Gp[IJ/hUp9$a25KuZEC1'Tq.U;PE:f`Mi!:HLl%"INK93dQ^XM?VQ-i,\\>u'cICS+k3V^=
+rr2uLMfU(ls1PtR_>f./ijEjY\T<9#]t(\is+>[/a+8;[_msj!_0bru+M#=8F/6jBW8=e#K`?OC
+F+=4>J,d3m\\\;uGKIP/W/J`<rmh'jo;r&9hYl"FEG4A3q:+-jFa*QZs2>EHrrCpUs69T2It)fX
+lM^`4qn](`G?Xb<cXq`PHg^jhZ^-)SW.AXAs7t0uqke.eTN#jts8N)UrrCpOru^M+H[gNlBBoKs
+hZ*W4!.Y#uDsmXTDsmZ*cXq`PHg^D'!TqZ+rs6UQs8T?9J$o%'s$QeZmcWN\dE08;Z`L!oQB$`N
+G]@J->?"9b4uY,C+W@!Qm1g3M*[NBp4$lP:=C>cZG(#%&PFJ;GYdhHgcILb3m.@O^)uB0mjkeV9
+ahkZtY,@t^P`:HLHZa7AARJ_I^A@jM]i7j.=C#?ICiOZIK8GYTS>3'f\%]i)db3RAme;;4JcEOc
+rmh'jo;r)WPY-H~>
+ZMsp]MhE:9s2Dgj`QaKt\`/kJR"US$`PKC0c&dh!ac(n3ah`YHac-"J+i29ZKUU0%a7kgOPlH\q
+KTQ4qOT3;9_8XZ\Lo%Aib1;BjK`9g.K_)kXf&lqf99EJ^nB6*UrK(:%oBpZgs8N)Us8VsFW:TVZ
+KE(trqu?D'hYXPXoD.s*3EE$Wqlca\el[3f>d!S>H)UI]BBJ,[D=%<&!8d_UhYI0mq^JK8o;I<A
+rrCpUs5!a*s*nnPs*ntTs8VY<3EE$SrrW/[k4nradS@pYl@2,"l7meFrp#(7JcC<$JcEUern[X.
+o=Y4oS5+S~>
+mJe(&p$_/*h:U0#a25O"['-O.UnF9IR$Nu"OoCIBOVa4GQC+/5Tr"]hZ*h0X`6$<Sg#(oWnbrFd
+!8EE[,)H99^:qD*LOHVkNUr3ZM#Y?+^;.mHK"f9[I>,\TID3^TpjF="`eAi*ahG^bNI?ieLOFT.
+s+lL2_S3b"b(kJ:XLc?uJ]W?>gAlis[K4b8rS'u,>d*Y>H)UY%>f#stF%630!8IPRq'r93o;[NE
+s31<=ok3.WXoe.go6r`$VZ6LqU[-B2H(/'BnB-$Tp3102hdL<ds8N)RrrCgLruUtcVXa8XL&_/Q
+g].<.!.Y#uC[;"MD=.B'o6r`$VYgApr8Qi5rsR:Qb4k4O7/uL,J_g=kg&FG=p@%5'g!Rs[]<n]:
+SsPLoJU)9O@pE#/7mK'i.jZ_<s-"-6*?lpc2EaH$;d*UCDg-YaNKfp-Wj0+Ma3W>mjm;]Fs$?GM
+lJgRJc,RN.Z)a[kQB6rUI!0IDA7&J>_>jMBF'isqrr9`*9i>"r@:j=rG^b@)P*qr>XgG^WajAYr
+jm;U<JcC<$_>jMh!.sgN!pc:LJ,~>
+mJe(&p$_/*h:U0#a25O"['-O.UnF9IR$Nu"OoCIBOVa4GQC+/5Tr"]hZ*h0X`6$<Sg#(oWnbrFd
+!7m'L,(KX+\[fDmIrhmSKC=S:J,d3m\\5t3H+Cb<F*ka6F1K,6pi@Uh_0^6]`OWbTK6)_GIrf[\
+s*oOu]t(\e`IE)rUp[n\GKFq*ec9d_XT?T$rROW$>d!S>H)U\'>f61$F%--/!8dbUq^JK8o;I<A
+s3:H@pLi@[YlOCknpNN!VZ6OsU?pH5H(8-BnB6*UpNL94i*^Egs8N)UrrCpOruV%dW:TVZKE(rO
+hZ*W4!.Y#uD=%:PDsmZ*npNN!VYgAprT*,9rsR7ManP(M63$4)J):1ig&FG=p@%5'g!Rs[]<n]:
+SsPLoJU)9O@pE#/7mK'i.jZ_<s-"-6*?lpc2EaH$;d*UCDg-YaNKfp-Wj0+Ma3W>mjm;]Fs$?GM
+lJgRJc,RN.Z)a[kQB6rUI!0IDA7&J>_>jMBF'isqrr9`*9i>"r@:j=rG^b@)P*qr>XgG^WajAYr
+jm;U<JcC<$_>jMc!-@b6!p>e?J,~>
+ZMsp]MhE:1lEQ;,Z,)*HPkW>WKS50HZ&FXH_1[KXac(n3ah`YHbDu@N+i2?^KSm\.f\V:7PlJ:Q
+N5=e8M!D7(N3U3PN7*rHXoF@%K`9g.K_4+&Su1ZKh@e"a@!,pp`W+2*@Wulg[K$7,hZ!O4TNZP`
+;NUqY:?qlV;JLPk<r;jqVCPj#s8Ag$F)bNbg4NdU@Vj$\RT+Qf<(OLurrCpU!8dMN(8+iTG>aP&
+rrCpUs5!a*s,]^Em!isArr3(t.pCL#rrVh_VYL/ul<7M<F'?-S\H$.<COuM:s+13$s2+g8h>i6#
+]`RYm:4N~>
+m/Iq#o^:r&h:L*"aMYd([^*'9Vkg&ZSXZ(9rKnChR[ftBU8=fhYHt^M^r=IBeCi^>lL4ZKrrCf3
+I3O1,XFl/*\p]!dou,L2I=LRaK7g28I=8iLKmeZp^4!`:L\Q9@^;u(XK>6BnepVt,s1!c<]'Fiq
+l`>_kWk*V3b)LnLs+\XDrn@F)o\'A8UZ;=-'$5c7F^o:-s35XoF`U6bs8N)Rrr4jM=a,'iOoPGU
+kPt?VCO'Poq>C8i/6pd+r2*hAE*oQrK4/n4D8l@><I'C$8[na"!8IMRg\CdaU02\a<K[=]!8IPR
+gAla'O%,l0Ir4TPrr],L>h8fP!qVkXq#:]e>@D_u=LeC>!+YtCf`+;4nEAibd`]SA[B?F"R$!5W
+HZX+9?<9ur6Td7[.Y@^!3ZK4d-nR595Y"RL>[qMgG^tR0Q(=_OZF[lnd+@.:mJ*sd+8tp%kMY%A
+bJ_*&YGe.`PDk3FG]IS2?Wg?8rr8r]48q5^VZ6Wp7nZZY>@D/]FF&LoNg6-0Wj0(K`m*#fj6H14
+JcC<$_>jMh!.sgN!pc:LJ,~>
+m/Iq#o^:r&h:L*"aMYd([^*'9Vkg&ZSXZ(9rKnChR[ftBU8=fhYHt^M^r=IBeCi^>lL4ZKrrCW.
+F!>hnUjIHa[<$DAo>0"!F*HoFH[DQrF*"n.HZOPM\T>=!IJ@k,\\ii:H+W(aeoPncs0[3'[H_s[
+lD/cRUpY8jab+f1s*Mk/rmh'jo[X)0T&0Fs'$#W4F^f1+s35[qGB6Nes8N)Urr4jK>'G0gOT5>U
+lMp`ZC3sSoqu-Pl.pCL'rMEnBEF,TtK4&h2CrQ:?<-a6u8@SX!!8d_UhY@*dTNZP`;NUqY!8dbU
+h>i'*O@Gu2IrFcSrr],K>1NNM!q`"[q#:]d>$cDo>.O[D!+YtCf`+;4nEAibd`]SA[B?F"R$!5W
+HZX+9?<9ur6Td7[.Y@^!3ZK4d-nR595Y"RL>[qMgG^tR0Q(=_OZF[lnd+@.:mJ*sd+8tp%kMY%A
+bJ_*&YGe.`PDk3FG]IS2?Wg?8rr8r]48q5^VZ6Wp7nZZY>@D/]FF&LoNg6-0Wj0(K`m*#fj6H14
+JcC<$_>jMc!-@b6!p>e?J,~>
+ZMsp]MM)/<f#c%f^&EZdhY4/OKG1WAaiW8MKS71`N.d/3_1]AUZ]=j7+h?I9NeFV$e?+CWPlK"I
+akj:UKX'+MakFF]Lt^.ncIRfnK`9g/K`Cc6"5[X6k5F-Lmb47bON7(pqp1R\K=1UVs*sJ9rt+q+
+K7fuks8RT:s8U?%Iur7\ruo3TL%bQHk,a8lZg.SESqE-FpAa!BKr22>_>jObmf.e)q#;-(XFl/$
+oDei?mf3=TJ%u$0OK@f`\+]h$"2RffpA=jkp:%g2rs.8BItt`;s3:FjJcC<$JcC<$_Z0Vl!/0sW
+!q2XSJ,~>
+li.duoBkc$h:U3%ai2*/\[A]FX/W"nUS=I\TGF5qUSXlfXKSq<]"Z&$bKn\khrO%jqYU9mgPUC_
+Y1(8)e[5=(!o*CFrd>H_e&&uP[!dA:`eAhp`kHl0gocG.I3H&SY(qG+l-H5TI?+?M_T(E7I=89I
+_SXj1I=]nh^s(;ZaaO0C!J:@Fm/u-UFlWGT'(";CKTX@Ms8($+K8$]0s8RT9rr3Q(XG);(oDei?
+mJm43Mgpl=rr4.X:kn`Es5pG;LpQ@Ffq*kZaS5_kTSBDPPJ[A"J*m8cmJ-\spT0($VXsifJ*m:9
+m=2nNc]G9p^UEk8rr^)6LA1TF!qs(;p\tKNQ%+Y'rVt+=J(Xcfq!mV.gXOHd^:(5DTph1'KRJ#^
+BOP(D9h.H02)*ne^Eb*Q.P<M:5"&%@=C5WUF*iLqOI)Q9XgG^Wb0el!kO/2Os$HVTmH*3Vd)j,8
+Z`L!pQ]R&UHZa4=@9QW*GQ7\R2D['A0O4YXBg>*[:f^h2BlJ9FKSu"]TVns#]u8+Bg#;/`q18Qs
+s2"a7gAlis[K>c`9n3~>
+li.duoBkc$h:U3%ai2*/\[A]FX/W"nUS=I\TGF5qUSXlfXKSq<]"Z&$bKn\khrO%jqYU9mer"MP
+W6W5qd]rdm!nR+=rc8aOcG@?FZ#aus_0^6M_7=Wkg89;oF!7dAVL<N]kfocAF+jS4]uA^(F*";*
+_84R)F*H3S]uncIa`II4!H\;7l3#aNF5HlH''e2BK94.Is81-.K7gT/s8RT:rr3Q(XFl/$oDei?
+mf3=3Mgpi>rr4.X:keWCs5pD:LU6:Gg7EqYa7fPiTS98LP/71uJ+!>dmeHetpT0""V"=WdJ+!@:
+mXN"Oc]G6p^UNq9rr^)6L%bED!qs+<p\tKPP^eJ%s8U@@J(Xcfq!mV.gXOHd^:(5DTph1'KRJ#^
+BOP(D9h.H02)*ne^Eb*Q.P<M:5"&%@=C5WUF*iLqOI)Q9XgG^Wb0el!kO/2Os$HVTmH*3Vd)j,8
+Z`L!pQ]R&UHZa4=@9QW*GQ7\R2D['A0O4YXBg>*[:f^h2BlJ9FKSu"]TVns#]u8+Bg#;/`q18Qs
+s2"a7ec9d_XTI[M8q6~>
+ZMsp]MM).hXhhiYN;eJ3V88,iKG00D_83C8KS6(sLkLS]U4euGXcE41+I]jCNeF.\^Pmi!PlIDi
+_6&NHKSZbH_6JrPKUf`l\X:Hkrn[[/s7Y:O]hWe6rS@PBg&D0MUgggKrr`(m@^gpgJcC<$JcDDC
+rn[X.o=Y4oS5+S~>
+lMiR6oBkc%hV$E*bK%N8]XYAUYcb(-WMlbnVl6PnX0&S1ZaREX^r4==dFR%/jQZ..qYpQMML>YZ
+W4]dCKDp9#TY?-ZI1q11]Y(7sI=7Z[JUN*CSUHd3Vhb(r+I0C5LOG]C\qPQ\NrPNY]W-O2I=\?0
+]W-U4I?h=V[Zed\rn@I*s7Y1L\kR>-rS%>>gA_<TpnhT2_>aZ;pnhT2[f8\io'>Ale]u4M\?W'/
+S<]+iJ9c0NA6r>791;*-D#aNL/1iJ/2*!if8P`>k@VKb(I>!NAR@pI\[_9W&db<[DnGKQk6Mg9=
+jPAA3a2#3iWhZ)LNJ;q-EGB#i<_uCqs8Qdd.k)kp@K6@&3^?,-;HR:<D01,VM3+'qV6%#8_TC0W
+hraA$JcC<$_>jMh!.sgN!pc:LJ,~>
+lMiR6oBkc%hV$E*bK%N8]XYAUYcb(-WMlbnVl6PnX0&S1ZaREX^r4==dFR%/jQZ..qYpQHMK8rF
+TXhV/HiA'fR(7SCEt`bj\[eM_F*!Y9GB7tsQ?/%iTRHWW+H<UuI<1_'[<lt9K`@.A\YOFjF*F:f
+\YORnF-*f?Z&HbFrmh*ks7Y"G[7YMsrRLu6g&D0MUgggKrr`(m@^ifG6M^3<jP8;2a1o-hWhZ)L
+Ne`.1Ebf2l=&DUZ5W`f^s(O#9/ho4D5!qn;<Es!IDg$P^MisL$VlmJA`66T_iTTe/Z2[/eo'>Am
+e]u4N\?W'/S<](gIs>sJA6i548mhVuBeLtc-n&O(s%YU?78-T]?Y4.sH\.*9Q_(%TZb+)rd+I7<
+me;;4JcERdrmh'jo;r)WPY-H~>
+ZMsp]JV;d2",O51WW%POPlJ+Drn[[/s7Y:O]hWe6rS@PBgA_<FX&ar<j8T,5qL8Ktkl1eTX&ar<
+JcC<$JcC<$T`>#J!/0sW!q2XSJ,~>
+l2MLooBtl(hqHZ0cH=/E^qI=h[C!6EYl:j+YS4:J['mKV^;7b.bKnYhgu.;Zn+c_Y!8E'QgjK<S
+JZI"grd=g-s0R4RgAup+p=f\\9m,LpgApWprrhei=+o_rrrC^JIfP2drrhei=+o_Es$HYUmH*3V
+d)j/9Z`L!pR$!8YI!'@@@U)r291D4bs5Q!p2)dNX5X\1=<*E[AD0(#RLQ7XiUT1T/^W+OJguI\i
+riuJiq=3b1gXOKe^:1;ETph1'KRJ#^BOP(C9LV1ks2HQ7+Wr&Ks2H]L4$cD4<Es$KEHltgNg6-0
+X0T:OaNrGojm;Yks+13ds8LaQK(HDPl^COu~>
+l2MLooBtl(hqHZ0cH=/E^qI=h[C!6EYl:j+YS4:J['mKV^;7b.bKnYhgu.;Zn+c_Y!7l^BgN*I@
+VTG;+ErgsoZuc5t!H\;7ecW<PF5HlH!:&;<"RrHmL$7Rs!8@:!!/'M8"RrHmL$5uF6N$KCjkeV9
+ahkWqXJMMUOc"d=F`1r&>ZO]p7R=rlj#/bP2`Wuc6qL-Q>$trZF*`@lNg6-0Wj0(K`m*#gj6H16
+Z2[/dn`o/heBPtH\$)a(RZiY_I<KOB@9QT'76f)t`[`;X+=+o*`\0225tFaN>[qMgG^kL/Q(4VM
+ZFRclcdpt7m.Gr0JcERdrmh'jo;r)WPY-H~>
+ZMsp]JV<9@!KO;Y_#U5/KER7;f"[=GKE71s["SG8!JLLHh?1GdGNSk\!:JS@"7WR[e)LB-gA6:!
+KBW=;n?J5,JcC<$JcC<$TE"oI!/0sW!q2XSJ,~>
+kl2@noBto*iS<)8dEThS`504%]=PP_rO3HM\[oGf^r"(3bKePeg"t`NlgXfHrrCf)IHc.\LSt$`
+!PFp$I0>;)e%LY<I0#;i[!hr.!J:@FgB5#]FlWGT!:AM?"RrXZdf/;,!8.-t!/9Y:"RrXZdf-]T
+62pTHkMY%AbJ_*&YGe.aP`:EJH#mh8@9Zc09h98D><Y265=%Y,92AMi?Y+"mGCG4'OdMc<XL#LS
+aO&Pqjm;ZEs$HMMl/LFGbJ_*%Y,@q[Oc"a;FDYSq=&;IT4%IQqiKo"Yir@.Z.PNeE6q^E\@;'S&
+IYE`ES"cme\A-)0e_T<Po7?pms2"a7gAlis[K>c`9n3~>
+kl2@noBto*iS<)8dEThS`504%]=PP_rO3HM\[oGf^r"(3bKePeg"t`NlgXfHrrCW$F6R`HIA$JJ
+!On<mEs-iad^O`*ErgdQZuc5t!H\;7ecW<PF5HlH!:&;<"7WR[e)LB-gA6:!KBW=;n?J5,[JrPl
+p@%2&g!\'^]sb,CTpq:+L4FPjD.d9]<`)R^EH,2H4[)(r6UsdF<*<R>CN4QIKStt[T;J]r]"uJ7
+fA>WUos"H_q!dP-g=+6`]sY#@TU:k!JpVTVAR8G78O>L/c2ZahI[/pmau1_'2a'Q%;H[FADg$S`
+N0Ba*WNitJa3N5kjQlDgs+13ds8LRLF7ZL8kEJSh~>
+ZMsp]JV<9@!KO;Y_#U5/KEI16\![,I!Jm_^K`9g2K`BocVYb98VV]!]GNSk\!:GF<JcC<$JcC<$
+YQ+UY!/0sW!q2XSJ,~>
+kPl4np$h;1j58VDeBuRbaiDB<_8*kb^Cn>u_Sa@5air)Ze_/a9jQQ"%rV-<lgOXe;I0#,$qn<*D
+S,Rg=Kr)/@If=`rK;Q#(rn@R-s4c;(qeZM4gU^+%j8I^4m=G;UruUt*lJp[McH!`2ZE'gnQ][/Y
+IX#mLAmnqG;c$.[8,bt!7nH?K;H?t.A86(,I"I08Q(4SJYdV6`bL5)%kO/5OruLk'ki(7DbJV!#
+Xeq_WOGSO7Ebf2j<DH%L3&*@jr;Rn7-m'cf1cn#q;-71;DKU>[MisO&W3EbF`m*&hj6Q:8JcC<$
+_Z0Vi!.sgN!pc:LJ,~>
+kPl4np$h;1j58VDeBuRbaiDB<_8*kb^Cn>u_Sa@5air)Ze_/a9jQQ"%rV-<leq%o,Erg]^qmca:
+Pl>_+H_.BurGr!`TX8e>ec^'of%-MkCB^B^[7YMsrRLu6JcE[g*r,9jj4r21a2#6kX/2DSOc"g@
+G]IV4@9cl4:eXJOr^Ir!8P;fV<a&j@C2e?DJr#JQS>*!e[_9W&db3RAmea6g*V]'eiS)`'_n<CZ
+VOs3:M1KtnCLg[M:.IQ/0fQ'/rue'b+!rQr4$lM9=C5ZXFaSk#P+&)CYd_?dc.1V0lgk%+s+13e
+s8LRLF7ZL8kEJSh~>
+ZMsp]JV8`1rn[g3s5)V02uN^\2l>HF:3Yk!h>ltps+13$s+13$s0)J%h>i6#]`RYm:4N~>
+k5Q%mp[[b;k2P7Pf[\HtcHOJRaSa*Ya:HG:c-Oedf%Jj9j6,aspAXdc!8E'QKmisT"bQd/gS?b+
+!!Y?WgU^+%j8I^4m=G;UruV(/m,d-WdE9A>[]cX(S<].lK7.raChI6a>$"[#;#X32:Jk%k=^>HJ
+C2e<BJVK/JR@pFYZb!uncIL_1lLFkYs$Zk\n*&``d`TJ>[&p3sQ]HrRH#dY0>Z=Ee4u[3Ds4!!G
+LXZ:k>U(aS3C-23='fHTFF8^uP*r#BYID6bc.(P/lLOq*s+13es8LaQK(HDPl^COu~>
+k5Q%mp[[b;k2P7Pf[\HtcHOJRaSa*Ya:HG:c-Oedf%Jj9j6,aspAXdc!7l^BKld7E"`s^pet=o!
+!!Y<Rf!S+khYl"*l@JuRruV(/m,d-WdE9A>[]cX(S<].lK7.raChI6a>$"[#;#X32:Jk%k=^>HJ
+C2e<BJVK/JR@pFYZb!uncIL_1lLFkYs$Zk\n*&``d`TJ>[&p3sQ]HrRH#dY0>Z=Ee4u[3Ds4!!G
+LXZ:k>U(aS3C-23='fHTFF8^uP*r#BYID6bc.(P/lLOq*s+13es8LRLF7ZL8kEJSh~>
+ZMsp]JV8`1rn[[/s8Lj_VDeJT2l>Hg]hWe6rS@PBJcC<$JcC<$JcDqRrn[X.o=Y4oS5+S~>
+jSpM&o^M53jl51Rg=Y!+da?Ffcd'h^cd:(geCN:,h;I>UlL+6>o`"pGJUN6#rn@I*s8La\Uc&2Q
+2Pf*^\kR>-rS%>>JcE[g5Q:BFki1@Hc,[W1Z`L$sRZrhgJphi`DJ<Zk?<gW8=&r@'=^,0>A8#e!
+G'eaoN00HuUoLZ.]u8+Af\biYpTXZcrqGmFi7ZQ$_n3:XV4O$7Lk'bkC1CII9gq6?pA^[$&deaH
+R/ckC.Pa"L85E8mASlO9K8Ph[TW#'&^;\@HgZ.Sirdk*#s2+g8gAlis[K>c`9n3~>
+jSpM&o^M53jl51Rg=Y!+da?Ffcd'h^cd:(geCN:,h;I>UlL+6>o`"pBJTHNdrmh*ks8LRWTJZ]L
+25&OO[7YMsrRLu6JcE[g5Q:BFki1@Hc,[W1Z`L$sRZrhgJphi`DJ<Zk?<gW8=&r@'=^,0>A8#e!
+G'eaoN00HuUoLZ.]u8+Af\biYpTXZcrqGmFi7ZQ$_n3:XV4O$7Lk'bkC1CII9gq6?pA^[$&deaH
+R/ckC.Pa"L85E8mASlO9K8Ph[TW#'&^;\@HgZ.Sirdk*#s2+g8ec9d_XTI[M8q6~>
+ZMsp]JV8`1rn[[/s8CdVVDgH2rn[aj:3Yk!h>ltps+13$s+13$s0)J%h>i6#]`RYm:4N~>
+j8TYhqXa4Dl0%-dhqd&@g"=pUf)O>1f\,!6hVdDTkN_I*qXXXdgOXd,IK%t%K)bf("/Ih5V#K*N
+\kR>-rS%>>JcEXf*Vo9mjkeV:b/D!&Z)XXmR?NVdK78)fE,96#@prdD?Q<KaAS>jtF*E"_L5V1\
+S>)sb[Ca8rcIL_0l1"VSs$HJKki(4Cb/:m!Xeq\VOGJI5Ebf/i<DH"JScAF4)\ikk$l8L8Pq4^P
+5tOmS?=n%sI"R??RA$R_\%]l,eD0*Mnq$gls2"a7gAlis[K>c`9n3~>
+j8TYhqXa4Dl0%-dhqd&@g"=pUf)O>1f\,!6hVdDTkN_I*qXXXdeq%mrF8j_kF8u3i"/%M/T`3LE
+[7YMsrRLu6JcEXf*Vo9mjkeV:b/D!&Z)XXmR?NVdK78)fE,96#@prdD?Q<KaAS>jtF*E"_L5V1\
+S>)sb[Ca8rcIL_0l1"VSs$HJKki(4Cb/:m!Xeq\VOGJI5Ebf/i<DH"JScAF4)\ikk$l8L8Pq4^P
+5tOmS?=n%sI"R??RA$R_\%]l,eD0*Mnq$gls2"a7ec9d_XTI[M8q6~>
+ZMsp]J\d&Vrn[[/s8:aRVZ#?R]hWe6rS@PBi;X+oKA,aCs8TjCp4<6ps+13$s+14(s8LjTK_)kY
+n!m.'~>
+iVsAdq=O4FlfmToj5T"Shu2C?hr*JQjQ5Rim-jNArpg!ggO[(m^AcjfK)bc's.oVJ"1h3Lj8I^4
+mGS!N\qAZ&J,fP`[e>:Pmf+=,p@%5)gXXTj_Rm4ZWMH,QPE(KQJ9uK^EGfQ,B`;WaBPD7!E-$2K
+IY*?6Od;N3Vld;9^W+LGg#(rZp9+E^p[IG+g="0_]X=o?T9t^sJpMKSAR/>483sogfHq[Y()%Au
+eGm$22*=5u;HR=>DK^G]N0B^)WN`kH`m3,ijQlDgs+13ds8LaQK(HDPl^COu~>
+iVsAdq=O4FlfmToj5T"Shu2C?hr*JQjQ5Rim-jNArpg!geq(Ac\c1.\F8u0hs.K>A"1:aBhYl"*
+lJV[K\V&W(J,fP`\+YCQmf+=,p@%5)gXXTj_Rm4ZWMH,QPE(KQJ9uK^EGfQ,B`;WaBPD7!E-$2K
+IY*?6Od;N3Vld;9^W+LGg#(rZp9+E^p[IG+g="0_]X=o?T9t^sJpMKSAR/>483sogfHq[Y()%Au
+eGm$22*=5u;HR=>DK^G]N0B^)WN`kH`m3,ijQlDgs+13ds8LRLF7ZL8kEJSh~>
+ZMsp]JcCH(rn[[/s7Y:O]hWe6rS@PBi;X*DBA2K.s8RRemb@aBL[Ngps24^5!/H.*JcC<$JcE.X
+rn[X.o=Y4oS5+S~>
+hu=&_r:fgPmd09(ki_m+s5s[OlKdj+nb;q[n,ECBJcCH(rn@I*s7Y1L\kR>-rS%>>i;X*GA_?$(
+s8RRcmG%XAL[Wpr!rg*Uqu6]qM9,]ZqXa(9hq?K&`k]0mY,S4gR?WbjL4Xo%G]n1LE,]`6E,frA
+GC"[gKo(hQQ^jeJXKo@M`6-HYh;deiriZ8fq!mV.gXFBc]sb,BTUCt$K7%fZB4"b=916/engc"0
+*?6%?nGf[I3Bou-<*NgGE-HbcNKfs.Wj0(La3N8ljm;Yks+13ds8LaQK(HDPl^COu~>
+hu=&_r:fgPmd09(ki_m+s5s[OlKdj+nb;q[n,EC=JcCH(rmh*ks7Y"G[7YMsrRLu6i;X*DBA2K.
+s8RRemb@aBL[Ngps24^5!/JYq4Sn[9k24k@bf7H0['$C(Ssbh(MhZh5H['^UEc>u9DfB];Fa&.[
+JVAr@P*_]5Vl[26^;S1@fA5KPnG]Tj6MU*8inMr+`P&^`VkBH@Mh?D"DJ*<Y;G0Ebs7.Zd+WVOB
+*q9351-%Qg9iP>+BlJ9FL5hFfUT1T/^rOaOh<""rJcC<$_>jMc!-@b6!p>e?J,~>
+ZMsp]JcCH(rn[[/s7Y:O]hWe6rS@PBi;X)`df9'Ps8RRemb@aB#i=>9"T.>p<eLAN"8CBB#_E#,
+s+13$s0_n+h>i6#]`RYm:4N~>
+g]%KUq=O7JnF-8B"n1sNo_A@MrrCf)s+ULPgAup+p=f\\9m,LpgApX!rs8bQs7Nu's*nnQg]%9[
+h:qr4qrYOlK`1oQpXZ&Ga8[+QnET)jf?qd\^UgeTWMH/TQBI5bL4b#*I!U):GT(jSI=Hj&Ll@F[
+R@U(MXKo=K_o^6TgYqAaq5sZ`q=<k3gssZh^UUMIU77C+Kmn5bBjt:H:.U$;s,&?U,pXaks8RF)
+4[Vh<='fEQEd<4lO-Z?4X0]CRaO&Pqk3_nos+13ds8LaQK(HDPl^COu~>
+g]%KUq=O7JnF-8B"n1sNo_A@MrrCW$s+ULPecBjlp=9>R8orkfec>!nrs8\Rs7a)(s*ntTg]%9[
+hV8&5qrYRmKDkfPpXZ,Ga8[+QnET)jf?qd\^UgeTWMH/TQBI5bL4b#*I!U):GT(jSI=Hj&Ll@F[
+R@U(MXKo=K_o^6TgYqAaq5sZ`q=<k3gssZh^UUMIU77C+Kmn5bBjt:H:.U$;s,&?U,pXaks8RF)
+4[Vh<='fEQEd<4lO-Z?4X0]CRaO&Pqk3_nos+13ds8LRLF7ZL8kEJSh~>
+ZMsp]JcCH(rn[[/s7X,.XA4!%rSAL]hP,Xaa7fQ1c^'3=[JU"(J(B_#s80'VK;ePBrt1=mGM;J7
+s8RRemet_,KpL'^q#:W`Z%n%7k1m2irr4(%c2Z4RIuDSOMZ@tTs80'VK;ePEs*r.KJ%<CoKq@)s
+rrVo'^\Ig3n?m*^J,TBLieUJ4JcC<$JcC<$[K$6_!/0sW!q2XSJ,~>
+f`2!N$N9o!qY9m`r;HWokl1Y;JcCH(rn@I*s7X#+W_IWrrS&:XgnKLba7fQ1d$B<>[/9n'J(0Ot
+s80*WK<"\Drt1:lFkH)2s8RRcmJYV+KpL*_q#:W`ZA=7;jkI&irr4(&cMu=TIuV\PN<"+Rs80*W
+K<"\Gs*r+LJ\&^uL7R)rrrVo&^\Ig3n?m*]J,TBLiJCD3a8[+Wp$V&'gt'ip`P9!kYH"InSX>\)
+Nf/^JKS"dSJ/WujK8#)<NKB?jS"HLTXg5IM_oU-Qg>M,[oW8'Zqt'19h:Bon_7?kPUn*g4Lk0kn
+Ch@$V;G9X4s8KHL@<AsWs3j"l6V'sO>@D2_FaSh!OdMc<XgPgZb0eo#kO/1ts+13ds8LaQK(HDP
+l^COu~>
+f`2!N$N9o!qY9m`r;HWokl1Y6JcCH(rmh*ks7Wi&Ue5^brRMqQhP,Xaa7fQ1c^'3=[JU"(J(B_#
+s80'VK;ePBrt1=mGM;J7s8RRemet_,KpL'^q#:W`Z%n%7k1m2irr4(%c2Z4RIuDSOMZ@tTs80'V
+K;ePEs*r.KJ%<CoKq@)srrVo'^\Ig3n?m*^J,TBLieUJ4a8[+Wp$V&'gt'ip`P9!kYH"InSX>\)
+Nf/^JKS"dSJ/WujK8#)<NKB?jS"HLTXg5IM_oU-Qg>M,[oW8'Zqt'19h:Bon_7?kPUn*g4Lk0kn
+Ch@$V;G9X4s8KHL@<AsWs3j"l6V'sO>@D2_FaSh!OdMc<XgPgZb0eo#kO/1ts+13ds8LRLF7ZL8
+kEJSh~>
+ZMsp]JcCH(rn[[/J+ZP<-[4_OhAadt@Wc-r`W+8.@X!#k[K$7,Dem&dW*4Oh:7V7^&Wd!:g>2i0
+s*ntTdt):Y@!0`is"4,D>]FaeU<@/5qu>XianJ\GHY-%IMZ@tTs/9+JF&&8*rr@7u=uf]5ED2\o
+r;QijS>Q)]"SBs9:4N6B"7!.]!29DnddD\dJcC<$QiI'A!/0sW!q2XSJ,~>
+ZMspZJcCH(rn@I*J+ZM;-?\AIgDe@mA9MI!`;e/-@Wcfe[f?@-DelraWa0mk:Rq@_&WZp7f\6E+
+s*nnQe:VO[@<Kijs"4,F?ZC'iU<7)4qu>[laS/\KH"g"IN<"+Rs/K@MF&/>+rr@8">rl,;E_D\n
+r;QiiR\ol["SBs99n3-A"6m+[!65$uqXa+;iS2o0b/M-,[BZg3UnF6FQ'.5hN/EIKLl$tGMiEd[
+P^JRaU8Fro[(*ifaNi8fhrX1orN-#>rUoUAhq6?!_n<@YVkBH@MhHM%E+rff=&DXi^&@m/+9&f@
+5=A%;;d!I=CiXfNL5hFeU8bB+^;\=Fg>_AdrIP!"s2"a7gAlis[K>c`9n3~>
+ZMspUJcCH(rmh*kJ+ZD8-$.rAef2eh@Wc-r`W+8.@X!#k[K$7,Dem&dW*4Oh:7V7^&Wd!:g>2i0
+s*ntTdt):Y@!0`is"4,D>]FaeU<@/5qu>XianJ\GHY-%IMZ@tTs/9+JF&&8*rr@7u=uf]5ED2\o
+r;QijS>Q)]"SBs9:4N6B"7!.]!65$uqXa+;iS2o0b/M-,[BZg3UnF6FQ'.5hN/EIKLl$tGMiEd[
+P^JRaU8Fro[(*ifaNi8fhrX1orN-#>rUoUAhq6?!_n<@YVkBH@MhHM%E+rff=&DXi^&@m/+9&f@
+5=A%;;d!I=CiXfNL5hFeU8bB+^;\=Fg>_AdrIP!"s2"a7ec9d_XTI[M8q6~>
+ZMsp]JcCH(rn[Xco615Ak5F-VQsd#bbD!>%P$Z&tmW1hsrr@,op\QP8oBqhhp\b%'!8db4!<<(K
+DsW^#amd,ONr/\Q/baHgd-.L?mX90)s-PP<mf9?]g3`So!8dbQ/YM_'PU6)(!1<Z;!)1N"D/o(C
+rrW/[k4\fVmVdUPrrLsVU&P132"6(rJcC<$R/d0B!/0sW!q2XSJ,~>
+ZMspZJcCH(rn@F]o5t)<j8I^PQ=6rcb(R/"OBo]mm;khurr@2qp%pG9naD\fp\b%'!8IP.!<<(K
+D<mI#aRI#NNViSP/baNkcKD4;mX0*(s-PS;mf]T^g3NGm!8IPN0VIt)PU-#'!1<Z;!)(DuD/f"B
+rrW,XjnA]Um;7@MrrLjS`W$hOo'GMsgXXZo`PK3rZ`^=+US+0HR$Nu#P5UL[P*D5uR@HYgS#NNp
+[CX,kaj/AghW3tkr2Tc^p[IG+g=+9b^:1>GU7@L/LOjbnDJ3Ka=&Maa>)AuPTnZN36Uj[D<*<O<
+C2e?EK8PbWSu&Kn\\Q82f%oEQo7?pms1n[6gAlis[K>c`9n3~>
+ZMspUJcCH(rmh(Oo5ar7hYl"FP[LT^bD!>%P$Z&tmW1hsrr@,op\QP8oBqhhp\b%'!8db4!<<(K
+DsW^#amd,ONr/\Q/baHgd-.L?mX90)s-PP<mf9?]g3`So!8dbQ/YM_'PU6)(!1<Z;!)1N"D/o(C
+rrW/[k4\fVmVdUPrrLsV`W$hOo'GMsgXXZo`PK3rZ`^=+US+0HR$Nu#P5UL[P*D5uR@HYgS#NNp
+[CX,kaj/AghW3tkr2Tc^p[IG+g=+9b^:1>GU7@L/LOjbnDJ3Ka=&Maa>)AuPTnZN36Uj[D<*<O<
+C2e?EK8PbWSu&Kn\\Q82f%oEQo7?pms1n[6ec9d_XTI[M8q6~>
+ZMsp]JaS6[rnd2-!93t6*-Z2Xs7tU8oQ>BOs8U%Hs8N)@s8V?aGCP*\!93qV&HL\fh>mTUIrFCj
+4*uI$2f\?`s"4,JCOM8SlMmYjJ,_Zis7]iDK:LNmrrCpUl2Z$XIr>>HrrCdQrr?p&s*ntTmf*@V
+Dh%Za!T!gMrr`4*2t;J!JcC<$RK*9C!/0sW!q2XSJ,~>
+ZMspZJaJ0YrnHu'!8mb0*-H&Vs7tR6oQ56Ks8U(Ks8N)?s8VBdFanmZ!9="W&HLScgAq9RIr44h
+4*lC#2f\Bas"4,LCjhARkl7GjJc.]js7]rGK:C<hrrCgRlN23YIr>>IrrC[Nrr?j#s*nnQmf*@U
+D1DH_!S[UmrttP$lfR-[f$V^^_S3RgZEC4*V4sWSS=>uHR2DB^S=Q:GUnp4#VR3kG_8XRCeCi^>
+l0nMKruV%-lf?mQccEr6Z`L$rR$*A]IsH*PB4>.K<)?:]8H)("7n?9J;,pe,A8,t)H\$s4PaeAF
+YI2$\b0el!k3_qps+13cs8LaQK(HDPl^COu~>
+ZMspUJa.sSrmpVr!8@D&*-5oTs7tU8oQ>BOs8U%Hs8N)@s8V?aGCP*\!93qV&HL\fh>mTUIrFCj
+4*uI$2f\?`s"4,JCOM8SlMmYjJ,_Zis7]iDK:LNmrrCpUl2Z$XIr>>HrrCdQrr?p&s*ntTmf*@V
+Dh%Za!T!gprttP$lfR-[f$V^^_S3RgZEC4*V4sWSS=>uHR2DB^S=Q:GUnp4#VR3kG_8XRCeCi^>
+l0nMKruV%-lf?mQccEr6Z`L$rR$*A]IsH*PB4>.K<)?:]8H)("7n?9J;,pe,A8,t)H\$s4PaeAF
+YI2$\b0el!k3_qps+13cs8LRLF7ZL8kEJSh~>
+ZN#L4J_obM*-GrSs7t0uoQ>BOs8U%Hs8N)Us8V?aH[gNlBBoEp&HL\fh>mTUIrFCj4ahg.EN&O+
+s"43+Z^-)SW;FnQ/_1cqs80X.LNcqrrrCpUl2Z0\IsYhnrrCpUrr@!*s*ntTmf*@VDh%Za!T!gL
+rr`1%3V%b$JcC<$RfEBD!/0sW!q2XSJ,~>
+ZN#L1J_TPG*-5iRs7t0uoQ56Ks8U(Is8N)Rs8V<`H%1<jBC#Kq&HLScgAq9RIr41e4FDX,EN/X-
+s"43+[$H/RW;FqT0%(Tns80[1LNQborrCgRkl?!YIsYhorrCgRrr?p's*nnQmf*@UD1DH_!S[Um
+rtk\0na,Dsgt1!!ai2'/\[A`HXK&4rUndj^(8I\%Vl?`"Y!+8=^Ve+9d+-k-jQc41W;f-]p$V#$
+g!\'^]sk5FUR[X3MM-G'Ec#K"?X$T2;G^.a:/=\b<ENL6ASQ.*H@Ua/P*hl<X0T:O`m*#fip#t2
+JcC<$_#ODg!.sgN!pc:LJ,~>
+ZN#L,J_'2=*-#ZOs7t0uoQ>BOs8U%Hs8N)Us8V?aH[gNlBBoEp&HL\fh>mTUIrFCj4ahg.EN&O+
+s"43+Z^-)SW;FnQ/_1cqs80X.LNcqrrrCpUl2Z0\IsYhnrrCpUrr@!*s*ntTmf*@VDh%Za!T!gp
+rtk\0na,Dsgt1!!ai2'/\[A`HXK&4rUndj^(8I\%Vl?`"Y!+8=^Ve+9d+-k-jQc41W;f-]p$V#$
+g!\'^]sk5FUR[X3MM-G'Ec#K"?X$T2;G^.a:/=\b<ENL6ASQ.*H@Ua/P*hl<X0T:O`m*#fip#t2
+JcC<$_#ODb!-@b6!p>e?J,~>
+ZN#L4J_obM16GhEnB6*UrK(:%oBpZgs8N)Us8VsFW:TVZKE(trqu?ZrhZ)F4s8RRem#l&,o?ET;
+q>W&DYG1C7=F'`5I2$!_s8Vh+hYXPXoD\gEs8+7DoCJo5s8N)Us8N(;mf.cTmem(drT*,7rrVV,
+J,B6Hh>j2J"8l.]oR[$ns+13>s8LjTK_)kYn!m.'~>
+ZN#L1J_TPG16>bEnB-$Tr/Y+!na1Bes8N)Rs8VmEVXa8XL&_1sq>^Hpg]-".s8RRclB,c'o$3T=
+q>W&CY+t=3=F']5IMQ9cs8Vb)hYF;Unc&U@s7n.Anaic7s8N)Rs8N(9mJhZQmJQtcr8Qi3rrVS)
+J,B6HgAo.k(B4'um-!Bag!nBmaMbm-]!o&PYcb(.r2LL4XKA\2ZaRET5:sRkcI1>"i8s7mqPO9V
+p[IG-gss]k_7I"UVkKTFO,8L<G]Rb;An#+P>$+j,<``C,?!q/TCN+EBIt`fCQ^snNYI;*]b0\bs
+jm;Vjs+13bs8LaQK(HDPl^COu~>
+ZN#L,J_'2=16#PAnB6*UrK(:%oBpZgs8N)Us8VsFW:TVZKE(trqu?ZrhZ)F4s8RRem#l&,o?ET;
+q>W&DYG1C7=F'`5I2$!_s8Vh+hYXPXoD\gEs8+7DoCJo5s8N)Us8N(;mf.cTmem(drT*,7rrVV,
+J,B6Hh>kIn(B4'um-!Bag!nBmaMbm-]!o&PYcb(.r2LL4XKA\2ZaRET5:sRkcI1>"i8s7mqPO9V
+p[IG-gss]k_7I"UVkKTFO,8L<G]Rb;An#+P>$+j,<``C,?!q/TCN+EBIt`fCQ^snNYI;*]b0\bs
+jm;Vjs+13bs8LRLF7ZL8kEJSh~>
+ZMsp]J['s7!9WP&'$Go8F^f1+s35[qGB6Nes8N)Urr3t2>'G0gOT5>UlMpkahZ)F4s8RRema$;p
+G@Y^6q>W&FVI"=`?E!i&VG7Dus8VsoC3sSoqu7gTgAdgLGBZrHs8N)Us8N(;mf.cTmem(doUMfP
+rrVV,J,B6Hh>j/I"8bt\on!-os+13?s8LjTK_)kYn!m.'~>
+ZMspZJZaa1!9<=u'$5c7F^o:-s35XoF`U6bs8N)Rrr3t4=a,'iOoPGUkPtP^g]-".s8RRcmEg8p
+G@kp;q>W&EVI+@_?`<o&VG7K$s8VmnCO'Poq>VRQf`.[KGB[&Ls8N)Rs8N(9mJhZQmJQtco9uQM
+rrVS)J,B6HgAo(i(&7@ekiCXUf@/'haMbp0]XkV][C!:>ZN%6E['mHS]=u(u_E]lte_/g=kNh[8
+V>hS5o^1eug!\'_^::JLV4X3@NerC;H?F4EC1_!c@/XFP@:Ee\CMn0:H[pg-OHuB0Vld>;^rO^L
+gYqAbqgncus1eU5gAlis[K>c`9n3~>
+ZMspUJY\$r!8ctk'$#W4F^f1+s35[qGB6Nes8N)Urr3t2>'G0gOT5>UlMpkahZ)F4s8RRema$;p
+G@Y^6q>W&FVI"=`?E!i&VG7Dus8VsoC3sSoqu7gTgAdgLGBZrHs8N)Us8N(;mf.cTmem(doUMfP
+rrVV,J,B6Hh>kCl(&7@ekiCXUf@/'haMbp0]XkV][C!:>ZN%6E['mHS]=u(u_E]lte_/g=kNh[8
+V>hS5o^1eug!\'_^::JLV4X3@NerC;H?F4EC1_!c@/XFP@:Ee\CMn0:H[pg-OHuB0Vld>;^rO^L
+gYqAbqgncus1eU5ec9d_XTI[M8q6~>
+ZMss^K_3(\6A3/U6?/`moYCPpn*/[Amb47bON7(pqp1R\K=1UVs*sJ9ruCd7K7fuks8RT:s8RT:
+s6bC:s1c&:qpCd`PfrmtrsRtjKnm#"s8Tof*:Eh+*R0LlOOjI3TRY\qpT0""V"=WdJ+!@:J%,.O
+^UNq7rrVo'^\7[/p:%g6rrMP;Sc8fg:I=c+s+13$s.02hh>i6$h?.*QS5+S~>
+ZMss[K(QhY6%m#S6#NEeoY:Jnlfm.:m+It`Oi[:sqTb@YKs^aWs*sG8ruCd7KnH8os8RT9s8RT9
+s6Y=9s1c#9qpCdaPg&sursRtkKo!)"s8Tof*q0+.*R9RmOjsF2TRkbqpT0($VXsifJ*m:9J%#(N
+^UEk6rrVo&^\7[/p9qa5rrMM:_#Gt_o^D)-iniD?da-.Z`l,a0^:h1k]=PVd]Y2%o_8F:6bKe<t
+2q6dHl0\-BU]2>.nEJugf$DIU]XG&EV4X0?O,AXAI!BaQDJX'$rb!3aBkhL'Ecu_VJqf2FQCFSF
+XKo@M`QQZ]hW=+rJcC<$^An2e!.sjs"'b)[9n3~>
+ZMssVF7d!C3J=pD3FnkGoXOu_kNUP1lIqh^ON7(pqp1R\K=1UVs*sJ9ruCd7K7fuks8RT:s8RT:
+s6bC:s1c&:qpCd`PfrmtrsRtjKnm#"s8Tof*:Eh+*R0LlOOjI3TRY\qpT0""V"=WdJ+!@:J%,.O
+^UNq7rrVo'^\7[/p:%g6rrMP;_#Gt_o^D)-iniD?da-.Z`l,a0^:h1k]=PVd]Y2%o_8F:6bKe<t
+2q6dHl0\-BU]2>.nEJugf$DIU]XG&EV4X0?O,AXAI!BaQDJX'$rb!3aBkhL'Ecu_VJqf2FQCFSF
+XKo@M`QQZ]hW=+rJcC<$^An2`!-@e`"'4TL8q6~>
+ZMt!_K`Cc6!mL`FL@,,f!+)D5!<;c\!mL`6l.uF.^]+E3UfMDbs4mVVq+F3OJcC<$JcD>Arn[[/
+s7Yj`blI4&:4N~>
+ZMt!\K)bQ3!mCZEL@#&d!*c2+!<;c[!mCZ1l.Z4*_#FQ:pnh24JcGcM')hRpmHN`kh:gK1dE]tY
+aN)9<r50,b`Q$!@bK\D_f%JV?52Y\qq4[gNr:KC>i7c]*a2,BqYH"CjR[&tmLP()(H$4:MEH#i7
+E,frAGC"[fKSYVNQCOYGXKf7J_o^6Ugu@Ser.4m!s1\O4gAup+p?`",!:-(JJ,~>
+ZMt!WF8tt!!m(HBL?\i^!*5hr!<;cX!m(H*l.,k"^]+E3UfMDbs8W*3rV,jLl/gm[g=Oj%cHOGP
+a2Q!p_\'i+`lQ9Fc-Xqjg"&GQhs9e-U&R7Qo^1i"g=4Bf_7R+YWhc8UQ&poZK7A8oG'%bEE,TZ6
+EH?8HH@:<sLlIR`S=ug]Z+%Eaaj8Pnip#q0JcC<$^An2`!H\;7l3,3/kEJSh~>
+ZMt!_K`Cc&!h98jL>E!%!+)D5!<;cL!h98Zl.uF.d/O.5XS[JJJ\h6`"RrHm3RWKYg]%BN84iT-
+s+13$s.B>jh>r<0p>,qB!:QFQJ,~>
+ZMt!\K)bQ!!h',hL>)cu!*c2+!<;cI!h',Tl.Z4*d/O.4XS[JJK#7Eb"Ri<k3mN<VrVmK+o^M52
+jl,(Ng"+[$d*L"^bl5fcbR_tDd*^=mf\50>jPW?mmJNUV)u9$ijkeY<bf7H0[BHU,TUV:2Nf&UE
+JUVumH2Vt+H$ashJV8i;O-H$&U8P)t\%KT!cICS+kO&"ps+13`s8LaRK)bQ!"I]>VRSA;~>
+ZMt!WF8tsb!gE]bL=QEj!*5hr!<;cD!gE]Jl.,k"d/O.5XS[JJJ\h6`"RrHm3RWKYrVmK+o^M52
+jl,(Ng"+[$d*L"^bl5fcbR_tDd*^=mf\50>jPW?mmJNUV)u9$ijkeY<bf7H0[BHU,TUV:2Nf&UE
+JUVumH2Vt+H$ashJV8i;O-H$&U8P)t\%KT!cICS+kO&"ps+13`s8LRMF8tsb"I&oLPY-H~>
+ZMt!_K`Cr+!,qhm!h98jL>E!%!+)D5!<<#S!,qbk!h98Zl.uF.d/O.5XS[JJJ\h6`"7WR[W.G!%
+rr`!a9_j8>JcC<$T`>#J!JLLHh?9>Kn!m.'~>
+ZMt!\K)b`&!,_\h!h',hL>)cu!*c2+!<<#P!,_Vf!h',Tl.Z4*d/O.4XS[JJK#7Eb"RrXZW;V;I
+r;R<,qXa4Cl/q$bhV?i;f@JLMeGn&/f@\g3h;I;Skj.['6qmEKru:t2n*/lgf?qd\^q-qXX/;V^
+R?`qqMhm+@Jq<oO)hETnKnkMDO->luT;/?eZF@K`a3E)dhrX1prdk*#s1SI3gAup+p=f_=!:-(J
+J,~>
+ZMt!WF8u-g!,MPa!gE]bL=QEj!*5hr!<<#K!,MJ_!gE]Jl.,k"d/O.5XS[JJJ\h6`"7WR[W.G!G
+rt#,*oC2,2k2YFWgtLE4f%']Js4%V2f\5*9i8Wk^lgF+-9_k=\)ufR"l/UUOdEBME]!\cCVP9WL
+Q'./cLk^S7Jc:0=JV&N.LP^tNPEqZ0USt<#\%KSuc-tA'jm2L:JcC<$^&S)_!H\;7ec_3;kEJSh~>
+ZMt!_K`Cu,!H.u:h?'2Is+]A3S,cli]`A*2h>mUpr8%LF!:T1/!:GF<PQ(aY6;RH/s8)`rj4o4c
+JcDbMrn[[/s7Y:PS,i#J:4N~>
+ZMt!\K)bc'!Gqi8gB*fDs+]80RK-Qd[K-@+gAq:kr7_:A!:/n(!:>@;[/UX8qXj=GlfmQmio/eO
+h;/%b&`)=$i8WeYkj%R)pAFsa6;RHMs#BoJmc`Zcf$V[\^q7%[Xf/%gS=,\,OH,9XMM[.GM2I4N
+O-,Z]KV"m7Wii\<]u%h7db*F;lL=\%s+13_s8LaRK)bQ!"I]>VRSA;~>
+ZMt!WF8u0h!G_]6ecM'9s+])+PQ4aYXT8D"ec>bdr71q6!9`Ut!:#.8[/UX8qXj=GlfmQmio/eO
+h;/%b&`)=$i8WeYkj%R)pAFsa6;RHMs#BoJmc`Zcf$V[\^q7%[Xf/%gS=,\,OH,9XMM[.GM2I4N
+O-,Z]KV"m7Wii\<]u%h7db*F;lL=\%s+13_s8LRMF8tsb"I&oLPY-H~>
+ZMt!_K`D#-!cJ&=rS@UG!<7f1!h96sU:gR,rSIPS!,qhm!h98Zl.uF.JcCo5"8+lWqgneErrSK,
+hLY]Xs/Z2!h?/H2hVS*Is5!mK!:QFQJ,~>
+ZMt!\K)bf(!c7o;rS%CB!<7f.!h'*nU:((%rS.>P!,_\h!h',Tl.Z4*JcE"T)Z9C%nF#Z.l0.9l
+jlPRajlPXfkj%O&nFZPTrVlum5?%HOru(\)mH<H`f$V[\_7[:aYH+RsTUhR>QB[SrrK.q[PEhK&
+S6Q\fW3!52\\>u&c-k8#j6?%/JcC<$]Dqlb"+pR-g\PdegB<rFl^COu~>
+ZMt!WF8u3i!c%c9rRM%7!<7f)!gE[cU9+FqrRUuK!,MPa!gE]Jl.,k"JcE"T)Z9C%nF#Z.l0.9l
+jlPRajlPXfkj%O&nFZPTrVlum5?%HOru(\)mH<H`f$V[\_7[:aYH+RsTUhR>QB[SrrK.q[PEhK&
+S6Q\fW3!52\\>u&c-k8#j6?%/JcC<$]Dql]"*=Lnf(s1^ec_3;kEJSh~>
+ZMt!_K`D&.!,qi:rS@UG!<7f1!h96sU:gR,rSIMR!,qkn!h98Zl.uF.JcCl4"7nWUr.4nFrrRco
+i.:oZs/c8"h?8N3hVN2K!!dH!hOFT7S5+S~>
+ZMt!\K)bi)!,_]8rS%CB!<7f.!h'*nU:((%rS.;O!,__i!h',Tl.Z4*JcDnQ#Q=MmoC;>=melJP
+mKN(LoD&7_q>UQg4BDBPs"sQBm-!?_f?qg`_nN^jZEC7,V5']TSXZ(:R@0M4S=Q:GUS_'+R^9K9
+^r4@?e(EO;l0e@us+13]s8LaUK)aT[D>XA=D;3g6!:-(JJ,~>
+ZMt!WF8u6j!,MQ6rRM%7!<7f)!gE[cU9+FqrRUrJ!,MSb!gE]Jl.,k"JcDnQ#Q=MmoC;>=melJP
+mKN(LoD&7_q>UQg4BDBPs"sQBm-!?_f?qg`_nN^jZEC7,V5']TSXZ(:R@0M4S=Q:GUS_'+R^9K9
+^r4@?e(EO;l0e@us+13]s8LRPF8shBC]"/;CY%($!9]S=J,~>
+ZMt!_K`D&.r;cfQ!h98jL>E!%!+)D5!<<#Sr;ciR!h98Zl.uF.JcCi3"7eHUrIP"GrrRWmidq,\
+s/l>#h>r<0rndPQrn[dJ!:QFQJ,~>
+ZMt!\K)bi)r;cfN!h',hL>)cu!*c2+!<<#Pr;ciO!h',Tl.Z4*JcDbM%0$5'qtg-`q>1$frr2Qi
+"7eHUrLa**q"!e7in`89cH=,B]t(SXYH=h'VPU'cU)'N"V5L;nY-;"EV7sgebL"blhW*kgpjrHr
+s1/1/gAup+rnI>Nrn@RE!:-(JJ,~>
+ZMt!WF8u6jr;cfI!gE]bL=QEj!*5hr!<<#Kr;ciJ!gE]Jl.,k"JcDbM%0$5'qtg-`q>1$frr2Qi
+"7eHUrLa**q"!e7in`89cH=,B]t(SXYH=h'VPU'cU)'N"V5L;nY-;"EV7sgebL"blhW*kgpjrHr
+s1/1/ecBjlrmpuIrmh4:!9]S=J,~>
+ZMt!_K`D#-rW)oR!h98jL>E!%!+)D5!<<#SrW)oR!h98Zl.uF.JcCf2"7\9UrIP"GrrRKljFR>^
+s/uD$h>r<0rSIMRrS@[I!:QFQJ,~>
+ZMt!\K)bf(rW)oO!h',hL>)cu!*c2+!<<#PrW)oO!h',Tl.Z4*JcCf2"7\9UrLa**q"!h9j5/J>
+d*0SL_7dFh[Bd$>XfJN$WYMS9Xfo"9[CEhP)mRN1dam12jQZ..JcC<$\GuQ_!J:@Mg\q3OgB<rF
+l^COu~>
+ZMt!WF8u3irW)oJ!gE]bL=QEj!*5hr!<<#KrW)oJ!gE]Jl.,k"JcCf2"7\9UrLa**q"!h9j5/J>
+d*0SL_7dFh[Bd$>XfJN$WYMS9Xfo"9[CEhP)mRN1dam12jQZ..JcC<$\GuQZ!H\;>f)>[Jec_3;
+kEJSh~>
+ZMt!_K`Cu,rrE#S!h98jL>E!%!+)D5!<<#SrrDuR!h98Zl.uF.JcCc1"7J$Srdk+HrrR<ik(3P`
+s0)J%h>r<0r8%DRr8%RH!:QFQJ,~>
+ZMt!\K)bc'rrE#P!h',hL>)cu!*c2+!<<#PrrDuO!h',Tl.Z4*JcCc1"7J$Srh'3*qXa.>jP\eE
+e'H7Z`PTC&]"#2V['Tb;s0EBG[C<]Y]thP*>TUQ.g"kWLlgXb%s+13Zs8LaRK)bc'!!)rO"I]>V
+RSA;~>
+ZMt!WF8u0hrrE#K!gE]bL=QEj!*5hr!<<#KrrDuJ!gE]Jl.,k"JcCc1"7J$Srh'3*qXa.>jP\eE
+e'H7Z`PTC&]"#2V['Tb;s0EBG[C<]Y]thP*>TUQ.g"kWLlgXb%s+13Zs8LRMF8u0h!!)rJ"I&oL
+PY-H~>
+ZMt!_K`Cr+!!)uS!h98jL>E!%!+)D5!<<#S!!)oQ!h98Zl.uF.Rf<HK@t0(0p\t?`0P167s82ft
+E@C%%s+13Ss8LjUK`Cc&"IoJ\S5+S~>
+ZMt!\K)b`&!!)uP!h',hL>)cu!*c2+!<<#P!!)oN!h',Tl.Z4*Rf<HJ@=Nk.p\t?`0P16Us"+*?
+nE]8shV-T1d*0YQ`59=)]tCth]">Se]Y;.s_o9^>c-]f?aPc.CmIU:-s+13Ys8LaRK)bQ!"I]>V
+RSA;~>
+ZMt!WF8u-g!!)uK!gE]bL=QEj!*5hr!<<#K!!)oI!gE]Jl.,k"Rf<HK@t0(0p\t?`0P16Us"+*?
+nE]8shV-T1d*0YQ`59=)]tCth]">Se]Y;.s_o9^>c-]f?aPc.CmIU:-s+13Ys8LRMF8tsb"I&oL
+PY-H~>
+ZMt!_K`Cc&!h98jL>E!%!+)D5!<;cL!h98Zl.uF.S,WT^IgggXs7ZHoln3"'s8)`sD(Fn&s+13T
+s8LjUK`Cc&"IoJ\S5+S~>
+ZMt!\K)bQ!!h',hL>)cu!*c2+!<;cI!h',Tl.Z4*S,WT^IgggXs7ZHoln3"DrtGD+o'P]'iSN;?
+eBuUdb/hWB`5MVl&]DZ.a2uNLd*gIsgg;DWlgOS!s+13Ws8LaRK)bQ!"I]>VRSA;~>
+ZMt!WF8tsb!gE]bL=QEj!*5hr!<;cD!gE]Jl.,k"S,WT^IgggXs7ZHoln3"DrtGD+o'P]'iSN;?
+eBuUdb/hWB`5MVl&]DZ.a2uNLd*gIsgg;DWlgOS!s+13Ws8LRMF8tsb"I&oLPY-H~>
+ZMt!_K`Cc&!h98jL>E!%!+)D5!<;cL!h98Zl/!BI]gW2MORE/CTIgE\C\Rl/!3IE's7^"7#ZC-h
+s"W@1V&021n+Zj3<bGIPpRj)H4gFna]gW2MORE/GXZ6eAT_JKdV',gUSH&Vc+TN@Lqu6]R!;6?o
+TN3q"JcGEC!pV:QJcGTH!bj7QJcC<$ZN'p\!JLLHh?9>Kn!m.'~>
+ZMt!\K)bQ!!h',hL>)cu!*c2+!<;cI!h',Tl.[0C\jd)ROR<)BU+Q]_C%qZ-!3.0!s7^(9#Z^?k
+s"W7.VAKG5lh1:-<Fo1KpS'8K4L"_]\jd)ROR<)FXuZtDUA+]fVBc-]RfEDb,QJgQqu6]O!;?Eq
+rLR(KIt@XmrrVI9D4U\=qt0CEl/gp^gtC</da?Cdc-611s3)"ucHstfe^rO2i8`s-.cC2Ts+13V
+s8LaRK)bQ!"I]>VRSA;~>
+ZMt!WF8tsb!gE]bL=QEj!*5hr!<;cD!gE]Jl.-g=]gW2MORE/CTIgE\C\Rl/!3IE's7^"7#ZC-h
+s"W@1V&021n+Zj3<bGIPpRj)H4gFna]gW2MORE/GXZ6eAT_JKdV',gUSH&Vc+TN@Lqu6]R!;6?o
+TN3q"JcGEC!pV:QSc9<!o^M53jl51Qg"4a%dEg+_bl5fcbR_tDd*^=mf@o'=j5s`!i;8**JcE(V
+rmh*ks7Y"HPQ9m28q6~>
+ZMt!_K`C_8!<E.RS,iUrU:gR,opc$_n*/[JYuZA6Ue.*VW(r`ChD'*Orr=d]n,HQhkMAg'r;SP/
+!(,Pn3DugUIi*7TpS^iSieLFB_,c'FUe.*VXB(kNPY.bOmf9Ka[/f[a!3Q"'!:Tjc!V`,Xrrg#I
+Qu@J*s7H<mkUCM&s82furamkOJcC<$ZiC$]!JLLGS-&c[S5+S~>
+ZMt!\K)bM4!<E.RRK3CmU:((%opPm]lfm.CY#g25U.CdRW(iT<gG!dMrr=mali16jj53F"r;SP,
+!(Ges3)QXSIi<IVor(TNhh=t>^fQ*GU.CdRY$%:RPY%\Nmf]fb[K,db"Kq@)!:Tjc!V;cRrrfuG
+Q>M,&s7H<mkUCMArsnntnEoK&jPf"Og=b*/ebmqseIL0_g"Y??ioT@hmdamBm=G:gs0Mb)gAup+
+opPs_l^COu~>
+ZMt!WF8tot!<E.RPQ:bbU9+FqoooIWkNUP:X]Br2Ue.*VW(r`ChD'*Orr=d]n,HQhkMAg'r;SP/
+!(,Pn3DugUIi*7TpS^iSieLFB_,c'FUe.*VXB(kNPY.bOmf9Ka[/f[a!3Q"'!:Tjc!V`,Xrrg#I
+Qu@J*s7H<mkUCMArsnntnEoK&jPf"Og=b*/ebmqseIL0_g"Y??ioT@hmdamBm=G:gs0Mb)ecBjl
+oooOYkEJSh~>
+ZMss^KRj-r!!$?"^%24(n*/[KIr!d<o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpUn,<8@h>l.,s4.0s
+qgVf's8..]mf2!QMi_`.s7=(Oqg3P]s6afLn*^7Qp](!fmf93Ys7c!^"kmaNl>M0's7?6lk9b>&
+s82furaI\PJcC<$[/^-^!/0qD!q2XSJ,~>
+ZMss[Jq3pp!!$5t[dsJ!lfm.DI;@R:o>&TGH#;sKs0`pIrrBM-s7ZZ^s8UsVn,<8@gAok*s3gsp
+qgVi(s7pqWmJkmSNK7l/s7=%MqgE\]s6jlMn*^CRp]'jbmf]BZs7>^Z"kmgOkA>^"s7?6lk9b>@
+rsekuna>`-kN([^i83;GrS/"@hV[8Mj5oIhm-jTDs8HI`mt(Lis0Vh*gAlis!!;JT9n3~>
+ZMssVF+F>a!!$&oXn)MmkNUP;HY_@8o>/]KHZ/?Ps0W^DrrBJ,s7ZN^s8UpUn,<8@h>l.,s4.0s
+qgVf's8..]mf2!QMi_`.s7=(Oqg3P]s6afLn*^7Qp](!fmf93Ys7c!^"kmaNl>M0's7?6lk9b>@
+rsekuna>`-kN([^i83;GrS/"@hV[8Mj5oIhm-jTDs8HI`mt(Lis0Vh*ec9d_!!;>J8q6~>
+ZMsp]Ja\<]l.uJ[C[1lu!q'uVrr38T!<<'!hZ*W4qZ$WIrVloT!<)p0!,q:TDsmYnDh%fel>(m!
+C[1lu!Uan(!"Neqs1M#93OSne]h/hr[IF2$o6Y90k%f>@JcG?A!p(\QJcGWI"8uO`n:CUjs0_n+
+hXU%8S5+S~>
+ZMspZJa8$Ul.Z8VC[:s!%e"=arVuoL!<<'!g].<2qZ$WJrVm\g!;lfrqZ(R'Ir4TQmr*XQs6FHM
+Ir"BKrrMS,qu@4BfDiQZ&3-uqs1V2=33r&R#kNI[gZ*!np\f[Co`#!S,^GjY)ZBL(naGl2l0.<m
+jlPRajlPXfkj%L$n+?DRrVluu?8_5's+13Xs8LdClN*GKJ,~>
+ZMspUJ`haMl.5lM!:'O_!q'uVrr38T!<<'!hZ*W4qZ$WIrVloT!<)p0!,q:TDsmYnDh%fel>(m!
+C[1lu!Uan(!"Neqs1M#93OSne]h/hr[IF2$o6Y90k%f>@JcG?A!p(\QRf=<)q=O4GmHa$#kN:mf
+jQ,Fak3(snlg=05q#10k"8uO`n:CUjs0_n+f(%o(PY-H~>
+ZN#L4J_kt7J_oqR!lZ0rQJVStpYc&.pYH#-:,(+IhLXOYh>s-AJ,~>
+ZN#L1J_Pb1J_T_L!l>snR+hl"f@80mcHXT2bQ#cic-F\cf@p&T"5-C&c[ji%gS<L(RSA;~>
+ZN#L,J_#D'J_'AB!koXfR+;Mmda-+ZaiMO#`rF'_aN;WOdae0E"4TsrbCS5qet^dsPY-H~>
+ZN#L4J_kt7J_onQ!lGssJ_p:\"5?I)dt-A,hPB!/S5+S~>
+ZN#L1J_Pb1J_T\K!l5goQ.l`$g"=p-e^W.#f@em3o\0K#8i"bEgO\+TgB!a;J,~>
+ZN#L,J_#D'J_'>A!k]FgQ.?)geC2jnrm1eqdaZgto[X,n8MSD>eq)DJecD"-J,~>
+ZMsp]^&J'4iW&q-f`1u$g]%6R_#FB7\GuSYao;BkDh6d7h?(M2FSjnpfn/&_g.4*OJ_kt7V;;6C
+:4N~>
+ZMspZ^&J'4iW&q-f`1u$g]%6R_#FB7\GuSYao;BkD1UI2gB,)+F8O\leq2WYf1.^HJ_Pb1V:u$>
+9n3~>
+ZMspU^&J'4iW&q-f`1u$g]%6R_#FB7\GuSYao;BkCOt(+ecNE"E;S2dd=TpOdR?";J_#D'V:G[3
+8q6~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?n(n,\(O5l7
+!J'!Xh?2G"37`Z;J_m9\!Luo8~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9n(RoV(O#`2
+!IrgTgB6"p2q*?4J_R'V!Lc`5~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/n(%QM(3BE)
+!IWFLecX;e2U6m)J_$^L!L-3,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?mbS#Y(46#:
+!E"u1h?2Ft44f&?J_m<]!Luo8~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9mb7fT(4#l5
+!Dni.gB6"m3n/`8J_R*W!Lc`5~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/ma_HJ'mKW-
+!D\T)ecX;a3R<9-J_$aM!L-3,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?mG7oW'S$,=
+!_F*YJ_gL]5<d\MhLXO^h>s-AJ,~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9mFq]Q'Rfu8
+!_=!TJ_L:W5!@DHgO\+XgB!a;J,~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/mFD?H'RKc0
+!_*jMJ^sqM4Zq)Beq)DNecD"-J,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?m+quX'S>2u
+70%[ch?;]e4@.VNhLXO_h>s-AJ,~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9m+VcR'7eil
+6i_L`gB?9\4@%GJgO\+YgB!a;J,~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/m+)EI'7JH_
+6ND=]ecaRM3^1oAeq)DOecD"-J,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?leVlU&r,70
+!"7/)h?;]d3^_SOhLXO`h>s-AJ,~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9le;ZP&qo"*
+!"7)'gB?9[3C;;JgO\+ZgB!a;J,~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/ldc<G&V8Lt
+!"-i!ecaRL3'krCeq)DPecD"-J,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?lJ;`Q&W&aQ
+#@rDBs5!k.2b2SQhLXOah>s-AJ,~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9lIuNK&ViRN
+#@`8=s4[Y(2Fc;LgO\+[gB!a;J,~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/lIH0B&;34I
+#@N,6s4.:s2+5lDeq)DQecD"-J,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?l.uWM&1.AW
+#/u/Ms5!k-2+lVShLXObh>s-AJ,~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9l.ZEH&1%;V
+#/YrGs4[Y'1eH>NgO\+\gB!a;J,~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/l.-'?%jV,T
+#/5Z>s4.:r1IooFeq)DRecD"-J,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?n(nK.LaX/[
+*?Q1#!!!0sJ_pC_"4K#"gO\44hQ>W8S5+S~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9n(S9(L+!oX
+*?H+"!!!0rJ_U1Y"4/brfR_e.gTB32RSA;~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/n(%osK-qNT
+*$-"!!!!0pJ_'hO"3WAjdt-)$eudL(PY-H~>
+ZMss^s8:aO!!,*nbME;j!<;uRqu@!_^!5DP?Hq>FrW!$'-%s_Fh?1GdJ+!9l!,qc8"$+'OhY[?Y
+3PF;+!577Gr;Zm)6H8r["2.HZmekoJdYKI\$q7,OhJ`>m"rr!7hVJ7GrS@Rg!<(aUS,iTehY[?W
+6I+H4?>oSp!cMDihqeF)!<;uRqu?mDLt9gWDti)iDdL]?h?1GdJ+!<m!N\H]!!5p/Du9S:#YND@
+h?&W9;Z,AT`_$dB(j#]5qZ$X2KDs^/]hWKshX0/#_*Rks!=#u`hYu@6d4\>OJ_kt7Y202L:4N~>
+ZMss[s8:XM!!39_]$&h0RK3Bcg\h*Y"?=!8gML<AgMQoi!sBs%bl-8u\kR\ArS%<hr;Zs'34dl!
+r;[*+34dl!!5@4Br;Zm)7DA]S"1h3VmJP]Fb_%AL%S!>MgMQoi#6Grlb1kYN^AZde^&\,d!h',h
+r7h/M"p@B<gWX#ApY,ad?d.E^!h',hr7h/M"p-'+e')09pY,ad?d.-V"1h3VmJbi@W]^.Y!`-IG
+qu?d(8]Uea!ep\Pr7_Ch8IPS=EW4_i!!*jfrn@Lc9l5I9mFqZU5ktB\#./s9rn@P#02L8PgO\+^
+gB!a;J,~>
+ZMssVs8:IG!!,*fbLQ`Z!<;uJqu@!_[Dg^4?HLc6rW!$'-%F&8ecW<PJ*R!`!,MK4"$*d?f),LQ
+3ORGh!56t7r;Zm)6G<<J"1:aNlMT3>ab)#F$q6uCenb3a"rqj+f%'i7rRM"_!<(IMPQ:a]f),LO
+6H7Tu?>K;d!c),ahpqjn!<;uJqu?mDK[.\GC\QB]CL5-7ecW<PJ*R$a!N80Y!!5p+C]"/6#XZQ0
+ecLL)9)R6D]h/P1(j#]-qZ$X2J,\"#[7Y4cf'V#h\j#oi!=#cZf)F5&at?E<J_#D'Y1<W<8q6~>
+ZMss^s8:^X!3OPl]g=0kh?'2Is8:^g!3OPl]g=0#hJZ`FhJZH.b.2jNDq=pE"2.HZmetu`DcXQs
+cFlOnhVJ77cHa*i.Gin]^#%TGXj4qg8eB;Hh?1GdJ+!9l("-kTLV9Z^4f$qQ<kZetIl2l8h>k7f
+h>t:irS@UG!<;uR$373RcF#AnhU\3mqq_O$CXV'X?HqBa!h98jr8%b\<kZepF#f?5S>?&=#'Xk2
+hJZ`FfA6VC:4M^2h@/,dcFm7kcHb"tDcXRNc2tC.6N,aC3>`%Qrn\%&&6cK]N"Bd]h>j\Uc2cGp
+h?(AcDh6d2h?'W"$N'l)!]GVdrS@Y'/Q:L'h>l2ZhLXOkh>s-AJ,~>
+ZMss[s8:UU!34)[[RDUfgB*fDs8:Ud!34)[[RDTqgML<AgMKs#a1?[OCXN.9"1h3VmJYc\D,n*d
+a0nDbgY2_.a2bVW.,3JV^>%BBWlN/_9b>ADgB5#]J*m3h("$kVKt=3Y4JLSI<Og)`I5ZZ2gAntd
+gB#"grS%CB!<;uO$37*Ha0INjgXDO_qqD<tB?]+I?d.E^!h',hr7_PY<Og)^F$,Q5R%X?2#'FS&
+gML<Af@pD=9n2R0gC2]Ya1,,Za2cNZD,n+F`r`P'62fO?3#DqMrn@h$'Nq`ZNY#pZgAn8P`rX<2
+rn@Lc9l5I9le;K<+q"5J!<P01g\ok/c7DlIr7_5%J_Pb1[G(_N9n3~>
+ZMssVs8:FP!2[]T[6c=cecM'9s8:F_!2[]T[6c<len\U6en\0k`jpFJCX2q1"1:aNlM]9TCJqR[
+`jJ,^f%'ht`l>DQ.G!&M^"1a7V8gNW8eB#@ecW<PJ*R!`(!1&BJ$l(I4eUAA;RONXHSp<(ec<D^
+ecEGarRM%7!<;uJ$36pB`iUs^f$9MMqpksmB$&V>?HM*U!gE]br722T;RONTD`Nd%PaqX%#'4Cu
+en\U6f@C&38q6.*edU!L`jJ]S`l?<TCJqS>`WE7s3W7M20c12ArmhIj&5oXDN"BdUec;QE`W4<`
+ecN6OCOt(&ecMQh$N'l)!]5JZrRM(m.o=doec='Jeq)D[ecD"-J,~>
+ZMss^s8:^S!58Bg!mUekbh`Dk!<;uR!<Bh4h?qO.B@_!-c/*AFc2QQ$Mb]rEh?1GdJ+!9l!cMDi
+rn[h(!7'F$^&Hjpc2c/H!577G!58?f!BFZgh?1GdJ+!9l!gllQrn\0n8orj-?Hq?`en8XHh>k7f
+h>t:irS@UG!<;uR!<Bh4h>s_YpYH*m?Hq>F?HqBa!h98jr8%YY?Hq?``E$pPh?In)c/*AFc.CeS
+]hX(Fqq_D!?>of!!cMDirS@RW!<1gX`W2h8PlBP>;Z5GUN!S:s!580a!kh?IJ_o\K"5ShE#lO`(
+#Gcq-rS@Y&.TbI)h>rA[J_kt7[b_%T:4N~>
+ZMss[s8:UP!5AHe!m:SabhE2f!<;uO!<Bk5gBu+(A'o.#bhHuAbl6>uMbKZ?gB5#]J*m3h!c;;g
+rn@V"!6<go^Acjnb5fT;!5@4B!5AEd!BaZdgB5#]J*m3h!gZWHrn@sh8T3:!?d.9Zdq*%:gAntd
+gB#"grS%CB!<;uO!<Bk5gB"G[pY,mh?d.8A?d.E^!h',hr7_GV?d.9Z`*%$RgBMM%bhHuAbh(SO
+\kR\AqqD1r?Z#br!c;;grS%@U"TI-Y`rMh:P5a2:;,.#D"c<T;gAnt_gB+r\D1UI,gB6/c%LE"5
+!=,?Mg\ok/bUQWHrS%@+d"0r&gU>i;RSA;~>
+ZMssVs8:FK!58B_!lb5[bgli[!<;uJ!<Bh4edBCsA'Sjrajt66ao9imLImm4ecW<PJ*R!`!c),a
+rmh7m!63Ri^&HRh`W4$0!56t7!58?^!BF?^ecW<PJ*R!`!gHHArmhUb8oN9r?HLdLc=:A0ec<D^
+ecEGarRM%7!<;uJ!<Bh4ecDlQpXTOa?HLc6?HM*U!gE]br72)Q?HLdL_,b@Heconrajt66ak,)G
+[7Yr6qpkhj?>KMj!c),arRM"O!<1OP]`=Q&PlB57;G-o="cN`<ec<DYecN6OCOt(%ecXHV%LE"5
+!=,3If)=/%a!js;rRM"#bCS5qf!a-1PY-H~>
+ZMss^s8:^S!58Bg/C"78h>icWHf!%?#RE/Pg>8Vg#TS39hV+>O#Ut_`hRQf$$r4(a\QTOE(khV>
+!h98jr8%GS^&Hjqc2_A&DdL]FDdL]fh?(5kJ,\:,]hX(FrS@To?HrK+"jR+fh>k7gh?hI-`ng^/
+hVJ7GrS@R>+oU7"]hX(FrS@Ts?HN0&s3_>4DdL]FhUZ=LdbXu;rS@Rg!<(aUS,iTeh>mVirn\Eu
+#i<g4Dr,D)<_5jk#ZeWW6;e@'<k8.b'Y.BY$lFZShUYj9#YND!hJ3Z&3PGCJ!h98jr8&@m?Hq?`
+a^0&5?>n\=8leMT$j]nIDaI>5$s'q9hAcN[.0(3LhVOJ?!#UCGhUYj9#YND!hJ3Z.*.,s0h?1Gd
+J+!3j!mP%irS@To?HrH*!OW44h?80BhEjR.h>mnir8%RrhVJ7Gptc(c:2b^?khZEjBa+b?!!+;"
+J_p@^"3r;th>Z73E,:*^J_mil!Luo8~>
+ZMss[s8:UP!5AHe/B\%2gAmBRFkb)2#RiJUg"W5`$6FQ<gXhZD$7Le\gU(#n$r=+^Zr[e=(l%b=
+!h',hr7_5P^Acjob5btsD-tNAD-tNdgB+lhIK%t'\kR\ArS%Bj?d/N("j6n`gAntegBl%'_qP1*
+gY2_BrS%@=+T:$s\kR\ArS%Bn>K$Nq&)#4RgML<AgY:1g@F*[.^AZde^&\,d!h',hr7_5P^Ack&
+Xpj(/?Z"P78QA5L$j]kED*q;;%TTt8gD%"r&.BD1gY:1W$j]GJgY6ER"?=-ogB*fDs8:Uj!+3t)
+gVdB=b[55AD+R_s7LTQ&\nsf7'Fn-OqqE(jQ7N.UP2"`O+9375gY:1W$j]GJgY6ER$6FQ<rn@Od
+9n2R-gB,T+D>i2jD-tNcgB"G_rn@Qu*8<bJrn@GZY5R)Yf>H@t!5A6_!kM*CJ_TDC"41Zb"o\K&
+,2.V&rS%Ft-s54&gAu2-J_Pb1[bChO9n3~>
+ZMssVs8:FK!58B_/B.\'ec:pOF4S>t#RE#DdajpK#TS35f$]X3#UtSTf!/*]#YM5MYu1u1&;9c.
+!gE]br71lK^&HRi`W0>eCL5-6CL5-^ecN6[GQ-.q[7Yr6rRM$c?HN2t"i^PUec<D_ed9=r^"*1s
+f%'i7rRM"6)#`"f[7Yr6rRM$g>/C0gs2b]#CL5-6f$7c3ajpI*rRM"_!<(IMPQ:a]ec>carmhje
+#hI+(CY!8n<^fFc#ZA'G6;e@'<jhkV'X:OE#S;[?f$7/!#YN+femf6k3PGCB!gE]br72ee?HLdL
+_-1d!?>J,-8leAL$j]b=CI1o1$s'e5ef4[S.0(3Lf%,cs!"ah7f$7/!#YN+femf6s*.,g,ecW<P
+J*Qp^!m+barRM$c?HN/s!NcY,ec^%2ej;_&ec?&Yr72"af%'i7psoMS8o'"/kgfjZAHi>;!!+7n
+J_'eN"3)]hec+,#ChSCNJ_%9\!L-3,~>
+ZMss^s8:_/!4CD/`_%E2h>f:#cJClJ`k?F_TVtV,`Jcs8hO%&o`d^",en7U_\P?qgB1fS_S,h.7
+h?'2Is8:^a!4CD/`_%D(hJZ`FhJZ`Frn[_$?>oi""2.HZmetuZDd(-2f#C<*hVJ7?f%.i5+l;&U
+^#%TG^&?dg]`A#f"2.HZmf)&FdUR(HqVDTu>/f(<Lc'\=h>k7fh>t:irS@UG!<;uR)Z[:sf#B^R
+hT]AFhJX6C[FT8&c/*@UHd\iUF8ar1en7U_\XWZNhGQtc`]6'9F"+fJ8hp;$!h98jr8&@m>/f(<
+In?0T?>n\=(hU2,DdL]FD]!iLW',5!hAcMU`nkJ:hTc+cesl`khGQtc`]6'9F"+fAN'2sqh?1Gd
+J+!3j!mP%irS@To>/gKl!kgp(rn[r1CYk!Mf&"CHf(n/'!4DaU!8@G/!kh?IJ_oPG#/`k6!<<Ff
+J_p=]!mDusrn[]n#0DGQJ_mlm!Luo8~>
+ZMss[s8:V,!4()&_bDE2gAidrbM,HJ_n'hWTVbD&_Mg[4gQkQg^jS>'eRqO^[S:D\B1oV\RK1\.
+gB*fDs8:U^!4()&_bDD+gML<AgML<Arn@Lq?#T_s"1h3VmJYcVD-=a)e&+m*gY2_6e'l3/,hq&R
+^>%BB^AZde[KQQ`"1h3VmJbiBcXCP>qV)Bp=i/Y2LcBn=gAntdgB#"grS%CB!<;uO)Z[1me&+:R
+gWX#AgMI^;[*rl!bhHtOH-`?OF8ai.eRqO^[[I3BgJLP[^-"O4E@AEA9ecP#!h',hr7`.j=i/Y2
+InZBV?Z"P7(1jl%D-tNAD&@QEVET(ugDg2M_q/`6gWokce!^9_gJLP[^-"O4E@AE8N';spgB5#]
+J*m-f!mG"grS%Bj=i10e!kLKsrn@`-D;0pNceH>;e+q`!!4)RP!S,m&gB+r\D1UI(gBPJ^"p"]1
+Ne,s_gB,JC>Q3@YC^.q2gO\+ggB!a;J,~>
+ZMssVs8:G'!3OPl]h0I!ec7.h`n!I:]sVcJS=i>e]neh(es&p^]mDbpdUu1W[8(A[B1fGSS,gk/
+ecM'9s8:FY!3OPl]h0Gpen\U6en\U6rmh.i>&4,g"1:aNlM]9NCKA-ocFlgnf%'i'cHa*q+kG3E
+^"1a7^&?L_[/g0V"1:aNlMf?:a^/W.qUQ$i<kZetK/J#,ec<D^ecEGarRM%7!<;uJ)Z["ccFl5A
+f#_66enYt/Z-I,kajt5EGKHXDDuJ6%dUu1W[@@6Bel#,R]fA+(CE^+*8hp:q!gE]br72ee<kZet
+HV'UH?>J,-'On>mCL5-6CD_9;UciYnef4ZE^"-s)f$48[cC=m[el#,R]fA+(CE^+!LcpCiecW<P
+J*Qp^!m+barRM$c<k\LX!jt$drmhB)CY"FEcITZ/cM?#l!3Q1E!7Lkt!jtX9J_&u7#/!;,!<<Fa
+J_'bM!lZEfrmh-b"i>iAJ_%<]!L-3,~>
+ZMss^s8:aO!$X/2hVJ7&hVQf`^#%VZ>'kU"^#%>>Z.`u+f&"hbB?k-ZZ2WG]en7IWf&#!Oh?'2I
+s8:aO!"(Hoc/*AFc/*AFc2QQ$c!G>fh?1GdJ+!9l!,qc8"#7LGhY[?[0tlH#!577G!58?f!PJL3
+h?1GdJ+!<m"4C[pgA9Y+DuBY?(jF6]h>k7fh>t:irS@UG!<;uRqZ%A5hT]AFhJZ0&hVN0Wc/*A:
+_;<FCDuJN-en7IWg>:E;ec="PhSoQ@(nBI>c@l/Q!h98jr8.;N'ir;u?>n\=:;,N@DdL]FDc4F.
+c!G>chAcNlhVPpGhTc+[f&#!7ec="PhSoQ@(nBI>eu>qRh?1GdJ+!3j!mP%irS@NmqZ%*3[GKcR
+!577?!0#dS!7pu&qZ$XKSGq@H]hWKshW3MsX<n2Q'\Iunr8%\$,[fKcC]IIdhLXOmh>s-AJ,~>
+ZMss[s8:XL!$X,.gY2_"gY:0W]%buN=a>9q]%bW0Yh*T#e(`)RB?t9^Y5[#WeS.OVe(`@FgB*fD
+s8:XL!"(Ekb1gc?bhHuAbl6>uaB```gB5#]J*m3h!,_W6"#.=@g\_$X0Y6#n!5@4B!5AEd!O`.0
+gB5#]J*m6i"4(CifD=5%D>aG=(j4!UgAntdgB#"grS%CB!<;uOqu@K8Y1q0-D;/o']\D1X?d.8A
+;81f-?#BPp("I"gY1MFWgX?/GgY9FBcPW,*gW,'IgB*fDs8:XL!#>W=`6;S*gMKa!gY6RPbhHu3
+^>$e9D>W'-!2A6&\cCL2"H([_e(`=ObM1dc!7)LNgY:,QYl<AZ\kR\AqqD1r?Z#br!,_T5%LBAp
+gU7*ngWp"[gVX$?q:kcH!A']=gB+r\D1UI&gBFT'#QPOgJ_U+W#KS/tgY6KD<.WeTgUGo<RSA;~>
+ZMssVs8:IG!$Wl"f%'hkf%/+H[FWp:;KI%_[FWX"XjUilcIU*DA&`"JXo?`Qc=9>GcIU;7ecM'9
+s8:IG!"(0_`R\g2ajt66ao9im`EI'VecW<PJ*R!`!,MK4""CY/f),LS.CIaX!56t7!58?^!OVq+
+ecW<PJ*R$a"3Fk^de_MpC]+5;'Q:tAec<D^ecEGarRM%7!<;uJqZ%A5f#_66en\$kf%+VCajt6&
+\^n`'C]2g!c=9>Gdal^pc2bl8f"D('(mNV&`e=<A!gE]br7:`F'ir/m?>J,-::\s,CL5-6CJMFk
+`EI'Sef4[[f%.5/f#@]KcIU:lc2bl8f"D('(mNV&cD@ZBecW<PJ*Qp^!m+barRLsaqZ%*3Xk)(2
+!4CD'!//q:!7(DkqZ$XGPlB58[7Y4cf&YBcVBcEI'@;<]r72+j,@/mOBE1q]eq)D]ecD"-J,~>
+ZMss^s8:^S!586c"TZ6mhSoQph?D/1Df8t,rS@S'A,H<:?Hp<-.3N69hSF7^&2B^Kh?'2Is8:^S
+!586c#&dhmhJZ`Frn[^e>(?P."2.HZmetuDDdL]bh>mViqVDAU^#%TG^&?dgPTg"^"2.HZmetuD
+F'?Q^h?M\`CW13uc2-8t!58?f!PJL3h?'2Is8:^S!58Bg(4-VLc!G>FDdL]FhJZ`FhJZ`FhT]AF
+r8%[pF"&4dSDM9_!!9h6^%pLdS,iTehAZH$c/.<Y7<d!_Dr,D=c/.;q?Hq>F?Hq?O?>o_t%KO3!
+hRrpGhPEOM0q@+?qZ$]2!583b"2.HZmebiBc!G>eh?%V%c2QQ'elj6RhJ<#h"?G>q#d+'^"kG-)
+h>k7ah?(AcDh6d*h?;Yp&HI-.hYZ.7aWY3OCB+ROJ_kt7\D@7V:4N~>
+ZMss[s8:UP!5A<a"TZ-ggVX$jgBG`*D/ES$rS%A!@Jg*8?-9m$-m3*4gV.YU&29RHgB*fDs8:UP
+!5A<a#&R_kgML<Arn@La>CHM*"1h3VmJYc@D-tN`gAq;gqV)/R^>%BB^AZdeQ6?.\"1h3VmJbiB
+fl(*5rn@Y/Iqc]8?d/B$!<B_0gB"kcrS%CB!<;uO)Z[V,gXgQZf?.H;gML6=gY6RPbhHu?b1k-I
+D>`,n^2YPD0Ugb6qZ$]/!4r!\!h',hr7`.j?d.9XVF#@H?Z"P7?-:pVD-tNAD-b<=b[55agC=4p
+gY9FBgY8Gg&29R-_tsE8\cB>;gB5#]J*m-f!mG"grS%Bj?d/N("j^<ogY6H?!!G:9f*JPXgBH%W
+VV;*bptGk]9l5I9j4a^jN"H&8J_U(V#K@orgM$Wl\UiLdgUPu=RSA;~>
+ZMssVs8:FK!586["TYs]f"D(_ecj#rCMR+mrRM"k?Mjd5>/e$j.3N*-f"#]J&2BFCecM'9s8:FK
+!586[#&@Peen\U6rmh.Y<d4Po"1:aNlM]98CL5-Zec>caqUPfM^"1a7^&?L_PSjAM"1:aNlM]98
+Dd(!VecsQLB>&(eanjQh!4DdV!OVq+ecM'9s8:FK!58B_(3:&<a^/c6CKe^.en\U6en\I.f#_66
+r72+`D^ce`Ph*PF!!9P.[JAATPQ:a]ef+Tqak#%=6$(.SCY!9)`R`UU?HLc6>/f(7?>KGh%KNof
+f"D(7eso&<0pL8&qZ$]*!4DXR"1:aNlMK-6a^/c]ecKVnao9ipc<;CBemnUX"?G&a#d+'V"jSQn
+ec<DYecN6OCOt'secaN[&--m)f)+#'_'!.:B)i+CJ_#D'\CL\F8q6~>
+ZMss^s8:^S!586c.0.'<hUV\?hVPqHGB[*$hU\'eg1tKXhV,rjg;1bb]hW4g_8Y9fS,gk/h?'2I
+s8:^S!586c#&dhmhJZ`Frn[^7:8%UC"2.HZmetuDDdL]bh>mViqVDAU^#%TG^&?dg3Fi$E"2.HZ
+metuDPY.2>h?LAWB@_!-c2-8t&>f?^!Ls`"h?'2Is8:^S!58Bg(=iK*_-V':DdL]FhJZ`FhJZ`F
+hT]AFrSA:C_8Y9ES,gjc!7p#`f!X?GSDN,JA,Y6cS,iTehAZH$c/.=2CLb1eDr,D=c/.;q?Hq>F
+?Hq?O?>o_t*!!\/hRrpGeudfcS,gjc!7p#`f!X?GSDN,RR%XH8"2.HZmebiBc!G>eh?%V%c2HK&
+]`?pG(i0-%"cNH,hF^E=h?Ai<cJAQ7ptc(c:2b^?iSF[eC`1TNhYZ.6`uo&1!!>B8hLXOnh>s-A
+J,~>
+ZMss[s8:UP!5A<a.0.*:gX?/6gY9;@GB[3&gX21Sf4emJgXj<^f=o,V\kQb^^;AXZRK1P*gB*fD
+s8:UP!5A<a#&R_kgML<Arn@L49Uu+:"1h3VmJYc@D-tN`gAq;gqV)/R^>%BB^AZde4C.p?"1h3V
+mJYc@PYIDAgBP#TA^bL'bkg&p&>K-X!La`$gB*fDs8:UP!5AHe(=N9$^gCs5D-tNAgML<AgML<A
+gWX#ArS&(=^;AX9RK1O[!70ESe$@^BT%i#??2`LZRK3BcgD^-"bhLn(BjneaD;/o7bhLlh?d.8A
+?d.9K?Z#\p*!!_-gV*[Be#M0WRK1O[!70ESe$@^BT%i#IP+;O+"1h3VmJGW>b[55cgB)5!bl-9"
+[K,(:(iB9$"c<<#gJ(E@gBET;bM*$2ptGk]9l5I9iS+I_CDb?Jg\]_0`#iW*!!>?7gO\+hgB!a;
+J,~>
+ZMssVs8:FK!586[.0.'4f$49'f%.B4F)tBmf$9AEdV!4@f$_7Jd^d'B[7XrO\\6SFPQ8_tecM'9
+s8:FK!586[#&@Peen\U6rmh.+8XTM."1:aNlM]98CL5-Zec>caqUPfM^"1a7^&?L_3ElC4"1:aN
+lM]98O@kW6ecrBKA'SjranjQh&=i^M!L+/oecM'9s8:FK!58B_(<uon]j>L*CL5-6en\U6en\U6
+f#_66rRM_3\\6S%PQ8_K!7'0HcE5Y/SCZ92>5d"RPQ:a]ef+Tqak#%kB3r8XCY!9-ak#$Y?HLc6
+?HLd??>KGh*!!\'f"D(7cDB+CPQ8_K!7'0HcE5Y/SCZ9:OI6$u"1:aNlMK-6a^/c]ecKVnao0co
+[/ee/(i0,r"bZlqek/R5ech!4`mt.'psoMS8o'"/iRS+UBGejBf)+#&^`R*!!!><6eq)D^ecD"-
+J,~>
+ZMss^s8:^S!586c!<Bh4hZ#nd`k?F_TVP2$`Jcs8hNUWgb)eoEg2C$*[7Y5cDcXR&PQ9;/h?'2I
+s8:^S!586c$u]IshJZH.b.W9VDq=pE"2.HZmetuDDdL]bh>mViqVDS[^#%TGXj4qo8eB;Hh?1Gd
+J+!9l%+8oGK>"6V25&fE?Hr?'#BL`H`l<rKHi;e&S,iTehAZHscHaF>&DkZ<Dr,D=c/.;q>05W>
+?Hq?O?>of!(#!S,]sX()f%s"k`m.I:hJ4RRc:Thih?'2Is8:^m!*6eYb*4o1c!G>FDdL]FhJZT>
+hJZ`FhT]AFqq`:m^#%VZ!8c94V:Lk2f%s"k`m.I:hJ4RR`Jcs8rn[aj:4M^/h?(r.DuJMoDdL]e
+h?CRmhQ6dtrn\1:#^bFJ&5opUN!NqMh>j\Uc2cGph?(AcDh6d&h>t['J_p7[#/qW=!!!5'J_kt7
+\_[@W:4N~>
+ZMss[s8:UP!5A<a!<Bk5gE]3M_n'hWTV+bo_Mg[4gQG3c`Jd-=eSA0rZ:eoXCK7spOp',*gB*fD
+s8:UP!5A<a$uK@qgMKs#a1?[OCXN.9"1h3VmJYc@D-tN`gAq;gqV)AX^>%BBWlN/_9b>ADgB5#]
+J*m3h%*rWAJ%2FO1n<<;?d/B$#Ak<<_nM!BFoC%rRK3BcgD^-ma2c)/'\gi=D;/o7bhLlh>KGQ9
+?d.9K?Z#br("I)"]!@J%ceD#c_oGV2gLVeEb=s\hgB*fDs8:Uj!*-PL`KWK/b[55AD-tNAgML09
+gML<AgWX#AqqE(j^>%DV!8Gg*U=58.ceD#c_oGV2gLVeE_Mg[4rn@Od9n2R-gB,T+D>i2jD-tNc
+gBG:kgSOtbrn@t4#^tIF&5fUJNXT4JgAn8O`rONdgB+r\D1UI!gB#6sJ_U%U#/VE:!!!5%J_Pb1
+\_@.R9n3~>
+ZMssVs8:FK!586[!<Bh4eg*RB]sVcJS=E&e]neh(er3(N_2(7,dVDagX[ZsKCJqRcMu_/tecM'9
+s8:FK!586[$u91ken\0k`jpFJCX2q1"1:aNlM]98CL5-Zec>caqUQ#S^"1a7V8gNW8eB#@ecW<P
+J*R!`%*<*5HaTYA0ppO-?HN&p#AY08]tK@9F8aYkPQ:a]ef+Uc`l>]%&D"s0CY!9-ak#$Y>/f'.
+?HLd??>KMj("-kq[B5AfcIP<S]uEZ!emg/:`_%uaecM'9s8:Fe!)g5E_2pZua^/c6CL5-6en\I.
+en\U6f#_66qpl_e^"1cJ!7oF$SBd&ncIP<S]uEZ!emg/:]neh(rmh1Z8q6.'ecNs"C]2fcCL5-]
+eci_eetiA[rmhV*#^b.9&5'(<N!NV<ec;QE`W4<`ecN6OCOt'oecERfJ_'\K#/2*4!!!5!J_#D'
+\^geG8q6~>
+ZMss^s8:^S!586c!<Bh4hBU<<#RE/Pg>8J_#TS?BhV+&?#UP/PhR-)a$s'pq[8$u-(mOaN!h98j
+r8%GS^&$RgDdL]FDuK_="=8QBrS@Xi:4M^1h?%V%c2-8t!586c!s$$khYdEU#XZ6&h?1GdJ+!6k
+$dF/I":R_thVN0Wc2$3"KIHm$.?+2]!h98jr8.>O(+HBBc!G>FDdL]FhMW@K]l.6%hT]AFr8&-q
+:'_7FPht9J8dG\h`noQ^&-+`1rS@UG!<;uRqu@KHCW4P)Dr,D=c/.<8*)=1c?Hq?O?>o_t*!!\/
+hRrpGhM`!G(mNn6ek-2R6H7m=@h8ncJ(">Q"2.HZmebiBc!G>eh?%V%c2HK%c2c^)1&Tl78ho2Z
+]g;u)(j#]5q>^_8g>:]":2b^?J_o/<#F[:b)BBn?!r`0"."U6+hRVJDS5+S~>
+ZMss[s8:UP!5A<a!<Bk5gEXm1#RiJUg"DfN#TeE?gXV<6#UG)NgTXBZ%Tg*nYY>H)*0U$M!h',h
+r7_5P^A?ReD-tNAD>jM;"=A]DrS%Fc9n2R/gB)5!bkg&p!5A<a!s$'ig\h*R#XuK*gB5#]J*m0g
+$d=/M"qF,"gY6RPbk]usJg^a)/;jA[!h',hr7h,L(+???b[55AD-tNAgPHtI\ntfugWX#Ar7_pi
+9aV@MP2"a;9aD"ja4o3O$j8Q-rS%CB!<;uOqu@KHCW+G(D;/o7bhLm/*`'@a?d.9K?Z#\p*!!_-
+gV*[BgP-CB*0T(2cV4ZN6-%a3>mpu[IF%oI"1h3VmJGW>b[55cgB)5!bl-9!cN)^&0`9Z39eb>V
+^-rG1*-(u4q>^_6fA#&k9l5I9J_Sr6#FI+_)BBk>!r`0"."U-(gUZ&>RSA;~>
+ZMssVs8:FK!586[!<Bh4eg&1$#RE/Ldajd?"<;d1f$]L+#UOuBeu_OM$rX@]X\&j!(l\1>!gE]b
+r71lK^&$:_CL5-6C]4;9"=8Q>rRM(Y8q6.)ecKVnanjQh!586[!s$$cf)5RM#XZ6&ecW<PJ*Qs_
+$d!lE":RShf%+VCanaKkHQ`@h.>7WM!gE]br7:cG(+HB:a^/c6CL5-6eq4f3[;0*jf#_66r72Ra
+8dGhBN7QS*8dG\h^"1b<#QQlurRM%7!<;uJqu@KHCVe,!CY!9-ak#$q(eV2O?HLd??>KGh*!!\'
+f"D(7eq=S7(l[%sc:S?J6G:t$=pP6NHcc9<"1:aNlMK-6a^/c]ecKVnao0cn`W4Rf1&TT/8h&?B
+]g;u)(i0-%q>^_4dam!W8o'"/J_&T,#F-kZ)B9e<!r`0"-\9j"f"'?4PY-H~>
+ZMss^s8:^SDpA.8!H66^hBUU9F*!,Kgtof(F+(4DhV>SmF+LUKhT;()FdgM1ad.!dHb&k,!h98j
+r8%Hmc2-9"VOl>pVZ(K9EIk:CrS@Xi:4M^1h?'RGeb\,'DpA.8")lH@hYh?oF-+ZEh?1GdJ+!6k
+$e;D2EHRD]hVP-$ebS&*Z%Ht5K=1X6!h98jr8.?i(5'T_eXiYpVOl>phR%]sc).)_hUS3pr8&.0
+Q?.1q\_c2sP]Lo-db`iRGAiDfrS@UG!<;uRr,3?rUs[_aVV\2Ae_]/iI?r-TT%2]JSu2DA*,j*Y
+hT]uqhR.QGHb&"ig6?Z"OOE"BTQbI*Y1Wa1"2.HZmebiBeXiZ:h?'RGec">-eo0E8L]$!8P_\,P
+c&d!bH`6r#qJQS6gtpo$:2b^?J_o,;"3OOB!W)it#aU%uJ_mup!Luo8~>
+ZMss[s8:UPD9Vk2!H$'[gEY1/EH?lFg=j,nEI=k<gXrlbEIY1CgVoCtFIC5)`KYC[Ha`Y&!h',h
+r7_6hbkg&sUn,uhV#G35Dh,">rS%Fc9n2R/gB+1Ae,%f"D9Vk2")Z9:g\ksjEKJEBgB5#]J*m0g
+$e)80E-.2WgY8Npe+q`%Y(:M0K<kF0!h',hr7h-d(4jEYe"*;hUn,uhgTl3lb+tTWgXD^hr7_q)
+P]Ckm[bKQeP]:]'dG*?EF)Qo]rS%CB!<;uOr,!3nUX.D[Ut_]9e(`W_I$MjMS^Z?BSYZ/;*,WpS
+gWXNhgTYm=Ha_\`eWb&nNmZV7S9&[tXO[=)"1h3VmJGW>e"*<5gB+1Ae,A#(eSX'0L&B[3P_IlH
+b`Hm_H`$esqJ?G2g"Y8m9l5I9J_So5"3=@?!W)it#aBnpJ_Rcj!Lc`5~>
+ZMssVs8:FKCWZG(!GfgVeg&J!Df:99eCM*]D0`)+f$psSDgeY3f"mGdEKnAl_2rSNGHpkm!gE]b
+r71maanjQkTUO3XT`/^/D1/G1rRM(Y8q6.)ecMM5chc2nCWZG(")H$0f)9@cDiDg9ecW<PJ*Qs_
+$dYi$D/kKGf%-L_chZ,qW-`;qJ$&Y"!gE]br7:d](4X0Oc^LNXTUO3XeuX(W`Lr[Gf$BeXr72Ru
+ODf,_Z.@LSODf&rak#%1Dek-MrRM%7!<;uJr+d'jTZbZMT[od)cdp[KGEBe:Ra9R2R\9Q/*,E[I
+f#_^Yeua"/GHo`MdZABcN60Z%Qu?heW6bIo"1:aNlMK-6c^LO*ecMM5ci)Dtc>2!qKDa:,OFPj4
+ac(.RGG+rdqJ-;,eCN3Y8o'"/J_&Q+"2dq8!W)it#a'\hJ_%E`!L-3,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?J_o&9!k'lj
+qZ$X6g4A+3hRhVFS5+S~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9J_Si3!jj]g
+qZ$X6f7D\-gUl2@RSA;~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/J_&K)!jFBb
+qZ$X5dXfu#f"9K6PY-H~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?J_nu7!h'u5
+r;Zj)J:ZR.hRhVFS5+S~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9J_Sc1!gjf2
+r;Zj)It?@*gUl2@RSA;~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/J_&E'!gOT/
+r;Zj)I"Bk"f"9K6PY-H~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?J_nr6"5/&.
+#Q=](%F]mbJ_n&r!Luo8~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9J_S`0"4hc)
+#Q=](%+'R[J_Ril!Lc`5~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/J_&B&"4;?"
+#Q=](%*O4QJ_%Kb!L-3,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?J_nl4#0pBU
+!rrUBJ_kt7]\W[Z:4N~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9J_SZ.#0U-Q
+!rrU@J_Pb1]\<IU9n3~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/J_&<$#0'^J
+!rrU>J_#D'][d+J8q6~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?J_nf2"hQc!
+!!^PrhLXOsh>s-AJ,~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9J_ST,"h6Mr
+!!^GogO\+mgB!a;J,~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/J_&6""gg2m
+!!U2ieq)DcecD"-J,~>
+ZMss^s1dClS,iTLh?1GdJ*u%I"2.HZmbQ_$S,iT+h?'2Is17%h]hX(FbME<6:2b^?J_n`0"/-b9
+;h<eVhS%bHS5+S~>
+ZMss[s1d:iRK3BJgB5#]J*ktE"1h3VmG6LuRK3B)gB*fDs16qe\kR\AbM**09l5I9J_SN*".gP6
+;M!SRgV)>BRSA;~>
+ZMssVs1d+dPQ:aDecW<PJ*Pb="1:aNlJ:"mPQ:a#ecM'9s16b`[7Yr6bLQa&8o'"/J_&/u".L;2
+:k@2Kf"KW8PY-H~>
+ZMss^s1c5KS,iTL]`Y?2J)8nm"0>7IhVGjHS,iT+]`O](s15lGXA49%bImtY:2b^?J_n]/"5AGB
+]7JgihS.hIS5+S~>
+ZMss[s1c,HRK3BJ\c\s,J)&bh"0,(FgtfOCRK3B)\cS<#s15cDW_IuubIRbT9l5I9J_SK)"5&/=
+\:NCcgV2DCRSA;~>
+ZMssVs1brCPQ:aD[0*3sJ(iVa"/JP=g>0.<PQ:a#[/uQms15T?Ue6-jbI%DI8o'"/J_&,t"4M]5
+["6eZf"T]9PY-H~>
+ZMss^J%eYY!.X!'![g3EfhMSr5A&\G!<@Vc:&t?E\P<2R5A&&5!@Mf:hLXP-h>u$&J_kt7^>8m\
+:4N~>
+ZMss[J%eVX!.X!&![^-DfhDMp5A&\F!<@Vc9`Y6D\P3,P5A&&4!@DZ7gO\,'gB#TsJ_Pb1^=r[W
+9n3~>
+ZMssVJ%eMU!.X!#![U'Afh);l5@iPA!<@Vc8c\pA\OloL5@ho/!@;N4eq)DrecEpfJ_#D'^=E=L
+8q6~>
+ZMsp]JU`6#Jq!d'J_kt7J_kt7LY`'%:4N~>
+ZMspZJU`6#Jq!d&J_Pb1J_Pb1LYDiu9n3~>
+ZMspUJU`6#Jq!d#J_#D'J_#D'LXlKj8q6~>
+ZMsp]JcC<$K)Yi=rS@P!J\?WJJ\?WJS\5$[o!&8YS5+S~>
+ZMspZJcC<$K)Yi<rS%=pJ\$EDJ\$EDS[ngUnu`&SRSA;~>
+ZMspUJcC<$K)Yi9rRLtfJ[L':J[L':S[AIKntZ?DPY-H~>
+ZMsp]JcC<$K)Yi=rS@RgFb*;=:4Z/k:7k8_c/+-G_#m$mS5+S~>
+ZMspZJcC<$K)Yi<rS%@aF+I&:9n?#i9qP,]bhIaA^]QmgRSA;~>
+ZMspUJcC<$K)Yi9rRM"WDh1N38qBTc8tS]WajtP*\H=kTPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMDu\[Is7Yj`blI4&:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMD?&@Bs7Yg_bQ-st9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMC]Dt,s7Y^\aT1Lg8q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs8:^RDuAGpS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s8:UOD>`,kRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs8:FJC])`dPQ9m28q6~>
+ZMsp]_uBc*It@WNs2+d9metuC]hX+YJH4'ts$)&7JH4*u"Q'18K`D#-!cJ'WrS@[I!:QFQJ,~>
+ZMspZ_uBc)It@WNs2+d9mJYc?\kR_UJH4'ts$)&7JH4*u"P`t2K)bf(!c7pSrS%ID!:-(JJ,~>
+ZMspU_uBc*It@WNs2+d9lM]97[7YuMJH4'ts$)&7JH4*u"P3V(F8u3i!c%dOrRM+9!9]S=J,~>
+ZMsp]_uBbo!;HKrqltd/\`NhprRREkLUl4?"o[#@KqR5Yrri5(K87"Urrr;)RY@Ei^&J97es_;c
+gsZ3&metuC]hX+YJH16$JH2>C"Q'18K`D&.!,qi:!,qkn"IoJ\S5+S~>
+ZMspZ_uBbl!;HKrqlk^.]&iqqrRI<iLUu:@"oZu>KqR5Yrri5'K87%Vrrr;(R>%<h^&J97eX;,a
+gsZ3&mJYc?\kR_UJH16$JH2>C"P`t2K)bi)!,_]8!,__i"I]>VRSA;~>
+ZMspU_uBbo!;HKrqltd/\`NhprRREkLUl4?"o[#@KqR5Yrri5(K87"Urrr;)RY@Ei^&J97es_;c
+gsZ3&lM]97[7YuMJH16$JH2>C"P3V(F8u6j!,MQ6!,MSb"I&oLPY-H~>
+ZMsp]_uBbo!;HKsYtB(U9$-5q#2"?1EGnIkh>[]3I9pnuM<*Up"gL[@DbA-jrs#`#??'5,jM(Wu
+fR7(G>`%OjrrDKch>t;bJH16$d/a22JH16$dJsO/s5&G/hVN2K!!dH!hOFT7S5+S~>
+ZMspZ_uBbl!;HKsZ:]+T9$6;r#2"B2E,S@kh>[]3IU6u!MWE^q"gUa?DbA0krs#c$?>s2-jM(Wu
+fR@.G?&I^lrrDHbgB"l[JH16$d/a22JH16$dJsO,s4`/*gY6TC!!dAqgR8-.RSA;~>
+ZMspU_uBbo!;HKsYtB(U9$-5q#2"?1EGnIkh>[]3I9pnuM<*Up"gL[@DbA-jrs#`#??'5,jM(Wu
+fR7(G>`%OjrrD?_ecE0NJH16$d/a22JH16$dJsO's428kf%+X7!!d;jes$0tPY-H~>
+ZMsp]rVlodJ,]I+mXP9:J(C!:OOjI3J(C!FLU6:GkconsW8djW^SIl`SAD.XT%sAGrRRKmK;ePE
+s1sVCPdpegrrkQ0mcI\^k5PXW>-dGU>%6=f#+f#(lC_Ifi;WsDGOFTs@`A?O4a43sTO+k:rs#&u
+ZKe)hYg`UPmetuC]hX+YJH4'ts$)&7JH4*u#2]C:K`BocqJZDj"IoJ\S5+S~>
+ZMspZrVlocJ,]I+m=509J(C$=O4=40J(C$ILpH:FkHK_qW8[dV^SIocS\hC]S_O2ErRRKmK<"\G
+s2'bFPI:JcrrkT3mH7\bk5PXW>I3VX>@lXj#+f&*lChUki;WsEH0sd!A]=ZR5'aL"TjY1?rs#'!
+Zg+5lZIAgRmJYc?\kR_UJH4'ts$)&7JH4*u#2B14K)aT[qJH8e"I]>VRSA;~>
+ZMspUrVlodJ,]I+mXP9:J(C!:OOjI3J(C!FLU6:GkconsW8djW^SIl`SAD.XT%sAGrRRKmK;ePE
+s1sVCPdpegrrkQ0mcI\^k5PXW>-dGU>%6=f#+f#(lC_Ifi;WsDGOFTs@`A?O4a43sTO+k:rs#&u
+ZKe)hYg`UPlM]97[7YuMJH4'ts$)&7JH4*u#1ih*F8shBqJ6,^"I&oLPY-H~>
+ZMsp]rVloT!<3!Vh>mTU!-a3J:1!u#!-a3NAlc)3UeYB?=J#EiIli."8m$L]9U>MSdt):YF&&8*
+_+nTdF&i;9rs&'#gAh2X*9[>,q0d8Ls8T>DhZ!iVI<"WRfOg-%rs&'#gAh2X*6/!`o*F(:s4CqC
+^]+Q7I<"WRfOg,lrrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+ZMspZrVloQ!<3!VgAq9R!-a9L:0mo"!-a9QB2u,3UeP<<=.T3fIli1%93H^a99o>Qe:VO[F&/>+
+_G=liF&rA:rs&'#f`1uU+Qrb0q0d5Js8T;GhZ!iVI;nNPf4^6(rs&'#f`1uU+NFEdo*F"7s4:qF
+^]+Q7I;nNPf4^5orrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+ZMspUrVloT!<3!Vh>mTU!-a3J:1!u#!-a3NAlc)3UeYB?=J#EiIli."8m$L]9U>MSdt):YF&&8*
+_+nTdF&i;9rs&'#gAh2X*9[>,q0d8Ls8T>DhZ!iVI<"WRfOg-%rs&'#gAh2X*6/!`o*F(:s4CqC
+^]+Q7I<"WRfOg,lrrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!Vh>mTU!.XG:X9ek+!.XG1eQRV&Z&mVtA97>AIn[uLD+r(:D/o(DP\/&,mZ]$l
+:0uZKhI6K[rs%H_qu?]I"R#din8WmTs8UXQhZ!iMEIIfcl>;+2rs%H_qu?]I"NLHHiW/lSs6=HP
+^]+Q.EIIfcl>;+$rrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQJ,~>
+ZMspZrVloQ!<3!VgAq9R!.XJ9X9ek+!.XJ2e67M$Y`RJo@r_&=In[uLD+ht8D/f"CQ"\8.n!#*l
+;.&&OhI?Q\rs%K`q>^KD#3Z!knSrsSs8UOPhZ!iNEI@]al"kt1rs%K`q>^KD#0-ZJirJoQs64?O
+^]+Q/EI@]al"kt#rrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(JJ,~>
+ZMspUrVloT!<3!Vh>mTU!.XG:X9ek+!.XG1eQRV&Z&mVtA97>AIn[uLD+r(:D/o(DP\/&,mZ]$l
+:0uZKhI6K[rs%H_qu?]I"R#din8WmTs8UXQhZ!iMEIIfcl>;+2rs%H_qu?]I"NLHHiW/lSs6=HP
+^]+Q.EIIfcl>;+$rrD?_ecE0NJH16$d/a22JH16$dJsF$s428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!Qh>mTU!6tQDh>mTU!6tQDmVdUTi2W*/8oO.tIr4QPIr4QPIrFcIFZXr"Ir>>H%
+))Z?!Pnd2rs%Tcqu?]I"R#dinoK6Xs8UXQhZ!iOF++#el>;+2rs%Tcqu?]I"NLHHjoG;Ws6=HP^
+]+Q0F++#el>;+$rrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQJ,~>
+ZMspZrVloQ!<3!QgAq9R!6kKCgAq9R!6kKCm;7@PhQ)s-8o<tqIr"BMIr"BMIr4TGFut#"Ir>>I%
+_hrB!Pe^1rs%Qbq>^KF#3Z!knoB-Us8UURhZ!iOEd[fbl>;.3rs%Qbq>^KF#0-ZJjT,,Ss6=HQ^
+]+Q0Ed[fbl>;.%rrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(JJ,~>
+ZMspUrVloT!<3!Qh>mTU!6tQDh>mTU!6tQDmVdUTi2W*/8oO.tIr4QPIr4QPIrFcIFZXr"Ir>>H%
+))Z?!Pnd2rs%Tcqu?]I"R#dinoK6Xs8UXQhZ!iOF++#el>;+2rs%Tcqu?]I"NLHHjoG;Ws6=HP^
+]+Q0F++#el>;+$rrD?_ecE0NJH16$d/a22JH16$dJsF$s428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!QblIeD!8dbUh>mTU!8dbUmVdUPVJD*_<,_4)IrFcTIrFcTIrFcIFZk/&IsYhn%
+)MrC!Pnd2rs&3'hZ*V`*9[>,qgW\Ts8TJHhZ!iXIrk&Xg1ZK)rs&3'hZ*V`*6/!`pB]XDs4V.G^
+]+Q9Irk&Xg1ZJprrDKch?(Ac*.^,$3Is2A3MAG9hZ)Gcs7X,/S,i#J:4N~>
+ZMspZrVloQ!<3!QbQ.\C!8IPRgAq9R!8IPRm;7@MVe_3`<Gh.'Ir4TQIr4TQIr4TFF?Fr#IsYho%
+`&)D!Pe^1rs&-'g].;^+Qrb0qL<PQs8TMMhZ!iWIrarVg1uc.rs&-'g].;^+NFEdoa9I@s4V7L^
+]+Q8IrarVg1uburrDHbgB+r\*J$8&3e9>C3h\S;g]-#[s7X#,RK2ZB9n3~>
+ZMspUrVloT!<3!QblIeD!8dbUh>mTU!8dbUmVdUPVJD*_<,_4)IrFcTIrFcTIrFcIFZk/&IsYhn%
+)MrC!Pnd2rs&3'hZ*V`*9[>,qgW\Ts8TJHhZ!iXIrk&Xg1ZK)rs&3'hZ*V`*6/!`pB]XDs4V.G^
+]+Q9Irk&Xg1ZJprrD?_ecE0NJH16$JH16$TE#,Gs428kp9b$f!9]S=J,~>
+ZMsp]rVntA!7Lo8HN=*G!8dbUh>mTU!8dbUmVdULGA$'r?u>91IrFcTIrFcTIrFcRP%`,3o;I<A
+:1DrOhIci_rrk]Aqt"9+k5PXY@__[/@Ue0n#,#G?pSq],i;WsHK_t@M@`A?O6%m#IWa`3Hrs#-*
+^\=a;Yg`UPmetuD]hUS=F+JD\F8qPWF+JD\Es1A"hLpCO:'1LbS5+S~>
+ZMspZrVnt>!7:c7HN=*G!8IPRgAq9R!8IPRm;7@HGA$$p@;G3/Ir4TQIr4TQIr4TNO_Dr/o;[NE
+;.82QhIQ]]rrkfBq=A*-k5PXZA%hU-@qFKr#,,P?p8_`0i;WsKK),"JA]=ZR7"W,GX(8NMrs#0,
+^%SL;ZIAgRmJYc@\kP5:Fb+\`FoReZFb+\`FTgJ!gOaqJ9`kC]RSA;~>
+ZMspUrVntA!7Lo8HN=*G!8dbUh>mTU!8dbUmVdULGA$'r?u>91IrFcTIrFcTIrFcRP%`,3o;I<A
+:1DrOhIci_rrk]Aqt"9+k5PXY@__[/@Ue0n#,#G?pSq],i;WsHK_t@M@`A?O6%m#IWa`3Hrs#-*
+^\=a;Yg`UPlM]97[7YuMJH4'ts$)&7JH4*u"P3V(F+<jT!s%MK8q6~>
+ZMsp]rVntR7Tt:sErc7?!8dbUh>mTU!8dbUmVdUPRT+Qf<(OLuIrFcTIrFcTIrFcTc[BJNG>aP&
+_+nTdG@LXIrrof.Is4Z0k5PY>K5#[V:<D>l#24]DHX_ooi;Wtg;L`mcai48a[8L^c@Z0<]rs%20
+BmX<IjO=,/metuD]hTPu3Is3=3WE?83Is3=3<S.<hLtNN!s%e[:4N~>
+ZMspZrVntP7pCP$E<-%=!8IPRgAq9R!8IPRm;7@LR8nNg<_9e#Ir4TQIr4TQIr4TQd!]SOG?'e*
+_G+ZeG@LXIrroi.IsFf3k5PY>K4oXX:<MDm#24]CHt82si;Wth;1Ejdb/OAb[S^^cA;oT`rs%20
+BRF?LjO=,/mJYc@\kO2r3e9??3r`K:3e9??3Wn.:gOf'I!s%YU9n3~>
+ZMspUrVntR7Tt:sErc7?!8dbUh>mTU!8dbUmVdUPRT+Qf<(OLuIrFcTIrFcTIrFcTc[BJNG>aP&
+_+nTdG@LXIrrof.Is4Z0k5PY>K5#[V:<D>l#24]DHX_ooi;Wtg;L`mcai48a[8L^c@Z0<]rs%20
+BmX<IjO=,/lM]97[7YuMJH4'ts$)&7JH4*u"4mM'F7aqa!9]S=J,~>
+ZMsp]r;SgsLOY]BJ,fOumf3=TJ,fOumf3=\\%ht"TS98LP/715\+]j:\+]j:\+]k!d?oQ=V"=Wd
+_2Ef1dXV#k"T,HVK=U+D"o[#@K7g_irrrAPRY.3ehu<iVZ%I\>`;^#<Z'p<:gqE^krRREiT%qco
+!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&mKCc7n!m.'~>
+ZMspZr;SgtM1M)EJ,fOumJm4RJ,fOumJm4[[_Mk!TSBDPPJ[@7[eBa9[eBa9[eBaud?oT>VXsif
+^l*]/dXV#k"T,EWKt?CG"oZu?Kn[+nrrrAORY@Bhhu<iVY_@eB`;^#<YaU9<gqE^krRI?jTA7lp
+!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!m0(W5l^COu~>
+ZMspUr;SgsLOY]BJ,fOumf3=TJ,fOumf3=\\%ht"TS98LP/715\+]j:\+]j:\+]k!d?oQ=V"=Wd
+_2Ef1dXV#k"T,HVK=U+D"o[#@K7g_irrrAPRY.3ehu<iVZ%I\>`;^#<Z'p<:gqE^krRREiT%qco
+!:'O6!OYON!.b-$!.b-C!!LmQeoUlbl3,3/kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]_uBbo!.k0$s2+d9metuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZ_uBbl!.k0$s2+d9mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspU_uBbo!.k0$s2+d9lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]_uBbo!;?F$KFeDep](9jXYgMQ\buI/ia[K3rrr;%2%1%;h#@QTXYgMQ\_mDipL=I?F2\(^
+pL?&h6+O]/"oGDZ$phGPrrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+ZMspZ_uBbl!;?F$JeSJjoDejfX>C>P]);R0iF.60rrr;$1^jq<h#@QTX>C>P]&3MjpL+==Fi=:`
+pL,le6Fsl1"oGAX$pqPRrrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+ZMspU_uBbo!;?F$KFeDep](9jXYgMQ\buI/ia[K3rrr;%2%1%;h#@QTXYgMQ\_mDipL=I?F2\(^
+pL?&h6+O]/"oGDZ$phGPrrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]_uBbo!;HL'N%roH6>QW$[8)M.G?W,frr_kB%"J!N#.73]f$5G'h>[\e:5@DE>05_&"`#jL
+c68Fkrs!6nLXpZQahIcZ[8)M.G?W,;rrDKch>t;bJH16$d/a2rJH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+ZMspZ_uBbl!;HL'N\K)F6#HZ%[SVb0G?`5hrr_kB%"J!N#.@?`e^#A(h>[\f:l!SF>KYn("`6*N
+cQJOmrs!<sLXgTQb.dl[[SVb0G?`5=rrDHbgB"l[JH16$d/a2rJH16$dJsF)s4`/*p=f_=!:-(J
+J,~>
+ZMspU_uBbo!;HL'N%roH6>QW$[8)M.G?W,frr_kB%"J!N#.73]f$5G'h>[\e:5@DE>05_&"`#jL
+c68Fkrs!6nLXpZQahIcZ[8)M.G?W,;rrD?_ecE0NJH16$d/a2rJH16$dJsF$s428kp=9A2!9]S=
+J,~>
+ZMsp]rVloT!<3!Vh>mTU!3IsU+g(eE!3Ism&80SodUNgs;T8\9InE`M3J13<4h:UmqlMje#ZC-k
+s+D3h.?ji,rsg3ls8V9%s8RjdhZ(],R/[*fTN3q"pAY>PB&<RfPVM"o#)?gIs2e`;i;Wrl^&S+s
+0ua.s&A?s#a^UXOrs"6jhZ(],R+)'8metuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZrVloQ!<3!VgAq9R!3S-]+KGJA!3S-u&nTSmcs[Io;8iM7In<]Q4G?cF4LkFkqlVsg#Z^?n
+s+VKn.$=T)rtQZos8V9&s8RjehZ(`0RK*<cSl[h"pAY>PBAW[gQ8IFt#)?jJs2no@i;Wrl^An5!
+1r]J!&AI$$b%7!Trs"6khZ(`0RFD09mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUrVloT!<3!Vh>mTU!3IsU+g(eE!3Ism&80SodUNgs;T8\9InE`M3J13<4h:UmqlMje#ZC-k
+s+D3h.?ji,rsg3ls8V9%s8RjdhZ(],R/[*fTN3q"pAY>PB&<RfPVM"o#)?gIs2e`;i;Wrl^&S+s
+0ua.s&A?s#a^UXOrs"6jhZ(],R+)'8lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]rVloT!<3!Vh>mTU!(,QBHP$5W!(,Q1]g[_NG<*(b??c/DIk@VM=tQ](>''<8XB(kNhF^E?
+KG_,c]bgbErtb&'N"?7mn,MQlHi*j*CP2Ze]k3XMJ+rsJo5f9Us8U@MhZ!iPF*mfak%fV.rs%Wd
+p](9=#fclLk5b8Rs5n*L^]+Q1F*mfak%fUurrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQ
+J,~>
+ZMspZrVloQ!<3!VgAq9R!(#N>I1ZGY!(#N0]LI\NG<3+^?$5i?IkIbP>:c`(>BBE9Y$%:RhapE>
+L)@Af^)R.Jrtb&'MA-=rn,MQlH27L%CPDfg]OdCGJ+rsJo5f3Qs8U7NhZ!iPF*[T]j_KS/rs%Wd
+oDej6%*&;Pk5b,Ls5e$M^]+Q1F*[T]j_KS!rrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(J
+J,~>
+ZMspUrVloT!<3!Vh>mTU!(,QBHP$5W!(,Q1]g[_NG<*(b??c/DIk@VM=tQ](>''<8XB(kNhF^E?
+KG_,c]bgbErtb&'N"?7mn,MQlHi*j*CP2Ze]k3XMJ+rsJo5f9Us8U@MhZ!iPF*mfak%fV.rs%Wd
+p](9=#fclLk5b8Rs5n*L^]+Q1F*mfak%fUurrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=
+J,~>
+ZMsp]rVloT!<3!Qh>mTU!58F4h>mTU!58F4mVdUTlK8!/CN&Y@Ir"?LIr"?LIrFcPH[#5as5!bE
+(o@63!Nc@srtaGk;Vp7s>6!GtJ,fQ:Dh%f@CQ.OsJ+rsEmVdUSrrLsVhZ!iKDh%femVdU6rrLsV
+rr3#U!65$>h>mQT!q'uV^]+Q,Dh%femVdU(rrDKch>t;bJH16$d/a2rJH16$dJsF,s5&G/p>,qB
+!:QFQJ,~>
+ZMspZrVloQ!<3!QgAq9R!5AL5gAq9R!5AL5m;7@Ol0%s.Bl38;Iqe0IIqe0IIr4TMI<YAas5*hF
+*2``8!NH.prtaJl<Su\"=o[AtJ,fQ9D1DT>D2[RoJ+rsEmr*^TrrLjShZ!iLDh%fem;7@3rrM!W
+rr3#R!65$>hZ3ZU!psiS^]+Q-Dh%fem;7@%rrDHbgB"l[JH16$d/a2rJH16$dJsF)s4`/*p=f_=
+!:-(JJ,~>
+ZMspUrVloT!<3!Qh>mTU!58F4h>mTU!58F4mVdUTlK8!/CN&Y@Ir"?LIr"?LIrFcPH[#5as5!bE
+(o@63!Nc@srtaGk;Vp7s>6!GtJ,fQ:Dh%f@CQ.OsJ+rsEmVdUSrrLsVhZ!iKDh%femVdU6rrLsV
+rr3#U!65$>h>mQT!q'uV^]+Q,Dh%femVdU(rrD?_ecE0NJH16$d/a2rJH16$dJsF$s428kp=9A2
+!9]S=J,~>
+ZMsp]rVloT!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9ec=;#
+rrL[Nq#;/n!:Tsfc3XI=GC05ek%fV@HY_L#CO>sRrs/:BHi*jCc3W;,#PWFhqu>eoKAlh7mf<+^
+s3:nirs.ump\Y!QCP0D%#PWFhqu>eoK@Bi#metuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZrVloQ!<3!HgAq9R!8IPRgAq9R!8IPRm;7@Qe8I*/.W+SQIr4TQIr4TQIr4TADu0M9f)XG%
+rrL^Oq#;2k!:Tsfb6\.6Fa<f_kA>qEI;@TtBmKIOq>U]mFa<f_s3D,1rs/4>H27L'D2$sK#3u9\
+s8UCR`r?;0!;$$dkA>pfrs/4>H27L'D2$I=!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspUrVloT!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9ec=;#
+rrL[Nq#;/n!:Tsfc3XI=GC05ek%fV@HY_L#CO>sRrs/:BHi*jCc3W;,#PWFhqu>eoKAlh7mf<+^
+s3:nirs.ump\Y!QCP0D%#PWFhqu>eoK@Bi#lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]rVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@rrt#J!s8U(Ms8Rjiir@88R,20I!!,R.q#:PRCZ>BoS2&k"#)@!Rs35/Ci;Wrl`rH(/
+0ua.s&B<`0c"<?Wrs"6oir@88R+)'8metuD]hU;5@tA-@@tA-`@g(ZghLtq&h?9>Kn!m.'~>
+ZMspZrVloQ!<3!Q^&\35!8IPRgAq9R!8IPRm;7@IH"Z7=Ir4TQIr4TQIr4TQIr4TKH$T5cs7ak>
+*30#<!NH.ort#V%s8U+Ns8RpkiW%2;RGM<K!!,U0q#:PTCZ5<nSi#:'#)R-Ss3>>Hi;Wrp_uKb.
+1r]J!'Z8o0c=r]\rs"<qiW%2;RFD09mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUrVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@rrt#J!s8U(Ms8Rjiir@88R,20I!!,R.q#:PRCZ>BoS2&k"#)@!Rs35/Ci;Wrl`rH(/
+0ua.s&B<`0c"<?Wrs"6oir@88R+)'8lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]rVntJ!2]_P3<9*Z!8dbUh>mTU!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrsiO2hVL8.s8TW5SF;8?ao25@mVdUKrs$#;SF>ViPhl?D\QYNlLgJ3]rrmI1pZEui
+`W$-`6CdM#?HKq]#.[p-mtb;le,KF9rS@Uh:,.<0JRd,<s07,bJRd,<"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZrVntF!2BMN2us!Y!8IPRgAq9R!8IPRm;7@GF_BgO6YYfbIr4TQIr4TQIr4TQW`PeRk?U4M
+L)@Af^*!FMrsiU7hqL,)s8TZ7RdGl;b5M>Am;7@Hrs$&=RdK8dQJMQF\m(WjLL83^rrmO2oB.Nf
+`W$-b6(71r?cp+_#.e$-m>#&ke,KF8rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUrVntJ!2]_P3<9*Z!8dbUh>mTU!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrsiO2hVL8.s8TW5SF;8?ao25@mVdUKrs$#;SF>ViPhl?D\QYNlLgJ3]rrmI1pZEui
+`W$-`6CdM#?HKq]#.[p-mtb;le,KF5rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]r;Sg:&-+Ge!<<'!hZ*W4!<<'!hZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i%JO$3#]'27s8/oU#X,`rrrVV,J+imGqlM^]#]nf$"oGDZ#X,`Urri(+#RGLirrr.,
+2$c@U^&J95XYgAI\^LKXmetuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZr;Sg<'Eg7m!<<'!g].<.!<<'!g].<@D1DT"64Qk,.#%\ND=.@QD=.@QD=.AtUbW8_:$;QV
+Jf"JAV?$Aj%J*^.$u,J9s8/lU$p_E%rrVS)J+imGqlD[a%!CA*"oGAZ$p_D]rri()$k.9srrr.*
+2@Mj^^&J95X>UJP]$gTYmJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUr;Sg:&-+Ge!<<'!hZ*W4!<<'!hZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i%JO$3#]'27s8/oU#X,`rrrVV,J+imGqlM^]#]nf$"oGDZ#X,`Urri(+#RGLirrr.,
+2$c@U^&J95XYgAI\^LKXlM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]_uBc*It@WNs2+d9metuC]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZ_uBc)It@WNs2+d9mJYc?\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspU_uBc*It@WNs2+d9lM]97[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]_uBbo!;QQoc22tjmf!1c_uBZ>rRREkT\T8@"o[#@Knm4orrrAPRY@Eihu<iVZ%IhB`;^#<
+Z'pB>gqE^krRREkT\Ruq!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZ_uBbl!;QQocMN(kmJd+erkl\RrrrAOR>%<hpAY<peX;,H]%m;hrRI<iT\SH)"T,EULUtG(
+"oGNlKqR57rrrAOR>%<hdf0=7rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspU_uBbo!;QQoc22tjmf!1c_uBZ>rRREkT\T8@"o[#@Knm4orrrAPRY@Eihu<iVZ%IhB`;^#<
+Z'pB>gqE^krRREkT\Ruq!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]_uBbo!;QQoao,u\4X'7nqrYRmKDtlTfR7(G>`%P9rs%,(??'mUakct$fR7(G>`%P"rroZ"
+F)O[m`W$.I8mZLBM<)DN#2"?1EEn@]e,KF9rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J
+:4N~>
+ZMspZ_uBbl!;QQoaSfl[4<j1mqrYOlK`:uUfR@.G?&I_;rs%,)?>sgTb2*(%fR@.G?&I_$rro]#
+EGnIl`W$.J8mZIBMWDMO#2"B2E*\@^e,KF8rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB
+9n3~>
+ZMspU_uBbo!;QQoao,u\4X'7nqrYRmKDtlTfR7(G>`%P9rs%,(??'mUakct$fR7(G>`%P"rroZ"
+F)O[m`W$.I8mZLBM<)DN#2"?1EEn@]e,KF5rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m2
+8q6~>
+ZMsp]rVlodJ,]I+mXP9:J(C!:OOjI3J(C!FLU6:GkconsW8djW^SIl`SAD.XT%sAGrRRKmK;ePE
+s1sVCPdpehrrDrql3Z0>R/d3U[;@@Brr31o>-dFd?Ej2(#+f#(lK28Zh>[\N>-dFd?EiAf"[.(t
+k#u65rrtW1ZKe)hYeL,ASm&GbTO+kOrrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+ZMspZrVlocJ,]I+m=509J(C$=O4=40J(C$ILpH:FkHK_qW8[dV^SIocS\hC]S_O2ErRRKmK<"\G
+s2'bFPI:JdrrDlolNu6<R/d3U[;@=Arr31o>I3Ug@']P,#+f&*lK;A_h>[\N>I3Ug@'\_j"[75!
+k?DN:rrtZ4Zg+5lZG->CSm/PdTjY1TrrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(J
+J,~>
+ZMspUrVlodJ,]I+mXP9:J(C!:OOjI3J(C!FLU6:GkconsW8djW^SIl`SAD.XT%sAGrRRKmK;ePE
+s1sVCPdpehrrDrql3Z0>R/d3U[;@@Brr31o>-dFd?Ej2(#+f#(lK28Zh>[\N>-dFd?EiAf"[.(t
+k#u65rrtW1ZKe)hYeL,ASm&GbTO+kOrrD?_ecE0NJH16$d/a22JH16$dJsF$s428kp=9A2!9]S=
+J,~>
+ZMsp]rVloT!<3!Vh>mTU!-a3J:1!u#!-a3NAlc)3UeYB?=J#EiIli."8m$L]9U>MSdt):YF&&8*
+_+nTdF&i;5rtC<'p](9cc)+6cs8VnCEU<_XArZTc#Pidfm/R*j*8^]#q0d8Ls4CqCiVs,R#ho=Y
+YoLd`#P/5Tm/P^MNPGJuq0d8Ls4CqCe,KF9rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZrVloQ!<3!VgAq9R!-a9L:0mo"!-a9QB2u,3UeP<<=.T3fIli1%93H^a99o>Qe:VO[F&/>+
+_G=liF&rA6rtC<%p&G'ac)+3bs8VnCE9mPUBTMrg#Pideli7!h+Q!,'q0d5Js4:qFiVs,R#h]1W
+YTUsc#P/5Rli5RMO2(]"q0d5Js4:qFe,KF8rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUrVloT!<3!Vh>mTU!-a3J:1!u#!-a3NAlc)3UeYB?=J#EiIli."8m$L]9U>MSdt):YF&&8*
+_+nTdF&i;5rtC<'p](9cc)+6cs8VnCEU<_XArZTc#Pidfm/R*j*8^]#q0d8Ls4CqCiVs,R#ho=Y
+YoLd`#P/5Tm/P^MNPGJuq0d8Ls4CqCe,KF5rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]rVloT!<3!Vh>mTU!.XG:X9ek+!.XG1eQRV&Z&mVtA97>AIn[uLD+r(:D/o(DP\/&,mZ]$l
+:0uZKhI6KXrrUV/f)5OVmVdUTs6t#VrVu/"Jb]6Mn8WmTs8UXQhZ!iMEIIfcl>;+2rs%H_qu?]I
+"NLHHiW/lSs6=HP^]+Q.EIIfcl>;+$rrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+ZMspZrVloQ!<3!VgAq9R!.XJ9X9ek+!.XJ2e67M$Y`RJo@r_&=In[uLD+ht8D/f"CQ"\8.n!#*l
+;.&&OhI?QYrrUP.eGT=Tm;7@Qs7()Vr;Z"tK)#?NnSrsSs8UOPhZ!iNEI@]al"kt1rs%K`q>^KD
+#0-ZJirJoQs64?O^]+Q/EI@]al"kt#rrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(J
+J,~>
+ZMspUrVloT!<3!Vh>mTU!.XG:X9ek+!.XG1eQRV&Z&mVtA97>AIn[uLD+r(:D/o(DP\/&,mZ]$l
+:0uZKhI6KXrrUV/f)5OVmVdUTs6t#VrVu/"Jb]6Mn8WmTs8UXQhZ!iMEIIfcl>;+2rs%H_qu?]I
+"NLHHiW/lSs6=HP^]+Q.EIIfcl>;+$rrD?_ecE0NJH16$d/a22JH16$dJsF$s428kp=9A2!9]S=
+J,~>
+ZMsp]rVloT!<3!Qh>mTU!6tQDh>mTU!6tQDmVdUTi2W*/8oO.tIr4QPIr4QPIrFcIFZXr"Ir>>H%
+))Z?!Pnd/rrHVVqu7)mDh%fenoK6Xs6=HPq#:TiF++#es4.>0rs/+9IJs32D1U[G#3Gp_s8UXQ`
+r?;+!;l`pl>;*ers/+9IJs32D1U19#4CXAk2*dHJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQJ
+,~>
+ZMspZrVloQ!<3!QgAq9R!6kKCgAq9R!6kKCm;7@PhQ)s-8o<tqIr"BMIr"BMIr4TGFut#"Ir>>I%
+_hrB!Pe^/rrW.-H2IUMm;7@Qs712Xr;Z&!K)#?NnoB-Us8UURhZ!iOEd[fbl>;.3rs%Qbq>^KF#
+0-ZJjT,,Ss6=HQ^]+Q0Ed[fbl>;.%rs%lOmH!$59n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9
+n3~>
+ZMspUrVloT!<3!Qh>mTU!6tQDh>mTU!6tQDmVdUTi2W*/8oO.tIr4QPIr4QPIrFcIFZXr"Ir>>H%
+))Z?!Pnd/rrHVVqu7)mDh%fenoK6Xs6=HPq#:TiF++#es4.>0rs/+9IJs32D1U[G#3Gp_s8UXQ`
+r?;+!;l`pl>;*ers/+9IJs32D1U19#3t.3i7>;.JH16$d/a22JH16$dJsF$s428kp=9A2!9]S=J
+,~>
+ZMsp]rVloT!<3!QblIeD!8dbUh>mTU!8dbUmVdUPVJD*_<,_4)IrFcTIrFcTIrFcIFZk/&IsYhn%
+)MrC!Pnd0rrUaphY[<]mVdUTs8.:emf2!SNVNMYqgW\Ts8TJHhZ!iXIrk&Xg1ZK)rs&3'hZ*V`*
+6/!`pB]XDs4V.G^]+Q9Irk&Xg1ZJps8VKjp9(:+:)JO:JMGA'JH16$ec5j0s5&G/p>,qB!:QFQJ
+,~>
+ZMspZrVloQ!<3!QbQ.\C!8IPRgAq9R!8IPRm;7@MVe_3`<Gh.'Ir4TQIr4TQIr4TFF?Fr#IsYho%
+`&)D!Pe^/rrU[mh#%*[m;7@Qs8%4cmJkmUO8/_[qL<PQs8TMMhZ!iWIrarVg1uc.rs&-'g].;^+
+NFEdoa9I@s4V7L^]+Q8IrarVg1ubus8VHhp8t.%9n<:q!6Y@n:[CjWBAA"2:\B2;BD,+$BC:9E:
+[`c5BBW.hIg"O+gOfJ!gB<rFl^COu~>
+ZMspUrVloT!<3!QblIeD!8dbUh>mTU!8dbUmVdUPVJD*_<,_4)IrFcTIrFcTIrFcIFZk/&IsYhn%
+)MrC!Pnd0rrUaphY[<]mVdUTs8.:emf2!SNVNMYqgW\Ts8TJHhZ!iXIrk&Xg1ZK)rs&3'hZ*V`*
+6/!`pB]XDs4V.G^]+Q9Irk&Xg1ZJps8V?eoW"Rl8q?tn!6Y@nJ*_Xb5MQ85J+WdA5PBR,5OJOHJ
++!@;5NmUp!!LmQeoUlbec_3;kEJSh~>
+ZMsp]rVntA!7Lo8HN=*G!8dbUh>mTU!8dbUmVdULGA$'r?u>91IrFcTIrFcTIrFcRP%`,3o;I<A
+:1DrOhIci^rrIUAqYpWbDh%cd#,#G?pSq],p\tGj@__[/@Ue0n#,#G?pSq],i;WsHK_t@M@`A?O
+6%m#IWa`3Hrs#-*^\=a;Yg`UWmcLZ2DnSn#JRa7@dUW<7rF:BYJH47$"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZrVnt>!7:c7HN=*G!8IPRgAq9R!8IPRm;7@HGA$$p@;G3/Ir4TQIr4TQIr4TNO_Dr/o;[NE
+;.82QhIQ]\rrIU?qYpWaD1DQb#,,P?p8_`0p\tGkA%hU-@qFKr#,,P?p8_`0i;WsKK),"JA]=ZR
+7"W,GX(8NMrs#0,^%SL;ZIAgXmGtB-D7WGm!.b-t!<5:^!.ga.ScI'ks7`,XrrC@<ScI((s7i2S
+rrC@.T)ATkg]-#[s7Y1MRK2ZB9n3~>
+ZMspUrVntA!7Lo8HN=*G!8dbUh>mTU!8dbUmVdULGA$'r?u>91IrFcTIrFcTIrFcRP%`,3o;I<A
+:1DrOhIci^rrIUAqYpWbDh%cd#,#G?pSq],p\tGj@__[/@Ue0n#,#G?pSq],i;WsHK_t@M@`A?O
+6%m#IWa`3Hrs#-*^\=a;Yg`UVlJS["CUHcc!.b-t!<5:^!.k1:rr@Q(!;HNd!!%NBrr@Q:!;QT_
+!!%N4s82j"f)O<Bs7Y"HPQ9m28q6~>
+ZMsp]rVntR7Tt:sErc7?!8dbUh>mTU!8dbUmVdUPRT+Qf<(OLuIrFcTIrFcTIrFcTc[BJNG>aP&
+_+nTdG@LXHrrF^9qYpWbDh%cd#24]DHX_oop\tHOK5#[V:<D>l#24]DHX_ooi;Wtg;L`mcai48a
+[8L^c@Z0<]rs%20BmX<IjO=,6mbXgZVS,_AJMD^1dP:c(r@rj'JH47$"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZrVntP7pCP$E<-%=!8IPRgAq9R!8IPRm;7@LR8nNg<_9e#Ir4TQIr4TQIr4TQd!]SOG?'e*
+_G+ZeG@LXIrrW-MOo#(Zm;7@Prs%20BRF?LjS/ZYg4O'dGtuN<rs%20BRF?LjP^%A[S_O":<LQU
+#.@BBHt82s^AeDkK4oXCN9&If#4:0@D5=a;JH16$d/a22r;_CElq[Uogjf&oomZsSp.k[$mXP"-
+msb=MkYM,+"P`t2K)bQ!"I]>VRSA;~>
+ZMspUrVntR7Tt:sErc7?!8dbUh>mTU!8dbUmVdUPRT+Qf<(OLuIrFcTIrFcTIrFcTc[BJNG>aP&
+_+nTdG@LXHrrF^9qYpWbDh%cd#24]DHX_oop\tHOK5#[V:<D>l#24]DHX_ooi;Wtg;L`mcai48a
+[8L^c@Z0<]rs%20BmX<IjO=,5lIMVDTX@CC!.b-t!<5:^!.fXdIfM^g!;D!9!!#7WIfM_$!;M'4
+!!#7IJ,B9Lf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]r;SgsLOY]BJ,fOumf3=TJ,fOumf3=\\%ht"TS98LP/715\+]j:\+]j:\+]k!d?oQ=V"=Wd
+_2Ef1dXUuj!JB,&rrVo'^]+6:rRREiT%s&>"o[#@K7g_irrrAPRY.3ehu<iVZ%I\>`;^#<Z'p<:
+gqE^krRREiT%qco!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZr;SgtM1M)EJ,fOumJm4RJ,fOumJm4[[_Mk!TSBDPPJ[@7[eBa9[eBa9[eBaud?oT>VXsif
+^l*]/dXV#k!r[c(qYpWj[_MhA"oZu?KqI/orrrAORY?I,h#@QVeXD2agu&,7qlkd.]#=UPqllNC
+TA7-["oZu?KqI/KrrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+ZMspUr;SgsLOY]BJ,fOumf3=TJ,fOumf3=\\%ht"TS98LP/715\+]j:\+]j:\+]k!d?oQ=V"=Wd
+_2Ef1dXUuj!JB,&rrVo'^]+6:rRREiT%s&>"o[#@K7g_irrrAPRY.3ehu<iVZ%I\>`;^#<Z'p<:
+gqE^krRREiT%qco!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Z&Ck3hBg]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BjR)$_\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?i9K7O[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)bl="ST!q]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)bl<"SSsn\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)bl9"SA^e[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Z&Ck,pX]]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BjK1=W\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?i2SYM[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Z&ChPP4g]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BgSA\^\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?et?fO[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Z&Ck3hBg]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BjR)$_\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?i9K7O[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)bl="ST!q]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)bl<"SSsn\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)bl9"SA^e[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Z&Ck,pX]]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BjK1=W\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?i2SYM[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Z&ChPP4g]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BgSA\^\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?et?fO[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Z&Ck3hBg]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BjR)$_\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?i9K7O[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)bl="TRoH]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)bl<"TRlD\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)bl9"TRc<[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)bi<s).qO:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)bi;s(qeJ9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)bi8s(_YC8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Z&ChJWC4]hX+YJH4'ts*oS"JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZJcC<$K)Z&BgMHq-\kR_UJH4'ts*oS"JH4*u"P`t2K)bQ!"I]>VRSA;~>
+ZMspUJcC<$K)Z&?enY8$[7YuMJH4'ts*oS"JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]_uBbo!.k0$s2+d9metuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZ_uBbl!.k0$s2+d9mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspU_uBbo!.k0$s2+d9lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]_uBbo!;HKsej9WJ;WmuXs+gLOs+g:I"oGDZ$kRL8rrr;%2%2d]hu<iR@gEWe`;^#8@l4Z\
+\\8"HqlM^a6+PGD!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZ_uBbl!;HKsf0orR<Tj>\!r[n2r;QisLPb^("oGAX$kRR:rrr;$1^l^^hu<iR@0dEe`;^#8
+@5JBZ]"S+IqlDU_6FtVF!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspU_uBbo!;HKsej9WJ;WmuXs+gLOs+g:I"oGDZ$kRL8rrr;%2%2d]hu<iR@gEWe`;^#8@l4Z\
+\\8"HqlM^a6+PGD!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]_uBbo!;HL%+`li'>!i8hpWe+3J,]HNpWe+3J+`gG[8)M.c68G.rs#l+LXpZQal*1&CGF\k
++dBtG#&>rKeot<>^AeDF:5@DE>057ns6^$imbYWPJH16$d/a2rJH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+ZMspZ_uBbl!;QR'q]L%EhcW8Fs7afc,_,gn"S^2g,_,Le#.@?`e^#A(h>[\f:l!SF>KYn("`6*N
+cQJOmrs!<sLXgTQb.dl[[SVb0G?`5=s8VHhs6\RP9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB
+9n3~>
+ZMspU_uBbo!;HL%+`li'>!i8hpWe+3J,]HNpWe+3J+`gG[8)M.c68G.rs#l+LXpZQal*1&CGF\k
++dBtG#&>rKeot<>^AeDF:5@DE>057ns69aelIN@8JH16$d/a2rJH16$dJsF$s428kp=9A2!9]S=
+J,~>
+ZMsp]rVloT!<3!Vh>mTU!3IsU+g(eE!3Ism&80SodUNgs;T8\9InE`M3J13<4h:UmqlMje#ZC-k
+s+D3h.?ji-rsdfbp](9E!<<)aS6ddsrr3,dS6ddsp&>5OB&<RfPVM"o#)?gIs2e`;i;Wrl^&S+s
+0ua.s&A?s#a^UXOrs"6jhZ(],R+)*7mf.2+]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+ZMspZrVloQ!<3!VgAq9R!3S-]+KGJA!3S-u&nTSmcs[Io;8iM7In<]Q4G?cF4LkFkqlVsg#Z^?n
+s+VKn.$=T*rsdicp](9B!<<)`S6mgsrr3,cS6mgsp&>5OBAW[gQ8IFt#)?jJs2no@i;Wrl^An5!
+1r]J!&AI$$b%7!Trs"6khZ(`0RFD38mJh#(\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+ZMspUrVloT!<3!Vh>mTU!3IsU+g(eE!3Ism&80SodUNgs;T8\9InE`M3J13<4h:UmqlMje#ZC-k
+s+D3h.?ji-rsdfbp](9E!<<)aS6ddsrr3,dS6ddsp&>5OB&<RfPVM"o#)?gIs2e`;i;Wrl^&S+s
+0ua.s&A?s#a^UXOrs"6jhZ(],R+)*7lMkW#[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]rVloT!<3!Vh>mTU!(,QBHP$5W!(,Q1]g[_NG<*(b??c/DIk@VM=tQ](>''<8XB(kNhF^E?
+KG_,c]bgbDrrjR!p[;TPrVlreDh%]b!q'uVpAYBhF*mfas3:o,rs/.:Hi*j*CP1UG#3Q!\s8U@M
+`r?;,!;HBjk%fUars/.:Hi*j*CP1+9#4C>d!,oPGJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+ZMspZrVloQ!<3!VgAq9R!(#N>I1ZGY!(#N0]LI\NG<3+^?$5i?IkIbP>:c`(>BBE9Y$%:RhapE>
+L)@Af^)R.Jrs&?CK(JG>4T59]m;7@NrrVS)J+imIo5f3Qs8U7NhZ!iPF*[T]j_KS/rs%WdoDej6%
+*&;Pk5b,Ls5e$M^]+Q1F*[T]j_KS!rs%lFD#eFa9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUrVloT!<3!Vh>mTU!(,QBHP$5W!(,Q1]g[_NG<*(b??c/DIk@VM=tQ](>''<8XB(kNhF^E?
+KG_,c]bgbDrrjR!p[;TPrVlreDh%]b!q'uVpAYBhF*mfas3:o,rs/.:Hi*j*CP1UG#3Q!\s8U@M
+`r?;,!;HBjk%fUars/.:Hi*j*CP1+9#3scT!,Ju7JH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!Qh>mTU!58F4h>mTU!58F4mVdUTlK8!/CN&Y@Ir"?LIr"?LIrFcPH[#5as5!bE
+(o@63!Nc@rrrBb3!!*A^rVlreDh%]b!q'uVpAY3^Dh%cd!T!h5rs.t1J,fQ:Dh$aG!T!hUrrLsV
+`r?(r!<3!"mVdTirs.t1J,fQ:Dh$79!:KgB!PM6Z!.b-t!<7P"!.b-u!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZrVloQ!<3!QgAq9R!5AL5gAq9R!5AL5m;7@Ol0%s.Bl38;Iqe0IIqe0IIr4TMI<YAas5*hF
+*2``8!NH.orrBY0!!*A[rVlrdD1DK`!psiSpAY3_Dh%cd!S[V2rs/"2J,fQ9D1COE!T*nVrrLjS
+`r?(s!<3!"m;7?frs/"2J,fQ9D1C%7!:Ba>!P2!V!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+ZMspUrVloT!<3!Qh>mTU!58F4h>mTU!58F4mVdUTlK8!/CN&Y@Ir"?LIr"?LIrFcPH[#5as5!bE
+(o@63!Nc@rrrBb3!!*A^rVlreDh%]b!q'uVpAY3^Dh%cd!T!h5rs.t1J,fQ:Dh$aG!T!hUrrLsV
+`r?(r!<3!"mVdTirs.t1J,fQ:Dh$79!:'O6!OYON!.b-t!<7P"!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]rVloT!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9ec=;#
+rrL[Np\tC6HhZu43W8sZmVdUQrrVV,J+imIpNLu]s8U@MhZ!iTGC05ek%fV.rs%olp](9=#fclL
+mf<+Zs5n*L^]+Q5GC05ek%fUurrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+ZMspZrVloQ!<3!HgAq9R!8IPRgAq9R!8IPRm;7@Qe8I*/.W+SQIr4TQIr4TQIr4TADu0M9f)XG%
+rrL^Oq#:Qq*.@GE>s/)c!psiSr;QicD1D9Z#PE4bq>^K@%,V!holYQUs6"6QiVs,J!;$6jcO@hn
+#O;B]q>]VpKtmWmolYQUs6"6Qe,KF8rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUrVloT!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9ec=;#
+rrL[Np\tC6HhZu43W8sZmVdUQrrVV,J+imIpNLu]s8U@MhZ!iTGC05ek%fV.rs%olp](9=#fclL
+mf<+Zs5n*L^]+Q5GC05ek%fUurrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@srs%Wdp](9E!<)p!mVdUQrrVV,J+`gGLMPoLs-th"rs"6oir@88R,IuJ&B=bMS2&"_
+"q\f6s35/C^AeCmCZ>B=Ash'Is6^'jmbYWP0nEhc@tA-@A"dB8hZ)Gcs7Y:PS,i#J:4N~>
+ZMspZrVloQ!<3!Q^&\35!8IPRgAq9R!8IPRm;7@IH"Z7=Ir4TQIr4TQIr4TQIr4TKH$T5cs7ak>
+*30#<!NH.prs%K`p](9B"TA?%m;7@NrrVS)J+`gGM/2)Ms.2('rs"<qiW%2;RGe)K'Z9tNSi"Fd
+"r+u6s3>>H^AeCoCZ5<=BpmHMs6TshmG#3HJH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+ZMspUrVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@srs%Wdp](9E!<)p!mVdUQrrVV,J+`gGLMPoLs-th"rs"6oir@88R,IuJ&B=bMS2&"_
+"q\f6s35/C^AeCmCZ>B=Ash'Is69aelIN@8JH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]rVntJ!2]_P3<9*Z!8dbUh>mTP!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrrj6\kMB*'rVlreDh%]b!q'uVp&>6,>+G'E.?rZg#.[p-mtb;li;Wt%6MKXlPf<Y,
+F$cDcLgJ3;rs$#;SF;8?aj^:hmf.2,]hU;5@tA.<A,ifb@tA.<@g(ZghLtq&h?9>Kn!m.'~>
+ZMspZrVntF!2BMN2us!Y!8IPRgAq9M!8IPRm;7@GF_BgO6YYfbIr4TQIr4TQIr4TQW`PeRk?U4M
+L)@Af^*!FNrs&??ETc4Z62gfbm;7@NrrVS)J+`gG\m(Wjk9uYPrs$&=RdGl;b2E:'F[>W^.$hjP
+#'E5#m>#&k^AeDK>FOr7?cpjtrpB`&!P2!V!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+ZMspUrVntJ!2]_P3<9*Z!8dbUh>mTP!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrrj6\kMB*'rVlreDh%]b!q'uVp&>6,>+G'E.?rZg#.[p-mtb;li;Wt%6MKXlPf<Y,
+F$cDcLgJ3;rs$#;SF;8?aj^:hlMkW#[7YuMJH4'ts*oS"JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]r;Sg:&-+Ge!<<'!hZ*W/!)Q>hhZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i"kH!?#ZBjarrVV,J,K<JmVdUJrrr;%2$aJ/h#@QTXYgAI\_mDipL=I7F2\(^pL?&d
+4h89+"oGDZ#X,`Hrs%oJDZF^h:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZr;Sg<'Eg7m!<<'!g].<)!)Q>hg].<@D1DT"64Qk,.#%\ND=.@QD=.@QD=.AtUbW8_:$;QV
+Jf"JAV?$Aj"kQ0G$rQ3drrVS)J,K<Jm;7@Grrr;$2@L":h#@QTX>UJP]&3MjpL+I=Fi=:`pL,rg
+5e=Z/"oGAZ$p_DPrs%lFD#eFa9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUr;Sg:&-+Ge!<<'!hZ*W/!)Q>hhZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i"kH!?#ZBjarrVV,J,K<JmVdUJrrr;%2$aJ/h#@QTXYgAI\_mDipL=I7F2\(^pL?&d
+4h89+"oGDZ#X,`Hrs%c>CB/.X8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]oD]$k[ndeJ''b&JJcD):!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZoD]$k[ndeJ''b&JJcD):!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspUoD]$k[ndeJ''b&JJcD):!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]pAYEp[ndeO!!!_]JcC<$QN$sQrS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZpAYEp[ndeO!!!_]JcC<$QN$sPrS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUpAYEp[ndeO!!!_]JcC<$QN$sMrRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]q>UTo[ndhPr;Zj1Y(?V(s-<WamKERXhRu[8!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZq>UTo[ndhPr;Zj1Y(?V(s-<Wam0*IVgU^+1!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspUq>UTo[ndhPr;Zj1Y(?V(s-<Wal3..Pf!S,$!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]qYpouRS4J3'*A47%Xip.JcCu7rpKf)!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZqYpouRS4J3'*A47%Xip.JcCu7rpB`&!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspUqYpouRS4J3'*A47%Xip.JcCu7rp'N!!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]pAY<W7L9&#9nE=qs-*HembVj^DnSns!.b-t!<7P"!.b-u!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZpAY<W7L9&#9nE=qs-*HemFuIXD7WGm!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+ZMspUpAY<W7L9&#9nE=qs-*HelIK_NCUHcc!.b-t!<7P"!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]p\tH.0;]Nd/,4\qJcCr6!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+ZMspZp\tH.0;]Nd/,4\qJcCr6!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspUp\tH.0;]Nd/,4\qJcCr6!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]q>U]lBhdd<%3"G]s+135rrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+g&D6Tr;6?dq#'jhq"adarTaC_g\LjSoP%%_d1%#XJcC<$P5bOLrS%@a9n<:q!.b-$!2';pg]-#[
+s7Y1MRK2ZB9n3~>
+g&D6Tr;6?dq#'jhq"adarTaC_f(o=NoP%%_d1%#XJcC<$P5bOIrRM"W8q?tn!.b-$!2';pf)O<B
+s7Y"HPQ9m28q6~>
+ZMsp]qYpf>0qA:DT*<Pls+134rrDKch>t;bJH16$d/a2rJH16$dJsF,s5&G/p>,qB!:QFQJ,~>
+h#@ZZqtTmXoCDG@r9jp\nac;EpA"Rbmf*:AqYpf>0qA:DT*<Pls+134rrDHbgB"l[JH16$d/a2r
+JH16$dJsF)s4`/*p=f_=!:-(JJ,~>
+h#@ZZqtTmXoCDG@r9jp\nac;EpA"Rbmf*:<qYpf>0qA:DT*<Pls+134rrD?_ecE0NJH16$d/a2r
+JH16$dJsF$s428kp=9A2!9]S=J,~>
+ZMsp]r;QlpG=1<frrI&<JcC<$OT,=KrS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+hu=,aqtTmVnaGl3lKRNrroa=F$0gaAmI0T:pA"RTrrCgOrr`(@6f@tD!H4uhs+133rrDHbgB"l[
+JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+hu=,aqtTmVnaGl3lKRNrroa=F$0gaAmI0T:pA"RTrrCXJrr`(@6f@tD!H4uhs+133rrD?_ecE0N
+JH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]rVluG2N[q:rrBoes+132rrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+iVt#!qY0XPmd03$jlGF[i8EMMi8ESQj5f@cl0Rj.o_8:SrrCgPrr^S*OT,4Y!5a<eJcCf2!:Ba>
+!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+iVt#!qY0XPmd03$jlGF[i8EMMi8ESQj5f@cl0Rj.o_8:SrrCXKrr^S*OT,4Y!5a<eJcCf2!:'O6
+!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMt-cs8W"M44f&`JcCQ+!:KgB!PM6Z!.b-t!<7P"!.b-u!!M0YhLtq&h?9>Kn!m.'~>
+j8TYhqtK^OmHWlqio&\KgY1?YfFHTggYCZDioK:fmI9`Ar:L!ng].<OKKIe:s+13+rrDHbgB"l[
+JH16$d/a2rJH16$dJsF)s4`/*p=f_=!:-(JJ,~>
+j8TYhqtK^OmHWlqio&\KgY1?YfFHTggYCZDioK:fmI9`Ar:L!nf)PdJKKIe:s+13+rrD?_ecE0N
+JH16$d/a2rJH16$dJsF$s428kp=9A2!9]S=J,~>
+ZMt*bs4KPfr.4m!s+gUSmetuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+jSoehq"4(Bl/q!`h:gN4e^Msor6Q#&daQatf\>6?j6#UmnFZMTpAY<Ns4KPfr.4m!s+gUSmJYc?
+\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+jSoehq"4(Bl/q!`h:gN4e^Msor6Q#&daQatf\>6?j6#UmnFZMTpAY<Is4KPfr.4m!s+gUSlM]97
+[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMt$_OuCU:s+13(rrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+k5Q(nqY'IHl/q!_gXt*+dEg(\b/sS&&]r2=c-Oedf%Aa7io]Lmo(N"Urr^u<2U6mRJcCH(!:Ba>
+!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+k5Q(nqY'IHl/q!_gXt*+dEg(\b/sS&&]r2=c-Oedf%Aa7io]Lmo(N"Urr^f72U6mRJcCH(!:'O6
+!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+Zi:-d4EgLNs+13'rrDKch>t;bJH16$d/a2rJH16$dJsF,s5&G/p>,qB!:QFQJ,~>
+kPl7pq=O.AkMtISf[S<obfRoE`59@,rkSQM&]2K*a2uQNdF?h'hrEncn+?MQrr_4AG5-XgJcCE'
+!:Ba>!P2!V!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+kPl7pq=O.AkMtISf[S<obfRoE`59@,rkSQM&]2K*a2uQNdF?h'hrEncn+?MQrr_4?G5-XgJcCE'
+!:'O6!OYON!.b-t!<7P"!.b-u!!LmQeoUlbec_3;kEJSh~>
+[/U3"19/7l!T!g-s+13errDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+kl2Cqq"*q<jl"qHeBuO`a2Gj1^:_(h\c0)Q\[oDc^;.V(a3)ZSeC`R7jlu4)q>:0nT/*@_rrLjS
+JcC<$_Z'W'rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+kl2Cqq"*q<jl"qHeBuO`a2Gj1^:_(h\c0)Q\[oDc^;.V(a3)ZSeC`R7jlu4)q>:0nT/*4[rrLsV
+JcC<$_Z'W$rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+[f6Kp:hfRY_uBbo!;HKsej9WJ;WmuXs+gUR#3q-j">-;@p\tEoXYgLuF56d!qlM^a6+PnQ"SZC3
+&9Gei"nuLa$phG;rrr;%2%2d]df0=8rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+l2NF7p[[_8j5/M@dEThR_n`ss\@/cNZE^[=Z*CU@['mKU]thP*b0JDcg>:lRmIL#NrrhR_C%U/t
+rrLjSp\tEK70j<%kPbD^rJ-7/rs%eJ+pKZmp%SIiqlDU_&9Ze."oGAX$pqP_rri()#S;-srrr.*
+1^l^^^&J95X>C>P]$gTYmJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+l2NF7p[[_8j5/M@dEThR_n`ss\@/cNZE^[=Z*CU@['mKU]thP*b0JDcg>:lRmIL#NrrhR_C%Tuo
+rrLsVp\tEJ63mipkPYA[L]7;XlAQkh/YMk4rrr;%2%1%;h#@QTXYgMQ\_mDipL=I?F2\(^pL?&h
+6+O]/"oGDZ$phGPrrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+\,QW60Y.5`hS]?oh>m<M%!u0%F&nP*s81rl<eLDO#.n>PF's.8p\tHMI9po39$,oh#2"?1EEn@]
+i;Wtc8onoCai48aYtA>B>`%OUrs%,(??'5,jO=,/metuC]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&
+"IoJ\S5+S~>
+lMhXtp[[\6in`8:ccaAH^V%+cZa$^9X/c)s*3-'AYHbFB\\,\pa32fYf\PQMm.0rOXY@<cs4bHk
+!S[VLrtkW\?$CEmPlLd\k.F`Js8W)1A7BXhFNjLZ#2"B2E,S@kh>[]3IU6u!MWE^q"gUa?DbA0k
+rs#c$?>s2-jM(WufR@.G?&I^lrrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(JJ,~>
+lMhXtp[[\6in`8:ccaAH^V%+cZa$^9X/c)s*3-'AYHbFB\\,\pa32fYf\PQMm.0rOXY@<cs45*f
+!T!hNrsX6XGB6fLs8VuY]iKdbrs$)E?uo^uc1h5BfR7(GDbA.-rs%,(??'5,jP^%AYtB(U9$,'P
+#-gd,EEn@]^AeDiI9pnuM<*.c!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+\c2d#>?pXrrrCpSrrMP;rr4nEJ,fOuesLrKf)Pc"esMANZg.SSZ%n%3irB%nUoK-=_5N'Zh#IEQ
+esqGHW;$>l_2Ef-\H)F)([_jBoBqths8VSrD(0u7s7CY?bOE2IP5"t\Sm&Gbk#u6Mrs#&uZKe)h
+Yi,Nb4a6>V>%5JN#!I19lC_If^AeD/>-dFd?EhoY!:KgB!PM6Z!.b-t!<597!.b-u!!M0YhLtq&
+h?9>Kn!m.'~>
+li.h#p[[\6iS<&5c,mo>]XYATY,nV#V50l\rh14(USO`aWN<;/[CElb`Q?ERfA,?Jm,M8Sn,E=e
+g\q-Qm=5-82XQ"os*rUfJWJ=\s*rUfNJOn)s6$VAKrEu1s1bA1LRl;^L7R*!s8CN=KnHE"s8Trq
+J!7;@q#;/t&@V3!Q6?5-n?m*]J,fQ?H<JG]]igNmrs#'!Zg-^XA_m@jSm/PdTjY1arrkT3mH7\b
+`W$-+H*ce0@'[NH#+f&*lChUke,KF8rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+li.h#p[[\6iS<&5c,mo>]XYATY,nV#V50l\rh14(USO`aWN<;/[CElb`Q?ERfA,?Jm,M8Sn,E=e
+f)>ULmXP692XZ(ps*rUeIur7]s*rUeMheY(s6-_CKrF#2s1bA0Kq,uXKq@*"s8CN=KnH>us8Ton
+J!@JDq#;/u&@M,tQm)M0n?m*^J,fQ@HW\J\]i^Hlrs#&uZKgRU@bq%gSm&GbTO+k\rrkQ0mcI\^
+`W$-*GI$M,?Eh0D#+f#(lC_Ife,KF5rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+])MiB0s1BR!8d\S!T!hUs#/^6s8N(CLOW'*s8N(CLP'2>Y5>"i@WPYCqu;.-IrS(_I;qrHq>\op
+CNjhpSH$E#Ap8;s!;QR1mL[)/pRE6's7FR5:4N<DnuB%ns4V"?q#:TpI<"WRs03R#rs/@JEU<_X
+ArYdL#4i,Ss8T>D`r?;8#hnYFfOg,Xrs/@JEU<_XArY:>!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&
+h?9>Kn!m.'~>
+m/It&q"!h8iS<#3bf@W8]!eoIWi)\fTUq[CRf8]lR[]h=TVA9\X0/b:]"Z)&bgG%tiM\B)qYgEo
+g\q-QgAq6Q2VS63rr@8"Inj;Lrr@8"KP+;fqkQqqEEA_-s*m+\F%]YbE_D\ns3u[:G&pHLs2%QG
+GB6gcq#;/t&A7i5RNDM/oZa7-J,fQ>WNl="fk-0;rs/@JE9mQ(YTVg&#Pideli5RMO5^*Co*F"K
+s0*Wcrs/-$f^&RhBTKq.#Pideli5RMO44+/mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+m/It&q"!h8iS<#3bf@W8]!eoIWi)\fTUq[CRf8]lR[]h=TVA9\X0/b:]"Z)&bgG%tiM\B)qYgEo
+f)>ULh>mQT2VnH6rr@7uInj>Mrr@7uK4\/eqkQtrF',%2s*m+[ECs>]ED2\os3lO7GB6NLs1qHB
+GB6dbq#;/u&A@u8S/hS/oZa7.J,fQ>WjDU&g16'8rs/@JEU<`*YoMX##Pidfm/P^MNT'mAo*F(M
+s03Q`rs/-$g?ejlArXS*#Pidfm/P^MNRRn-lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+]`/*+Bi+'krrCpSrrLsVrr4n5!<<'!J+!?<#ljo)J+!$\>(c^WOP&Q'F7T?\9ZcR:9ZcR:EU`pk
+B$'Q1PU6'!?J>/1@K?0&"`H_SG;Y<Wrs\=6J,fQIo_/19Me]s#rs/%5IJs3Gecak0#Ol_]rVu/"
+J`6V5iW/lUs4.=mrs.N`qu-Q[D1TJ%#Ol_]rVu/"J^aW!metuC]hX+YJH4'ts$)&7JH4*u"Q'18
+K`Cc&"IoJ\S5+S~>
+m/K!?oBkc$gt'ls`kf?uZ`gF-UnF9JR$O#$P*1rjP*;/sR%'Y>Uo18sZad]ca3;rV>=[32o_e^g
+!8IJP!S[VRs#/U3s8N(Kn,9<ns8N(Kn+P77KDMg6fAC(Xnc+)4am*_9aQdV]nGSVcaRJY_,kk/C
+g@sH6!;QQurG=iGG;P6Vrs\:3J,fQIo_/18MJBj"rs/(6I/O$Edg"\/#Oue]r;Z"tK&Q_6irJoT
+s3h1lrs.Qaq>C9WCkBG%#Oue]r;Z"tK%'`"mJYc?\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>V
+RSA;~>
+m/K!?oBkc$gt'ls`kf?uZ`gF-UnF9JR$O#$P*1rjP*;/sR%'Y>Uo18sZad]ca3;rV>=[32o_e^g
+!7q,K!T!hUs#/^6s8N(Kmf0?os8N(Kme517KDVp8f]$F_o)F25am*_:am*__nGSS`ame__-21/@
+g@sH5!;HKsDaJep22hG5%.8%`s8W&ipA<R%C;'EB#Ol_]rVuoK"Q'.`n8WmTs6=HPiVs,A!;lfr
+eca"m#N>a\rVu/"J\V3in8WmTs6=HPe,KF5rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m2
+8q6~>
+^&J/Q1SFRD!8d\S!T!hUs"W@1s8N)Ds8UpUs8N)Ds8VM*J,eH,QBk-]mf.cRm/MQPm/MQRmdtW`
+H[gN`!9+F#rr3#8!;HKsC-?of0oQ#1!q'uVrVm&^VL*Zto(`4inoK6Xs8UXQhZ!iOF++#el>;+2
+rs%Tcqu?]I"NLHHjoG;Ws6=HP^]+Q0F++#el>;+$rrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/
+p>,qB!:QFQJ,~>
+mJe($p$_/*h:L&u`kf<sZE:+&Tq.U;PECocMu8GPMiEd[PEqW-Tr"`jZF@K_`h"Z8h;dbgp&>!k
+g\q-QgAq6Q1"u^.rrC:Cs4[PRrrC:Cs6XZQrna]APtGo\s*nhMs*nhMs*nnQol`ECIt)A:isrg&
+rrKn8q#:QsCHd#d15l,2!psiSrVm&^VgE`ro(`4inoB-Us8UURhZ!iOEd[fbl>;.3rs%Qbq>^KF
+#0-ZJjT,,Ss6=HQ^]+Q0Ed[fbl>;.%rrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(J
+J,~>
+mJe($p$_/*h:L&u`kf<sZE:+&Tq.U;PECocMu8GPMiEd[PEqW-Tr"`jZF@K_`h"Z8h;dbgp&>!k
+f)>ULh>mQT1#;p1rrC=Ds5!bUrrC=Ds6afTs59oCQ:c)`s*nnPs*nnPs*ntToQ<6BIt)A:iXEO"
+rrKq9p\tD34aVB-MuEYWmVdURrrqJ\H[E0kq#:TiF++#es4.>0rs/+9IJs32D1U[G#3Gp_s8UXQ
+`r?;+!;l`pl>;*ers/+9IJs32D1U19!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+^]+E3G"1KdrrCpSrrLsVrr4^t!<<'!hZ*W4!<<'!hZ*WDDh%Y]CQ"ibDsmXTDsmXTDsmXTDsm7?
+4ahg0HY;UP_>aH8_#X91#4i86qtHHtrVlreDh%cd"k\`SRb%B1rs/FNF70).[2e''#Q'!lmf2!S
+NT'mApB]XUs0Widrs/9(hX:EtBT9e,#Q'!lmf2!SNRRn-metuD]hTDq0nD'10nD'Q0a-A5hLtq&
+h?9>Kn!m.'~>
+mf+7*p[RP0hUp9#`kf9qZ)jjtSskt.O,SpNKnP*XJfTJsKnkMDO-5ftSti3bZ*q,F2mq)dhW4"m
+q>^KLrVloQ!<3!QbQ.\C!8IPRgAq9R!8IPRm;7@MVe_3`<Gh.'Ir4TQIr4TQIr4TFF?Fr#IsYho%
+`&)D!Pe^1rs%p%](u#d+T;<Am;7@Prrq&7F.(STp\tKpIrarVs0a',rs/CMEp`n\CQIHS#5&>Xs
+8TMM`r?;:$JXtJg1ubars/CMEp`n\CQHsE!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+mf+7*p[RP0hUp9#`kf9qZ)jjtSskt.O,SpNKnP*XJfTJsKnkMDO-5ftSti3bZ*q,F2mq)dhW4"m
+q>^KGrVloT!<3!QblIeD!8dbUh>mTU!8dbUmVdUPVJD*_<,_4)IrFcTIrFcTIrFcIFZk/&IsYhn%
+)MrC!Pnd2rs&''\bl,g*<#m=mVdUSrrq&5F.1\Wp\tKqIrk&Xs0Wj'rs/FNF70(^BT;!N#58D[s
+8TJH`r?;<#i>"Lg1ZJ\rs/FNF70(^BT:L@!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+_#FM_2O".7rrCpSs#]?Cdf8`^!<<'!hZ*W4!<<'!hZ*WDDh%M*BBJ,[D=%:PDsmXTDsmXTDsmRe
+B[-/?W.Y+F@bUS5B)q`,#4i82oBqhdrVm;oDh%feoT!%WjQc%&p\tGj@__[/@Ue0n#,#G?pSq],
+i;WsHK_t@M@`A?O6%m#IWa`3Hrs#-*^\=a;Yg`UPmetuD]hU;5@tA.<A,hF;@tA.<@g(ZghLtq&
+h?9>Kn!m.'~>
+mf+7&oBk\ug=+<e_7[4\X/;S\R$3ShLkUG2IXHMAH6%?[IXm$(Ll@CYR%0kIX,n]F_8jgMg>M,\
+oD\dErVnt>!7:c7HN=*G!8IPRgAq9R!8IPRm;7@HGA$$p@;G3/Ir4TQIr4TQIr4TNO_Dr/o;[NE
+;.82QhIQ]^rs%p%[.EaN,5qNMm;7@Qs7D:SYN5$8p%SIjTjte0o4)@frs#0,^%SL;ZJb`d7"Y7+
+@qEXZ#"4'Vp8_`0^AeD2A%hT:A?s\a!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!gB<rFl^COu~>
+mf+7&oBk\ug=+<e_7[4\X/;S\R$3ShLkUG2IXHMAH6%?[IXm$(Ll@CYR%0kIX,n]F_8jgMg>M,\
+oD\d@rVntA!7Lo8HN=*G!8dbUh>mTU!8dbUmVdULGA$'r?u>91IrFcTIrFcTIrFcRP%`,3o;I<A
+:1DrOhIci`rs&''[I`gN+oVELmVdUTs7D=RYN5!6o_8@iTOP\1o3u1brs#-*^\=a;Yi,Nb6%o.,
+@Ud=V#!mpWpSq],^AeD1@__Z;@^+>]!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+_#FFZg@bIGhYmI9pI8>9LN<IqrrCpUs5!bUrrCpUs6afTqjLK0LK$gRs*ntTs*ntTs*ntTs3H+,
+GBZrHs1qHBGB[Nsp\tD@>'"a_Pl:UfmVdUTs4gj6BDuZH[J0\*g4O*dG>?99rs%20BmX<IjP^%A
+[8MKu:<CKT#.7?CHX_oo^AeDkK5#[AMr`@e!:KgB!kh>GJMD^1dP:c(JMD^1dP1m]s5&G/p>,qB
+!:QFQJ,~>
+n,FC*p@%8*gss`m_nEOaX/;PZQBI5aKn4]"G]n1Mrc0$#FEVnUIY!30NKTTsTr(YQ\%T]$cdpn2
+l0nEIg\q.6og`5;M/`OqrrCgRs4[PRrrCgRs6XZQqO(?/LfR*Vs*nnQs*nnQs*nnQs3Q1-GB[&L
+s2%KCGB[Nsq#:QsH!>E6;j@7\#jlJYs8UeW0k^K$!4DS$#24]CI!JK0h>[]5K4oXCN9&ps"h%9X
+GtuN$rs#o/BRF?LjM(Wug4O'dA;oTurrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(J
+J,~>
+n,FC*p@%8*gss`m_nEOaX/;PZQBI5aKn4]"G]n1Mrc0$#FEVnUIY!30NKTTsTr(YQ\%T]$cdpn2
+l0nEIf)>V1pI8>9LN<IqrrCpUs5!bUrrCpUs6afTqjLK0LK$gRs*ntTs*ntTs*ntTs3H+,GBZrH
+s1qHBGB[Nsp\tD@>'"a_Pl:UfmVdUTs4gj6BDuZH[J0\*g4O*dG>?99rs%20BmX<IjP^%A[8MKu
+:<CKT#.7?CHX_oo^AeDkK5#[AMr`@e!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]r;SgsLOY]BJ,fOumf3=TJ,fOumf3=\\%ht"TS98LP/715\+]j:\+]j:\+]k!d?oQ=V"=Wd
+_2Ef1dXV#k"mVb1K;eD?rs&2+^]4>rVYkoD^\@a3rRREiK=Te;"o[#@K:^lUrri5(K7g_Qrrr;)
+RY.3e^&J97es_5_gsZ3&metuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+n,GQHo'GJpf[7m\^::JMVP0KFOGemGIX63[EGo]0CMIX#D/XE9GC"^iLQ%@]S"Z^\ZFIWfbL+u"
+jm;U;g\h(4`ef87e:7MuJ*m:9m=509J*m:9p9qa9hOoV%[$/B,^UEk9^UEk9^UEk9qpCdaK;S8?
+s1jPBQdUBXrrq__JVC&orVm)q[_MkBjehs*!5J:."oZu?Kn[+nrrrAORY@Bhhu<iVY_@eB`;^#<
+YaU9<gqE^krRI?jTA7lp!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+n,GQHo'GJpf[7m\^::JMVP0KFOGemGIX63[EGo]0CMIX#D/XE9GC"^iLQ%@]S"Z^\ZFIWfbL+u"
+jm;U;f)5P/`J8r1epm`"J+!@:mXP9:J+!@:p:%g:hOoS"Z]`0)^UNq:^UNq:^UNq:qpCd`K;A,=
+s1sVCR*pKYrrq\\ItO]krVm)q\%htCk,/'+!5J:."o[#@K7g_irrrAPRY.3ehu<iVZ%I\>`;^#<
+Z'p<:gqE^krRREiT%qco!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+nGaO-p@%5(gXOKg^q-nTVkKWHOGejEI!B^OCh[NnAH$'ZA7]CgCiFK@I"@$1OHuE2Vld>;_8jjN
+gZ%GcpY19!JcC?%!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!gB<rFl^COu~>
+nGaO-p@%5(gXOKg^q-nTVkKWHOGejEI!B^OCh[NnAH$'ZA7]CgCiFK@I"@$1OHuE2Vld>;_8jjN
+gZ%GcpXXoqJcC?%!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+nGaO*oBbSqf?qaY]XG#CURda6MhQ\.G&_A5AR]%Q>lIqJ>[CfIASH"$G'eaoMij?sUT(K+]u/"?
+f\Y`Vo@ecqJcC?%!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!gB<rFl^COu~>
+nGaO*oBbSqf?qaY]XG#CURda6MhQ\.G&_A5AR]%Q>lIqJ>[CfIASH"$G'eaoMij?sUT(K+]u/"?
+f\Y`Vo@8ElJcC?%!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+nc(iQp[IG,gXOKf^q$bPV4X-<N.uk0F`;,.@U<8@<b6rEJS8(d>@(cOCN+ECJ;0#GR@g=WZFRck
+c.(M-l1!;Us+13%rrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+nc(iQp[IG,gXOKf^q$bPV4X-<N.uk0F`;,.@U<8@<b6rEJS8(d>@(cOCN+ECJ;0#GR@g=WZFRck
+c.(M-l1!,Ps+13%rrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp^JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+nc'[.p$Uu"f[7jZ]X=rATpq:,Lk0nqE,&rl>ZasDci3nC*9M-<=Bo6FC2e?CJV]>NS"cjb[_9T$
+dFdC?maQgfJcC?%!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!gB<rFl^COu~>
+nc'[.p$Uu"f[7jZ]X=rATpq:,Lk0nqE,&rl>ZasDci3nC*9M-<=Bo6FC2e?CJV]>NS"cjb[_9T$
+dFdC?ma$IaJcC?%!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp^JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+nc(lNo'>Amf$DCP\[&94SsPOrK7.r`CLpjV<De5As8:Bbe*m<[9i4qp?tF+nGC>+$OdDZ9XL#LS
+aNrGnjQk1lJcC<$KDtr=rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+nc(lNo'>Amf$DCP\[&94SsPOrK7.r`CLpjV<De5As8:Bbe*m<[9i4qp?tF+nGC>+$OdDZ9XL#LS
+aNrGnjQk"gJcC<$KDtr:rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp^JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+nc'[*nEJree',eF\$2j+S!8neJ9c0OAmeeB:h08"`DQUs*^FaK7nZZY>$trYF*W:jNKfp,WN`kG
+`QZidip"bdJcC<$KDtr=rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+nc'[*nEJree',eF\$2j+S!8neJ9c0OAmeeB:h08"`DQUs*^FaK7nZZY>$trYF*W:jNKfp,WN`kG
+`QZidip"V`JcC<$KDtr:rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+o)Bg1p@%2&g!Rs[]X4f<T9tauK7%f[BOP+F:eJn1dQBGe1`eP84?u>-:fU_/BQ&$@K8PeYT;J`t
+]Yhn>g#2&<pjrHrs+C=OmJYc?\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+o)Bg1p@%2&g!Rs[]X4f<T9tauK7%f[BOP+F:eJn1dQBGe1`eP84?u>-:fU_/BQ&$@K8PeYT;J`t
+]Yhn>g#2&7pjrHrs+C=OlM]97[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+o)D#Ro^1etf?hUT]!AB4SX#4jJ9c0NA6r>794@l#B/2+l/1iM12**rj92SbsA8?42J;9/NSYW<l
+]"uJ7fA>Z5pOW?qs+C=OmJYc?\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+o)D#Ro^1etf?hUT]!AB4SX#4jJ9c0NA6r>794@l#B/2+l/1iM12**rj92SbsA8?42J;9/NSYW<l
+]"uJ7fA>Z0pOW?qs+C=OlM]97[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+o)D#QoBbPoe]u4M\?Ms,S!/ebIWfXC@9QW)7[a;D0InLu,UFfg0/P^T7SQic@;'S'IYE`FS"cme
+\A-)0f%oE0oR[$ns+C=OmJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+o)D#QoBbPoe]u4M\?Ms,S!/ebIWfXC@9QW)7[a;D0InLu,UFfg0/P^T7SQic@;'S'IYE`FS"cme
+\A-)0f%oE,oR[$ns+C=OlM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+o)D#Po'>>keBPtH[]cX&R?EG[Hus4;?WU)s6biZ71n!A%n]#Jn.PE\B6V:3X?Y4.sI"R<>RA$R_
+\%]l,eD0*+nq$gls+C=OmJYc?\kR_UJH4'ts$)&7JH4*u"P`t2K)bQ!"I]>VRSA;~>
+o)D#Po'>>keBPtH[]cX&R?EG[Hus4;?WU)s6biZ71n!A%n]#Jn.PE\B6V:3X?Y4.sI"R<>RA$R_
+\%]l,eD0*'nq$gls+C=OlM]97[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+o)Bj.n`o,ge',bD[B?F"R#m/UH?3k4>ZFNh5h5nAh>dNBrr4%E-S$r45Y"RL?"@_lH@h!9R%L:Z
+[_9Z(eD'$)o)=4?JcCE'!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!gB<rFl^COu~>
+o)Bj.n`o,ge',bD[B?F"R#m/UH?3k4>ZFNh5h5nAh>dNBrr4%E-S$r45Y"RL?"@_lH@h!9R%L:Z
+[_9Z(eD'$%o)=4?JcCE'!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+o)D&On`f&ee'#\B[B6<tQ]HrQH#[S/>?"9b52lP@rfSK:+.rT5N$p><5"/1F>@VDgH%Cd5Q_1.W
+[CjH$e(Wg&nbn%=JcCE'!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+o)D&On`f&ee'#\B[B6<tQ]HrQH#[S/>?"9b52lP@rfSK:+.rT5N$p><5"/1F>@VDgH%Cd5Q_1.W
+[CjH$e(Wg!nbn%=JcCE'!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp_JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+o)D&On`f#dd`]P@[&p3sQB-fOG]@G,>#S*_4lHA?V\]mN"UVX;n161L4[_tB>@M>eH%:^3Q_((V
+[CjH$e(Wg&nbn%=JcCE'!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!gB<rFl^COu~>
+o)D&On`f#dd`]P@[&p3sQB-fOG]@G,>#S*_4lHA?V\]mN"UVX;n161L4[_tB>@M>eH%:^3Q_((V
+[CjH$e(Wg!nbn%=JcCE'!:'O6!OYON!.b-t!<597!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp__uBc*It@WNs2+d9metuC]hX+YJH4'ts$)&7JH4*u"Q'18K`Cc&"IoJ\S5+S~>
+o)D&OnEJocd`]P@[&p0rQB-fOG]@G,>#S'^4P9]66l-C?!shR"s&q$44[_tB>%22cH%:^3Q_((V
+[(O?#e(Wg&nbpH,!UYAfs+13errDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*p=f_=!:-(JJ,~>
+o)D&OnEJocd`]P@[&p0rQB-fOG]@G,>#S'^4P9]66l-C?!shR"s&q$44[_tB>%22cH%:^3Q_((V
+[(O?#e(Wg!nbpH,!UbGgs+13errD?_ecE0NJH16$d/a22JH16$dJsF$s428kp=9A2!9]S=J,~>
+ZMsp__uBbo!;HKslC`c^W:Tres24j9"n9-\M7N'JrrrAPRY?O-h#@QVes_;cgu&,7qltd/\]"LO
+qluTDT\R6\"o[#@KqR5LrrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+o)D&On`f&ee'#\B[B6<tQ]HrQH#[S.>?"9b4i76s,T.7)$P"Zds)p%R5"/.E>@VDgH%:^3Q_1.W
+[CjH$e(Wg&nc$N-!S[VKrrq__K8$>srVlru_o2QS"nB3^MRi0KrrrAOR>$F-h#@QVeX;,agu&,7
+qlk^.]#=UPqllKBT\R6\"oZu>KqR5LrrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+o)D&On`f&ee'#\B[B6<tQ]HrQH#[S.>?"9b4i76s,T.7)$P"Zds)p%R5"/.E>@VDgH%:^3Q_1.W
+[CjH$e(Wg!nc$N-!T!hNrrq\\K7g,or;Zf7rr3/k]8;BTme6YarRREkLUl4?"o[#@KqR5Yrri5(
+K87"Urrr;)RY@Ei^&J97es_;cgsZ3&lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp__uBbo!;HL%HWkW7<g<XaqrYRmKDtlS[piua@']M+#2"?1EGnIkh>[]3I9pnuM<*Up"gL[@
+DbA-jrs#`#??'5,jM(WufR7(G>`%OjrrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+o)D#On`o,ge',bD[B?F"R#m/UH?*e3>ZFNg5G8&R-QO$<',3)!s*-7X5=\IK>\%VkH@^p7R%L:Z
+[CsN&e(`m'n\kG.gAq$K%K1WZGBHuOs8VuY]N0^brs#uCB51n^rqHEsfR@.GDbA1.rs%,)?>s2-
+jP^%AZ:]+T9$5-Q#-pj-E*\@^^AeDiIU6u!MWE7d!:Ba>!P2!V!.b-t!<597!.b-u!!M'VgOfJ!
+gB<rFl^COu~>
+o)D#On`o,ge',bD[B?F"R#m/UH?*e3>ZFNg5G8&R-QO$<',3)!s*-7X5=\IK>\%VkH@^p7R%L:Z
+[CsN&e(`m#n\kG.h>m<M%!u0%F&nP*s81rl<eLDO"h.rRBje7?rs%,(??'mUakct$fR7(G>`%P"
+rroZ"F)O[m`W$.I8mZLBM<)DN#2"?1EEn@]e,KF5rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"H
+PQ9m28q6~>
+ZMsp_rVlodJ,]I+mXP9:J(C!:OOjI3J(C!FLU6:GkconsW8djW^SIl`SAD.XT%sAGrRRKmK;ePE
+s1sVCPdpehrtk)7[I`gR+ohT3[;@@Bs8VnEAD5mPIJNX;#+f#(lK28Zh>[\N>-dFd?EiAf"[.(t
+k#u65rrtW1ZKe)hYeL,ASm&GbTO+kOrrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+o)D#Oo'58ieBPtH[]cU%R?<AZHZX+9?<9rp6>cc&8g>Dt)]VfVs'moJ6:k!T?=dtqH\73=R@pL^
+[_B`*eD0*+oD\ajm=5-82XQ"os*rUfJWJ=\s*rUfNJOn)s6$VAKrEu1s1bA1LRl;^L7R*!s8CN=
+KnHE"s8TrqJ!7;@q#;/t&@V3!Q6?5-n?m*]J,fQEJ7[EiB70IJrs#'!Zg-^XA_m@jSm/PdTjY1a
+rrkT3mH7\b`W$-+H*ce0@'[NH#+f&*lChUke,KF8rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1M
+RK2ZB9n3~>
+o)D#Oo'58ieBPtH[]cU%R?<AZHZX+9?<9rp6>cc&8g>Dt)]VfVs'moJ6:k!T?=dtqH\73=R@pL^
+[_B`*eD0*'oD\ajmXP692XZ(ps*rUeIur7]s*rUeMheY(s6-_CKrF#2s1bA0Kq,uXKq@*"s8CN=
+KnH>us8TonJ!@JDq#;/u&@M,tQm)M0n?m*^J,fQEIq79iApsLLrs#&uZKgRU@bq%gSm&GbTO+k\
+rrkQ0mcI\^`W$-*GI$M,?Eh0D#+f#(lC_Ife,KF5rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"H
+PQ9m28q6~>
+ZMsp_rVloT!<3!Vh>mTU!-a3J:1!u#!-a3NAlc)3UeYB?=J#EiIli."8m$L]9U>MSdt):YF&&8*
+_+nTdF&i;9rtk)7^&.Po*<6'2c)+6cs8Vo*^&@/5J,/m>#Pidfm/R*j*8^]#q0d8Ls4CqCiVs,R
+#ho=YYoLd`#P/5Tm/P^MNPGJuq0d8Ls4CqCe,KF9rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J
+:4N~>
+o)Bg/oBYJne]u1L\$2j+RZi\`I<KOB@9QT'77-8=V(!bj,9F5lni/Wo7SH`a@;'S&I>*WDR\Hdc
+\A-&/e_T</p&=slgAq6Q2VS63rr@8"Inj;Lrr@8"KP+;fqkQqqEEA_-s*m+\F%]YbE_D\ns3u[:
+G&pHLs2%QGGB6gcq#;/t&A7i5RNDM/oZa7-J,fQE\\7q'DLM9Srs/@JE9mQ(YTVg&#Pideli5RM
+O5^*Co*F"Ks0*Wcrs/-$f^&RhBTKq.#Pideli5RMO44+/mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!
+"I]>VRSA;~>
+o)Bg/oBYJne]u1L\$2j+RZi\`I<KOB@9QT'77-8=V(!bj,9F5lni/Wo7SH`a@;'S&I>*WDR\Hdc
+\A-&/e_T<+p&=slh>mQT2VnH6rr@7uInj>Mrr@7uK4\/eqkQtrF',%2s*m+[ECs>]ED2\os3lO7
+GB6NLs1qHBGB6dbq#;/u&A@u8S/hS/oZa7.J,fQE\\7t*Dh%TXrs/@JEU<`*YoMX##Pidfm/P^M
+NT'mAo*F(Ms03Q`rs/-$g?ejlArXS*#Pidfm/P^MNRRn-lM]97[7YuMJH16$JH2>C"P3V(F8tsb
+"I&oLPY-H~>
+ZMsp_rVloT!<3!Vh>mTU!.XG:X9ek+!.XG1eQRV&Z&mVtA97>AIn[uLD+r(:D/o(DP\/&,mZ]$l
+:0uZKhI6KZrrm=-HZq?*rVlreDh%]b"2APRYkS/&n8WmTs8UXQhZ!iMEIIfcl>;+2rs%H_qu?]I
+"NLHHiW/lSs6=HP^]+Q.EIIfcl>;+$rrDKch>t;bJH16$d/a22JH16$dJsF,s5&G/p>,qB!:QFQ
+J,~>
+o)D#Ro^1bsf?_OR\[&61S<]+iIs>sJA6i548jnI7qi*<\0q/+APrV#r8l/PoA8?42J;9/MS><3k
+\\ZA5fA>Z5p\t0ngAq6Q2VS63rr@Q;rN$;)rr@Q;p=*8uqQQ(5hd^Zrs*m_al>928l>:M0rKV';
+nF)SepJG;OpYKB[q#:QsD*`Gk1lM>4!psiSrVm'#]kCTQrqQKunSrsSs8UOPhZ!iNEI@]al"kt1
+rs%K`q>^KD#0-ZJirJoQs64?O^]+Q/EI@]al"kt#rrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*
+p=f_=!:-(JJ,~>
+o)D#Ro^1bsf?_OR\[&61S<]+iIs>sJA6i548jnI7qi*<\0q/+APrV#r8l/PoA8?42J;9/MS><3k
+\\ZA5fA>Z0p\t0nh>mQT2VnH6rr@Q:s/ZM+rr@Q:p=3?!qlu78iad-$s*m_al>95:l>:P1rKLp9
+nEuMepJ,&KpYK?Zp\tD86@3o6MuEYWmVdUQrr^#M>-Rc$#Ol_]rVuoK"Q'.`n8WmTs6=HPiVs,A
+!;lfreca"m#N>a\rVu/"J\V3in8WmTs6=HPe,KF5rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"H
+PQ9m28q6~>
+ZMsp_rVloT!<3!Qh>mTU!6tQDh>mTU!6tQDmVdUTi2W*/8oO.tIr4QPIr4QPIrFcIFZXr"Ir>>H%
+))Z?!Pnd1rrm.#HZq3&rVlreDh%]b"M\YOWr;_m#P)qarVuoK"Q'.`noK6Xs6=HPiVs,E!;lfre
+ca"m#Nc$`rVu/"J\V3inoK6Xs6=HPe,KF9rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:
+4N~>
+o)D#Tp?q,%f[7jY]<n];SsPOqJpVWXB44tC:.[jVs8VrUqu?],4[2>+:K1M+B5Vj>Jr,SVT;J`t
+]>D_<f\kr:qYpKqgAq6Q1"u^.rrC:Cs4[PRrrC:Cs6XZQrna]APtGo\s*nhMs*nhMs*nnQol`EC
+It)A:isrg&rrKn8q#:QsCHd#d15l,2!psiSrVm'#^1gZLrV6BtnoB-Us8UURhZ!iOEd[fbl>;.3
+rs%Qbq>^KF#0-ZJjT,,Ss6=HQ^]+Q0Ed[fbl>;.%rrDHbgB"l[JH16$d/a22JH16$dJsF)s4`/*
+p=f_=!:-(JJ,~>
+o)D#Tp?q,%f[7jY]<n];SsPOqJpVWXB44tC:.[jVs8VrUqu?],4[2>+:K1M+B5Vj>Jr,SVT;J`t
+]>D_<f\kr5qYpKqh>mQT1#;p1rrC=Ds5!bUrrC=Ds6afTs59oCQ:c)`s*nnPs*nnPs*ntToQ<6B
+It)A:iXEO"rrKq9p\tD34aVB-MuEYWmVdUQrrg)N<iZ,nrs/+9IJs3Gecak0#P)qarVu/"J`6V5
+joG;Ys4.=mrs.Zdqu-Q[D1TJ%#P)qarVu/"J^aW!lM]97[7YuMJH4'ts$)&7JH4*u"P3V(F8tsb
+"I&oLPY-H~>
+ZMsp^rVloT!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9ec=;#
+rrL[Np\tC6HhZu43W8sZmVdUPrr^\MJ,B$@#PWFhqu?]A#i>RdpNLu]s5n*LiVs,N!;HNnc3VGi
+#O_Zequ>eoK>7EkpNLu]s5n*Le,KF9rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+nc(lKnEJoce',bD[]cX'RZi\aIs?!LARAS>:.ds)dJNtBf7Z=R77p?T=^P`UEd3(gN0B^(W3<YC
+`QZfbip"berr3#R!<3!HgAq9R!8IPRgAq9R!8IPRm;7@Qe8I*/.W+SQIr4TQIr4TQIr4TADu0M9
+f)XG%rrL^Oq#:Qq*.@GE>s/)c!psiSqu6cH=b6JFrs/4>H27L?cOA\1#PE4bq>]VpL#N%9lN$PV
+s3D+nrs.iioD/FLD2#b)#PE4bq>]VpL"$&%mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+nc(lKnEJoce',bD[]cX'RZi\aIs?!LARAS>:.ds)dJNtBf7Z=R77p?T=^P`UEd3(gN0B^(W3<YC
+`QZfbip"S`rr3#U!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9
+ec=;#rrL[Np\tC6HhZu43W8sZmVdUPrr^\MJ,B$@#PWFhqu?]A#i>RdpNLu]s5n*LiVs,N!;HNn
+c3VGi#O_Zequ>eoK>7EkpNLu]s5n*Le,KF5rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp^rVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@srs%Wdp](9E!<)p+mVdUTs7`%Zs8RRioCr7hLMPoLs-th"rs"6oir@88R,IuJ&B=bM
+S2&"_"q\f6s35/C^AeCmCZ>B=Ash'I!:KgB!PM6Z!.b-n!.eX2A(G,mhZ)Gcs7Y:PS,i#J:4N~>
+nc'[+o'>Ale]u4N\[&93SX,@oJp_`\C1LXR<)?7Z7R[5B*CN@f9Me\k?=[eiG'nq!OI)N6X0T:O
+a3N5kjQk1krrLjSrr4^e!<<'!g].<.!<<'!g].<@D1D;*BBB/CD=.@QD=.@QD=.@QD=..EH27L?
+pWrjZWrE#!WW;ho#3,^Xs8UONrVm;nD1DTcopVWRrI&\Up\tGSCZ5<nSi#:'#)R-Ss3>>Hi;Wrp
+_uKb.1r]J!'Z8o0c=r]\rs"<qiW%2;RFD09mJYc@\kR\PrrC@=T(2jAScI'RrrC@AT(r?VT#Ug$
+ScI'\rrC@AScI(5rrC@;Sq-lm!7h,Qg]-#[s7Y1MRK2ZB9n3~>
+nc'[+o'>Ale]u4N\[&93SX,@oJp_`\C1LXR<)?7Z7R[5B*CN@f9Me\k?=[eiG'nq!OI)N6X0T:O
+a3N5kjQk"frrLsVrr4^d!<<'!hZ*W4!<<'!hZ*WDDh%M*BBK5DDsmXTDsmXTDsmXTDsmLLHi*jC
+pWidUXoA>$XT8.r#3Q!\s8UXMrVm;oDh%fepRJ&Zs*o+]p\tGQCZ>BoS2&k"#)@!Rs35/Ci;Wrl
+`rH(/0ua.s&B<`0c"<?Wrs"6oir@88R+)'8lM]97[7^;r!.XbCnGqYM!.Vld!.XnGp]0mb`W5T0
+!.W5n!.XnG!.XkG!.X\AJH16$ec5j(s428kp=9A2!9]S=J,~>
+ZMsp]rVntJ!2]_P3<9*Z!8dbUh>mTU!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrrj6\kMB*'rVlreDh%cd"c$!l]i'd^rs$#;SF>ViPhl?D\QYNlLgJ3]rrmI1pZEui
+`W$-`6CdM#?HKq]#.[p-mtb;le,KF9rS@Rg:4WCr!7:fHJ,K@u@tA.@@g(ZghLtq&h?9>Kn!m.'~>
+nc'[/o^1euf[7jZ]X=o?Tph1)LOa\mDeW`h>#nQu9hYIX*D9+';c[(/A8,t(H@Ud1Pa\;DY-kp[
+b0el!k3^^ts#]NHUAs+1!<<'!g].<.!<<'!g].<@D1D5$BB?orC$GYID=.@QD=.@QD=.A'=.\O:
+>s/.A(q/nI+9;3:#5]B[kMK9*rVm;nD1DTcrIn+a]MXOap\tH/>FOsB.$i]h#.e$-m>#&ki;Wt'
+61a7fQGrk.F[;J`LL83<rs$&=RdGl;b1$@jmJYc@\kR\PrrC@=T(2jAScI'RrrC@AT(r?VT#Ug$
+ScI'\rrC@AScI(5rrC@AT)[+7Sq-lm!7h,Qg]-#[s7Y1MRK2ZB9n3~>
+nc'[/o^1euf[7jZ]X=o?Tph1)LOa\mDeW`h>#nQu9hYIX*D9+';c[(/A8,t(H@Ud1Pa\;DY-kp[
+b0el!k3^Oos#]ZLV>oC4!<<'!hZ*W4!<<'!hZ*WDDh%M*BBI#sC[1qLDsmXTDsmXTDsmY(<hSX=
+=ulV9(q&hG+TV9:"W2=DhGQ]=rrVV,J,]HOLJkt%;N(8K#.[p-n)l-ah>[\i>+G&;?HM.*"`m$)
+k:)Y7rs!O2SF;8?ahIcZ\QYNlLgJ3PrrD?_ecE0NqZ$VGp]'a`jSo40_Z0[dqu?Eko)H]0o)A]>
+bl@`nqu6YGqZ$VGp&BRCJH47$"P3V(F8tsb"I&oLPY-H~>
+ZMsp]r;Sg:&-+Ge!<<'!hZ*W4!<<'!hZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i"kH!?#ZBjarrVV,J,]HOg1q66GN/>r"oGDZ#RGM,rrr;%2$c@Uhu<iR@gE?]`;^#8
+@l4NT\\8"HqlM^]4h9#@!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+nGb]HnEJoceBQ"J\?W*1SsPRtKn"AiDe`il?!16.;c6Ij;cHh%?"%;ZDfg;TKo;(\Su&Kn\A-&.
+eD'!InCda>3fXmW1o^QUrrCgRs4[PRrrCgRs6XZQs1Uf0;/%G4s*nnQs*nnQs*nnQs7`<E$4'Ah
+s8RZf!&18Mp\tEK70F#rkPbD^m;7@Prrq+l&/KQOpAY<nX>UIqFkm!#qlD[a5e>kQ"SZ=5%!BMg
+"nuF`$p_D;rrr;$2@Mj^df0=7rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+nGb]HnEJoceBQ"J\?W*1SsPRtKn"AiDe`il?!16.;c6Ij;cHh%?"%;ZDfg;TKo;(\Su&Kn\A-&.
+eD'!InC7C93fFUM0s(HUrrCpUs5!bUrrCpUs6afTs1L],:1kl*s*ntTs*ntTs*ntTs7`<D#RF&c
+s8R`h!&:;Mp\tEJ63%9hkPbD^mVdUSrrq+l&/9?JpAY<nXYg@iF56d!qlM^]4h9JM"SZC3#]mra
+"nuLa#X,`3rrr;%2$c@Udf0=4rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+nGaO)o'>Anf?hXV]X=rAU7@O2MM-J*F`;,/A78eL>5hYF>$PBBA8#duFaAOjMNF-oU8Y9']Y_e;
+fA>WUo\4rsJcC?%!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+nGaO)o'>Anf?hXV]X=rAU7@O2MM-J*F`;,/A78eL>5hYF>$PBBA8#duFaAOjMNF-oU8Y9']Y_e;
+fA>WUo[\TnJcC?%!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+nGaO-p$V&&g=+<d^U^\PVP'BCO,AU?HZjFICM79h@fBdV@Uit_CMn09H[g^+O-Q3.Vld;9^rFXJ
+g>V8aqV-T$JcC?%!:Ba>!P2!V!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+nGaO-p$V&&g=+<d^U^\PVP'BCO,AU?HZjFICM79h@fBdV@Uit_CMn09H[g^+O-Q3.Vld;9^rFXJ
+g>V8aqUU5tJcC?%!:'O6!OYON!.b-t!<7P"!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+n,FC'o'>Anf?h[Y]sk8IV4X3@O,AXBI<fsUDf'9)rb3BfCMe!1Fa8CdL5M%WR\6LXZ+%Ebb0eht
+jQlF;gO]BUs+:7NmJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+n,FC'o'>Anf?h[Y]sk8IV4X3@O,AXBI<fsUDf'9)rb3BfCMe!1Fa8CdL5M%WR\6LXZ+%Ebb0eht
+jQlF;eq*jPs+:7NlM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+n,GQMp$_,'gXONi_S!=]Whl>VQ&pr[K7J>pGB@nGEH#o<F*)VOI"6j)N0'<nT;AQl[_0JucIL\/
+kjSEKgO]BUs+:7NmJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+n,GQMp$_,'gXONi_S!=]Whl>VQ&pr[K7J>pGB@nGEH#o<F*)VOI"6j)N0'<nT;AQl[_0JucIL\/
+kjSEKeq*jPs+:7NlM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+mf,EGo'GJqg!\*a^q7"XWhlAXQBI8cL4b#*I!U'`G^4R\I"$X!LPh+TQCFPDWirhB_8a^Jg#(rY
+o`+sGJcC<$K)Yi<rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+mf,EGo'GJqg!\*a^q7"XWhlAXQBI8cL4b#*I!U'`G^4R\I"$X!LPh+TQCFPDWirhB_8a^Jg#(rY
+o`+sBJcC<$K)Yi9rRM"W8q?tn!7:fHIt7TN!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+mf+7*p@.A-h:L&t`PB'mYc=RoSX>\)Nf&XIKS"dSJ/s2mKSG;@NffTpSY;p]YdM'X`QQZ\h;dei
+rVuoPJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+mf+7*p@.A-h:L&t`PB'mYc=RoSX>\)Nf&XIKS"dSJ/s2mKSG;@NffTpSY;p]YdM'X`QQZ\h;dei
+rVuoKJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+mJe+&o^:r&gt'ip`PB'mYcOatT:;45P)kT\MM_=g)2X6/NK96fR%'_CVl[/2]"l;.d+7"3kjJ6F
+rrCf)s+13%rrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+mJe+&o^:r&gt'ip`PB'mYcOatT:;45P)kT\MM_=g)2X6/NK96fR%'_CVl[/2]"l;.d+7"3kjJ6F
+rrCW$s+13%rrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+m/It"o'GPugXXZn`PB*oZEC1(U7[sDQ^*btOoCFZOckonQ^OA9U8FrnZF@H]`QQWYgYq>_p&4mj
+gO]BUs+:7NmJYc?\kR_UJH4'ts*oS"JH4*u"P`t2K)bQ!"I]>VRSA;~>
+m/It"o'GPugXXZn`PB*oZEC1(U7[sDQ^*btOoCFZOckonQ^OA9U8FrnZF@H]`QQWYgYq>_p&4mj
+eq*jPs+:7NlM]97[7YuMJH4'ts*oS"JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+li.drna#>qgXXZo`kf?u['6X2VPBfUS=>rEQku0[S=ZFLVQ$]%[(*fc`ll`ZgYh5\o)AUf!8E))
+JcC?%!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+li.drna#>qgXXZo`kf?u['6X2VPBfUS=>rEQku0[S=ZFLVQ$]%[(*fc`ll`ZgYh5\o)AUf!7l`$
+JcC?%!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+li/d?p@7J1i7li1bf@W9]=5,NXfA=sUnXQUTV%mMTq\?[W2cu(Za[Q]_oU'Lf%]-Flgk#PrrCf)
+s+13%rrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+li/d?p@7J1i7li1bf@W9]=5,NXfA=sUnXQUTV%mMTq\?[W2cu(Za[Q]_oU'Lf%]-Flgk#PrrCW$
+s+13%rrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+lMh\"p@.D1iS<&5cH4&A^:Le\Z*1:1Wi2lqVuN\0WiN8*ZF%*P^;@k3cI1>"iTBIqr;6KogO]BU
+s+:7NmJYc?\kR_UJH4'ts*oS"JH4*u"P`t2K)bQ!"I]>VRSA;~>
+lMh\"p@.D1iS<&5cH4&A^:Le\Z*1:1Wi2lqVuN\0WiN8*ZF%*P^;@k3cI1>"iTBIqr;6Koeq*jP
+s+:7NlM]97[7YuMJH4'ts*oS"JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+l2MLsp@7M4in`8:d*0SM_7mOl\$WKHYl([=Yd(OB\%0,b_8XL>d+$b)iof[ur;-EngO]BUs+:7N
+mJYc?\kR_UJH16$JH2>C"P`t2K)bQ!"I]>VRSA;~>
+l2MLsp@7M4in`8:d*0SM_7mOl\$WKHYl([=Yd(OB\%0,b_8XL>d+$b)iof[ur;-Eneq*jPs+:7N
+lM]97[7YuMJH16$JH2>C"P3V(F8tsb"I&oLPY-H~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+kl2@rp[RY7j58VCe'H7Z`P]L*]XkY`r3m?L\[oGf^r+15bg4bigY_&TmIL5OrrCf)s+13%rrDHb
+gB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+kl2@rp[RY7j58VCe'H7Z`P]L*]XkY`r3m?L\[oGf^r+15bg4bigY_&TmIL5OrrCW$s+13%rrD?_
+ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+k5Qq,oBto*iSE5=e'Q@^aMu08_8*h#^;%Fu_8=.1aNDcSe(37/iT9@mpAXje!8E))JcC?%!:Ba>
+!P2!V!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+k5Qq,oBto*iSE5=e'Q@^aMu08_8*h#^;%Fu_8=.1aNDcSe(37/iT9@mpAXje!7l`$JcC?%!:'O6
+!OYON!.b-t!<7P"!.b-u!!LmQeoUlbec_3;kEJSh~>
+ZMsp]_uBbo!.k0$s2+d9metuC]hX+YJH16$JH2>C"Q'18K`Cc&"IoJ\S5+S~>
+jo5tjo^M52jP\kJf@83oc-+8Na2e2!&]_u7b0/&UdF?e%h;RGYm-siErrCfkrrLjSJcC<$_Z'W'
+rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+jo5tjo^M52jP\kJf@83oc-+8Na2e2!&]_u7b0/&UdF?e%h;RGYm-siErrCWfrrLsVJcC<$_Z'W$
+rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]_uBbo!;HKsej9WJ;WmuXs+gRQ"i3e>/Yr:<rrr;%2%1%;h#@QTXYgMQ\_mDipL=I?F2\(^
+pL?&h6+O]/"oGDZ$phGPrrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+jSohkp[[e=kN(UYgY(3/e'ZOgci25icOS=Le(*('gYUoMkNhU0r:U'igVa$lgAq!J"kQ0K$ruKh
+rrW.SM>dGX^e5.iV"scb"oGAX$kRR:rrr;$1^l^^hu<iR@0dEe`;^#8@5JBZ]"S+IqlDU_6FtVF
+!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+jSohkp[[e=kN(UYgY(3/e'ZOgci25icOS=Le(*('gYUoMkNhU0r:U'if#.Lgh>m<M"kH!G#ZBj`
+s8RlQrrp52$n\:Pp\tEoXYgLuF56d!qlM^a6+PnQ"SZC3&9Gei"nuLa$phG;rrr;%2%2d]df0=4
+rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]_uBbo!;HL%+`li'>!i8hpWe+3J,]HP`En2RPZG3drs#l+LXs`oPhl?D[8)M.G?W,Hrrm0m
+hTd:/`W$-X0o+>(>04MY#.73]eot<>e,KF9rS@Rg:4WCr!7:fHIt7TN!7CiMhZ)Gcs7Y:PS,i#J
+:4N~>
+ir9Mep@@Y;kiLj_hV?l=f[p&P%G07cgYCZDj5oLjme$DJrrCfkrrLjSq#:g#+Ecl)=[E)fpWe+2
+J,]HP`a=ASP#o*drs#o.LXj]nQJMQF[SVb0G?`5Jrrm6rgWq".`W$-Z1l'V*>KX\[#.@?`eTY6?
+e,KF8rS%@a9n<:q!7:fHIt7TN!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ir9Mep@@Y;kiLj_hV?l=f[p&P%G07cgYCZDj5oLjme$DJrrCWfrrLsVp\tXFF6DC`6N@)[c?gje
+rr32A?A%+!<jh]%#.73]f$5G'h>[\e:5@DE>05_&"`#jLc68Fkrs!6nLXpZQahIcZ[8)M.G?W,;
+rrD?_ecE0NJH16$d/a2rJH16$dJsF$s428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!Vh>mTU!3IsU+g(eE!3Ism&80SodUNgs;T8\9InE`M3J13<4h:UmqlMje#ZC-k
+s+D3h.?ji-rsdfbp](9E!<<)aS6ddsrr31aF5m5kf&HH(#)?gIs8S<<h>[\7B&<R0@[Q*R"VABI
+s-,7Wrrs%JhZ(],R(iS)LM#ECa^UXdrrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+i;X5ap@@\>lKIBkio/hQr8%h=i8N\Vk32*tn+6GHrrCgPrrLjSrr4n2!<<'!Xu$8(WrN)!Xu%+2
+A^pb,@1WiE`;fje8QQHcKiJUF\GuU+XuZss<U]tfL)^1AOoY:W%Gq0[s8UOJs8V>R?S$^+rs"O(
+iW&N$j7iQXLM,KDs->Ltrs"6khZ(`0RGe)K&AJ2EQ8HS\"q\N*s2no@^AeCmBAW[2AXV$I!:Ba>
+!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+i;X5ap@@\>lKIBkio/hQr8%h=i8N\Vk32*tn+6GHrrCXKrrLsVrr4n5!<<'!XYBf!XoJD$XYCY(
+B@d+2@h9&H`W,sf8lc?\K2N+@\c;^,XZ6dq;XaYcKGX\<PQ:LY%Gh*Zs8UXMs8VAS?7g[+rs"R+
+irAW$iqNHWLM#ECs-,7ors"6jhZ(],R,IuJ&AA,DPVL/W"q\K)s2e`;^AeCmB&<R0@[PXE!:'O6
+!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]rVloT!<3!Vh>mTU!(,QBHP$5W!(,Q1]g[_NG<*(b??c/DIk@VM=tQ](>''<8XB(kNhF^E?
+KG_,c]bgbDrrjR!p[;TPrVm;oDh%fepNK)%$n\.Hq#:TjF*mfas3:o,rs/.:Hi*j*CP1UG#3Q!\
+s8U@M`r?;,!;HBjk%fUars/.:Hi*j*CP1+9!:KgB!PM6Z!.b-$!.b-C!!M0YhLtq&h?9>Kn!m.'~>
+hZ"JlqXsCImHa'%kND!ijlY^gkNV9tmI0ZAr9sXcg\q-QgAq6Q2VS63rr>@BqgB%Urr>@BmCYoD
+pNJ[*em3Fks*lZ$els](em!4es/oLpiSR3us+VB!n%KbAq#:Qq+G04R@6FMg%..n]s8Vh;78FCG
+UA+H_#P3"^q>^K<%,V!ho5f3Qs5e$MiVs,F!;$6jb7)Dj#Nl*Yq>]PlKtmWmo5f3Qs5e$Me,KF8
+rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+hZ"JlqXsCImHa'%kND!ijlY^gkNV9tmI0ZAr9sXcf)>ULh>mQT2VnH6rr>CBs*G=Wrr>CBm_)&E
+pNJX*g0T!ts*lW!eljZ(elm.ds/]7kind:"s+D5sn%BP<p\tC?K_OqF3W8sdmVdUTs7^_,:(/_I
+p\=ano5f9Us8U@MhZ!iPF*mfak%fV.rs%Wdp](9=#fclLk5b8Rs5n*L^]+Q1F*mfak%fUurrD?_
+ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]rVloT!<3!Qh>mTU!58F4h>mTU!58F4mVdUTlK8!/CN&Y@Ir"?LIr"?LIrFcPH[#5as5!bE
+(o@63!Nc@rrrBb3!!*A^rVm;oDh%femVaPAhN1L6q#:E`Dh%cd!T!h5rs.t1J,fQ:Dh$aG!T!hU
+rrLsV`r?(r!<3!"mVdTirs.t1J,fQ:Dh$79!:KgB!PM6Z!.b-t!<7P"!.b-u!!M0YhLtq&h?9>K
+n!m.'~>
+g]%QYqtK^QnF,f5rpBaR"n1sOp%nXRrrCgPrrLjSrr4_-!<<'!^An5f!<<'!^An6#D1DNKkPOLX
+D=.@QC$GYIC$GYID=.4KGP2"9hZ3*bVZ-SrWW;en!4r.0!=7HYrs\:3J,fQ;D^q45OA2hOrrVY-
+J,]HKgAp+1#OcS\s8VJ'J)UD.hZ3ZU!S[UorrM!Wrr3&eD1B>##OcS\s8VJ'J(+DtmJYc?\kR_U
+JH4'ts*oS"JH4*u"P`t2K)bQ!"I]>VRSA;~>
+g]%QYqtK^QnF,f5rpBaR"n1sOp%nXRrrCXKrrLsVrr4_0!<<'!^&S,h!<<'!^&S-#Dh%fPk54FZ
+DsmXTC[1qLC[1qLDsmLLGPD.;h>m!]V>gJqXT8+q!58@3!=7Q\rs\=6J,fQ:D^h(1OA;nPrrVV,
+J,]HKh>lF4#OZM[s8VM*J)UD.h>mQT!T!grrrLsVrr3&fDh#P%#OZM[s8VM*J(+DtlM]97[7YuM
+JH4'ts*oS"JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]rVloT!<3!Hh>mTU!8dbUh>mTU!8dbUmVdUTeo*9/.<"YSIrFcTIrFcTIrFcCDu0M9ec=;#
+rrL[Np\tC6HhZu43W8sdmVdUTs7:;Up]'AkKD>HOpNLu]s8U@MhZ!iTGC05ek%fV.rs%olp](9=
+#fclLmf<+Zs5n*L^]+Q5GC05ek%fUurrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+fDc6XrVZQhq"X[^r;HWYrrCgPrrLjSrr4D$!<<'!g].<.!<<'!g].<@D1DT8D_aX/D=.@QD=.@Q
+D=.@QD=-e1qZ$]L!8%5M!S7>Hrs&??IIlc14T59gm;7@Qs7()Qp]'>hKD>HOolYQUs8UCRhZ!iR
+Fa<f_kA>q3rs%choDej:%*&;PlN$PPs6"6Q^]+Q3Fa<f_kA>q%rrDHbgB"l[JH16$JH16$TE#,L
+s4`/*p=f_=!:-(JJ,~>
+fDc6XrVZQhq"X[^r;HWYrrCXKrrLsVrr4D'!<<'!hZ*W4!<<'!hZ*WDDh%f<D_XO,DsmXTDsmXT
+DsmXTDsm%3qZ$]K!7q/L!S.8Frrj6dp[;9GrVm;oDh%feo5f-Ms5n*Lq#:TnGC05es3:o,rs/:B
+Hi*j*CP1UG#4DQds8U@M`r?;4!;HBjk%fUars/:BHi*j*CP1+9!:'O6!OYON!.b-$!.b-C!!LmQ
+eoUlbec_3;kEJSh~>
+ZMsp]rVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@srs%Wdp](9E!<)p!mVdUSrs"+"oDdfcL\LfQLMPoLs-th"rs"6oir@88R,IuJ&B=bM
+S2&"_"q\f6s35/C^AeCmCZ>B=Ash'I!:KgB!kh>`JRa7@JRa7@Tjn5^s5&G/p>,qB!:QFQJ,~>
+ZMspZrVloQ!<3!Q^&\35!8IPRgAq9R!8IPRm;7@IH"Z7=Ir4TQIr4TQIr4TQIr4TKH$T5cs7ak>
+*30#<!NH.prs%K`p](9B"TA?%m;7@Prs"1&oDdidL\LfQM/2)Ms.2('rs"<qiW%2;RGe)K'Z9tN
+Si"Fd"r+u6s3>>H^AeCoCZ5<=BpmHM!:Ba>!P2!V!.b-$!.b-C!!M'VgOfJ!gB<rFl^COu~>
+ZMspUrVloT!<3!Q]`A*4!8dbUh>mTU!8dbUmVdULGA$(<IrFcTIrFcTIrFcTIrFcPH[GYis7ah=
+(p3f;!Nc@srs%Wdp](9E!<)p!mVdUSrs"+"oDdfcL\LfQLMPoLs-th"rs"6oir@88R,IuJ&B=bM
+S2&"_"q\f6s35/C^AeCmCZ>B=Ash'I!:'O6!OYON!.b-$!.b-C!!LmQeoUlbec_3;kEJSh~>
+ZMsp]rVntJ!2]_P3<9*Z!8dbUh>mTU!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrrj6\kMB*'rVlreDh%cd#-h3nhMY:>p\tH.>+G'E.?rZg#.[p-mtb;li;Wt%6MKXl
+Pf<Y,F$cDcLgJ3;rs$#;SF;8?aj^7imetuD]hU;5@tA.<A,ifb@tA.<@g(ZghLtq&h?9>Kn!m.'~>
+ZMspZrVntF!2BMN2us!Y!8IPRgAq9R!8IPRm;7@GF_BgO6YYfbIr4TQIr4TQIr4TQW`PeRk?U4M
+L)@Af^*!FNrs&??ETc4Z62gfbm;7@Prs#c3QJIBo[.jS)\m(Wjk9uYPrs$&=RdGl;b2E:'F[>W^
+.$hjP#'E5#m>#&k^AeDK>FOr7?cpjt!:Ba>!P2!V!.b-t!<7P"!.b-u!!M'VgOfJ!gB<rFl^COu~>
+ZMspUrVntJ!2]_P3<9*Z!8dbUh>mTU!8dbUmVdULGA$'S6>PldIrFcTIrFcTIrFcTW)fSSk?9nG
+KG_,c]cdCMrrj6\kMB*'rVlreDh%cd#-h3nhMY:>p\tH.>+G'E.?rZg#.[p-mtb;li;Wt%6MKXl
+Pf<Y,F$cDcLgJ3;rs$#;SF;8?aj^7ilM]97[7YuMJH4'ts*oS"JH4*u"P3V(F8tsb"I&oLPY-H~>
+ZMsp]r;Sg:&-+Ge!<<'!hZ*W4!<<'!hZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i"kH!?#ZBjarrVV,J,]HPqku4T3O/JUrrr;%2$aJ/h#@QTXYgAI\_mDipL=I7F2\(^
+pL?&d4h89+"oGDZ#X,`HrrDKch>t;bJH16$JH16$TE#,Os5&G/p>,qB!:QFQJ,~>
+ZMspZr;Sg<'Eg7m!<<'!g].<.!<<'!g].<@D1DT"64Qk,.#%\ND=.@QD=.@QD=.AtUbW8_:$;QV
+Jf"JAV?$Aj"kQ0G$rQ3drrVS)J,]HPq5,hQ3jAMUrrr;$2@L":h#@QTX>UJP]&3MjpL+I=Fi=:`
+pL,rg5e=Z/"oGAZ$p_DPrrDHbgB"l[JH16$JH16$TE#,Ls4`/*p=f_=!:-(JJ,~>
+ZMspUr;Sg:&-+Ge!<<'!hZ*W4!<<'!hZ*WDDh%f#5n$M$-%l5IDsmXTDsmXTDsmZ"UbN,\9'?6S
+KGX\DV#^8i"kH!?#ZBjarrVV,J,]HPqku4T3O/JUrrr;%2$aJ/h#@QTXYgAI\_mDipL=I7F2\(^
+pL?&d4h89+"oGDZ#X,`HrrD?_ecE0NJH16$JH16$TE#,Gs428kp=9A2!9]S=J,~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7X,/S,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7X#,RK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Wi'PQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)GcJ+ZP=!:QFQJ,~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[J+ZM<!:-(JJ,~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<BJ+ZD9!9]S=J,~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiLhZ)GcoR?rCn!m.'~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiLg]-#[oR?rCl^COu~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiLf)O<BoR?rCkEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Yj`blI4&:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Yg_bQ-st9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y^\aT1Lg8q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';rhZ)Gcs5)W/Du\YsS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';rg]-#[s4c<)D?&>nRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';rf)O<Bs45ctC]DrgPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiPhZ)Gcs5)UNqu?t?hVOb&n!m.'~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiPg]-#[s4c:Fqu?t=gY8.sl^COu~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiPf)O<Bs45b:qu?t;f%-&ckEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs8LjTDuK_:DuSSrS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s8LaQD>jM8D>r8mRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs8LRLC]4;6C];lfPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs8CdUDZF_Sh?9>Kn!m.'~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s8C[RD#eGOgB<rFl^COu~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs8CLMCB//Kec_3;kEJSh~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs8:^RDuAGpS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s8:UOD>`,kRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs8:FJC])`dPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!.b-$!2';phZ)Gcs7Y:PS,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!.b-$!2';pg]-#[s7Y1MRK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!.b-$!2';pf)O<Bs7Y"HPQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Rg:4WCr!7:fH5Cifc!7CiMhZ)Gcs7X,/S,i#J:4N~>
+ZMspZJcC<$K)Yi<rS%@a9n<:q!7:fH5Cifc!7CiMg]-#[s7X#,RK2ZB9n3~>
+ZMspUJcC<$K)Yi9rRM"W8q?tn!7:fH5Cifc!7CiMf)O<Bs7Wi'PQ9m28q6~>
+ZMsp]JcC<$K)Yi=rS@Uh:,d`BJT&tTs/pokJT&tT"Q'18KR`Yi!s%e[:4N~>
+ZMspZJcC<$K)Yi<rS%Cb9f@Q>JSihPs/gihJSihP"P`t2Jq*Gf!s%YU9n3~>
+ZMspUJcC<$K)Yi9rRM%X8i;08JSW\Ls/LWcJSW\L"P3V(F+<jT!s%MK8q6~>
+ZMsp]JcC<$K)Yi=rS@UhNOOK,JaS*WJaT3!!rq,fo619)S5+S~>
+ZMspZJcC<$K)Yi<rS%CbN4+<)JaJ$UJaK,t!rq#`o5t-#RSA;~>
+ZMspUJcC<$K)Yi9rRM%XM7%p"Ja.gOJa/on!rpiRo5aurPY-H~>
+ZMsp]JaS*WK'iX$rS@S"eUd.>mXaeWm[ihHhXT_/S5+S~>
+ZMspZJaJ$UK'`R!rS%@qdt-n;m=FYUm@N\Fg[X;)RSA;~>
+ZMspUJa.gOK'E?orRM"gc[kA4l@J5OlCR8@f(%StPY-H~>
+ZN#L4J_kt7J_kt7J_kt7L>Ds$:4N~>
+ZN#L1J_Pb1J_Pb1J_Pb1L>)`t9n3~>
+ZN#L,J_#D'J_#D'J_#D'L=QBi8q6~>
+ZMsp]c0bV8Dkuh$Y(?$!mJq1amf0Gemf0G@mXaeWmXafNmddUak+#1s~>
+ZMspZc0YP6D5?S!Xb#ltm/V"^mJj;cmJj;>m=FYUm=FZLmIIC]j-i\m~>
+ZMspUc0>>0CS^7qWe'Hnl2YVYlMml]lMml8l@J5Ol@J6FlLL_PhNUW_~>
+ZMss^s3L*8hIZcfVX=QCAq0N*mc*X9blIe(mK;<XJ,cJ8"5[X>p4;X_mXaeWm`t5#K_3(_6LUF>
+J,~>
+ZMss[s3L'7gh$QdVX4K@Aq0N*mGdL7bQ.\'m/u-UJ,cJ7"5IL<p4;U^m=FYUmEY)!K(Qh\60jt6
+J,~>
+ZMssVs3Ks4g113`VWn9;A:O6&lJh(1aT2A$l3#aNJ,cJ4"57:8oRZ:Yl@J5OlH\YpF7d!F3TlW!
+J,~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc6"O-r8
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ3"O$l3
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tt!"N^Z,
+PY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc&"IoJ\
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ!"I]>V
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tsb"I&oL
+PY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc&"IoJ\
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ!"I]>V
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tsb"I&oL
+PY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cu,!,qel
+"IoJ\S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bc'!,_Yg
+"I]>VRSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8u0h!,MM`
+"I&oLPY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`D#-!cJ'W
+rS@[I!:QFQJ,~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bf(!c7pS
+rS%ID!:-(JJ,~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8u3i!c%dO
+rRM+9!9]S=J,~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`D&.!,qi:
+!,qkn"IoJ\S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bi)!,_]8
+!,__i"I]>VRSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8u6j!,MQ6
+!,MSb"I&oLPY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjs\K`BocDu9S?
+Dr0?@!:QFQJ,~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOVK)aT[D>XA=
+D;3g6!:-(JJ,~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hLF8shBC]"/;
+CY%($!9]S=J,~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjs[K`Bocq>gQP
+"IoJ\S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOUK)aT[q>gQM
+"I]>VRSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hKF8shBq>gQH
+"I&oLPY-H~>
+ZMss^s81XV`_$dB(j#]5qu?p]^#%Ua?HrK+#gH[ohJZ`FhJ`An!sBp'df&#)]hSS-r8.;N!%G51
+"2.HZmY9R!X?HF\"&>q(Ds?*[S,iTeh>hKm!!jQkc/*AFc/*C<!!<?MK[ThU"2.HZs8:aN!!"J.
+h?%V%c/7@Y!583b"2.HZmetuBDu9S9'SG?#r;Zm)6H8*C!mSCYo\KV^!.j!XhLXOgh>r<0p>,qB
+!:QFQJ,~>
+ZMss[s81OS^.A_5*-(u4r;['*34dl!D-tNdgBc#1D;/o7bhI"6!!<?NJ^")I"1h2,s8:XK!!"RU
+gB5#]J*i!F!NJ9Z!!?$"?Z#&^!h',hr7_3grW!6+*dPo_D-tNAD>jM;"=A]DrS%Fc9n33@g\UsN
+/E>IdD-tNEgAq;gq:c"_9n2R/gAl*g!!*jfi7n21!XM6/jP'a[^&[f[!PSPbgO\+1gTfK6K)bQ!
+"I]>VRSA;~>
+ZMssVs81@N]h/P1(j#]-qu?p][FWoE?HN2t#g$Cgen\U6enb6b!sBp"ao0cm[7UH!r7:`F!%G5)
+"1:aNlA!jjW'1"X"&>q(C['COPQ:a]ec9La!!jQg`R\g2ajt8,!!<?MJ'%Z?"1:aNs8:IF!!"J.
+ecKVnaktYM!583Z"1:aNlM]96C]"/5'S#&lr;Zm)6G;I2!m/+Uo[X&V!.i^Peq)DWecBjlp=9A2
+!9]S=J,~>
+ZMss^s8:^g`Xl=]`f(IEhVJ77cHa*i.Gip"?HrK+&C"O"hJZ`FhJZH.b.2jNDq=pE"2.G0s8:^S
+!3Q1EkhZAbCXUMb"2.HZmY9R+g="9[<bK_'f%-@el.uK3!<;uR'lR-dcGb8jKALNQc/*A>]umm4
+/T95>h?1GdJ,fH'!<B8"cM-/r&B=1q!cMDij5'qN`noPP^%pLe]hX(FrS@To<k\IW!7pAj!>*9J
+h?X+`cGltY&C/khh?)9RC\QZg&B<SPCOt>nhLXOgh>r<0p>,qB!:QFQJ,~>
+ZMss[s8:Ud`tV[^_i>:BgY2_.a2bVW.,3Kn?d/N(&BnKugML<AgMKs#a1?[OCXN.9"1h2,s8:UP
+!36"<!6aT\!d//"cJ&H49n2PbgC)WXa1,,Za2cNRR%W]u!h',hr7_s'<Og)`I5ZZ2D-tNAD,n*d
+\pZ2HdJhl&\kR\Sr7_5PWr9s<bP0`l&AIVf!c;;gj4a_K^>%BB^A6Lc\kR\ArS%Bj<Oi%K!QigS
+gAql"qqDAVWlN/_9b>@mk1]sdb@UG&";&<%b@Q7ZJ_Pb1Z.f;2s7Y1MRK2ZB9n3~>
+ZMssVs8:F_]b")D]o3M<f%'ht`l>DQ.G!'c?HN2t&BS6oen\U6en\0k`jpFJCX2q1"1:`$s8:FK
+!2]V5kgffVB$&?L"1:aNlA!jtd`TS;;Id_dcH_ZEl.,p#!<;uJ'l-^T`k?^VJ(ACAajt6*[Dob(
+/SiZ2ecW<PJ,fGt!<Ato`qS$b&A@P`!c),aj44AF^"1a7^%p4][7Yr6rRM$c;RQJC!7'fZ!>)sA
+ed)8P`l>,Q&B<#XecO.:A,"OW&A?Z7@tE3^eq)DWecBjlp=9A2!9]S=J,~>
+ZMss^s8:aR;Z5GUN!S:s!58Bg#0m4oeo+m>rn\",?>n\=?Hq>F?HrK+!fKgHrn[aj:&t=lh>mVi
+j5'iU?HpdP"2.HZmXs?tc!G>Kh?'2Is8:^aDdL]FhUZ=Peo+m>hJZ`Frn[^7:8%UC"2.HZs8:^S
+!57s[!<Bh%h?%V%c/[Xa!577G!583b"2.HZmetuDDdL]Kh>mViqq_>R^&?dh3Fe`8h>mViJ_kt7
+J_mQd!JLLHh?9>Kn!m.'~>
+ZMss[s8:UP;,.#D"c<T;gAntegBPh$a3ea2bl6?(b[55AD-tNAD-tNdgB*:,SGq7F\kN2)r7_5P
+^>mrLD-tN4gB5#]J*hmC!mG"gj4aX(!<;uO%rG[tgY:1gA'o.#bhHuAbl6>uMbKZ?gB5#]J,fH$
+!<Bk)gAq;gn(Rn\?d.Qb"TZ9kgAnt`gB5#]J*m3h!c;;gj4aS7^AHXc!5AEd!^'bYg"QN-^4G$i
+gO\+^gAup+p=f_=!:-(JJ,~>
+ZMssVs8:FK;G-o="cN`<ec<D_ecs+o`m/@+ao9iua^/c6CL5-6CL5-^ecLUuR/YY=[7UH!r71lK
+^#RZFCL5-.ecW<PJ*M[;!m+baj449r!<;uJ%r5Lnf%/,VA'Sjrajt66ao9imLImm4ecW<PJ,fGt
+!<Bh(ec>can(%PU?HM6Y"TZ6eec<DZecW<PJ*R!`!c),aj4452^&-@]!58?^!]aGOg"$0(]n+ac
+eq)DTecBjlp=9A2!9]S=J,~>
+ZMss^s8:^S#dsTe"NK<T!58Bg#0m4gdViI:rn\",?>n\=?Hq>F?HrK+!kDKarn[aj:&t=lh>mVi
+qq_??>5m@o.<F@s=pPC+cIUij8mW2?<k3Pc#ZeXbh?1GdJ*qsG!mP%irn\+/?>n\=!.,O_@tYBn
+A,b<geli=b9$[Cl!h98jr8%s&?Hq?`en8L@DdL]FDdL]fh?(5kJ,\:,]hX(Wr8%GS^&$S%!0eo4
+(mNko!"b[W!0e<lDcW+ZhLAS6rS@To?HrE),2/D=#Ut_`hVJ6s.0(3LhVNSr!%Ej,hA?5(SDF7!
++TN@DrS@Xi:4M^1h?%V%c2?E;OA;>&hLeS%g6aT##YND!h>ich!#UsW(]Y,;r8%GS^&?eQPTbP5
+g6aT#.?)j7\QTOQ:9iZO4U<$Sc/*A2<_8gp!8bBhPSaBecJBB<&=gE6hVQOM#RFVbhVJ6s.231k
+\UiUghLXP#h>r<0p>,qB!:QFQJ,~>
+ZMss[s8:UP#d4-\"kUZHgAntegBPh$_p<1,bl6?(b[55AD-tNAD-tNdgB+lhIK%t'\kN2)r7_5P
+^AHXc79TWE(+=1Wdo?e^8^#T;D+e:S%TTr_$j]kEceAQ59n2P_gB,T+D>r9!b[55AD#eu$"D*/r
+"C_;a"k-H[#YE5<gB*fDs8:U^D-tNAgXB_BcY[%5gML<Arn@La>CHM*"1h3Vs8:UP!5A<a(BBaP
+";m<V(]Y,9gAmBR7Vc"egY7-VZMiMZD-tNbgEP760FB4ce(`UWQ7N.UP2"`:(]Z+I!8A=j&=V>R
+L*Qm=P5X,;\kR\ArS%Bj?d/H&)j!jagY79QVUq%d$j]GJgY2^o/-HfQgDBo%Rf(n@!5AEd5aEO@
+gXhZD$7Le\gU(#n$r=+^U-&c(Hd(5]8QA6J^&Zp%!0.`r7EaF&!"bU5!8H8O8I,`-fA#$[Q7Nj_
+<ORJ5J_Pb1_V5*Cs7Y1MRK2ZB9n3~>
+ZMssVs8:FK#d+$U"MNC;!58B_#0$YVa_P5)rmhFu?>J,-?HLc6?HN2t!ju'Qrmh1Z8c\nhec>ca
+qpkd7;Z>5_.<F(c;@!P#`m3.N8mW2?<jd,[#ZA(VecW<PJ*M[;!m+barmhP#?>J,-!.,O_@s\ae
+A,b$_c;FoR9#gh\!gE]br72Bo?HLdLc=:2&CL5-6CL5-^ecN6[GQ-.q[7YrKr71lK^&$:r!0eo4
+(mNSg!"bCG!0e<hCJp,BeoslkrRM$c?HN,r,1;Q)#UtSTf%'hc.0(3Lf%,0b!%Ej,eeeAuPh#hf
++TN@DrRM(Y8q6.)ecKVnao'^/N(T>cepgGjdZ?$d#YN+fec:p`!#UsO(]Y,3r71lK^&?MIPSeVq
+dZ?$d.>Z:#Yu1u99!-[73=$UOajt6"<^iCh!7ng`N">tU`mtt,&<sj.f%.i-#RF>Rf%'hc.231k
+[=Qn[eq)DhecBjlp=9A2!9]S=J,~>
+ZMss^s8CdU`W4Tch?s=kf%.i5+l;'o?HrK+$I)mqhJZ`FhJZ`Frn[_$?>oi""2.G0s8:^S!4DaU
+)r?ejhVPpGcJDGk`l:#!Mr&@lJ't,QF5ChAc-G/J]hX(FKAH[S?>oi"(<p0(hJWBlesl_4esl`c
+hVM.&`l:#!rS@UG!<;uR%rYXjf$9(/J)5*Mc/*AFc2QQ$c!G>fh?1GdJ,fH'!<BP*f)OSC!'/'U
+CC&eR!577G!&:"O]io@.`EI36rS@To?HrE),+),]`d^",hVJ5m`nkJ:hKp*9eu^(qhVJ7GhVJ5e
+`nkbBrS@Xi:4M^1h?%V!`Vn@,g::+*hT]A>esK3g`l:#!hVJ5m`nkJ:hVJ7Gqq_>R^&?eQ]`<!-
+QqiIWIlWG<B1fSB:2?Y#F2a)$LYcqdB!oUk!8bBh3QA`e6JgQ!^#$F&hVLRZ`k<g2hVJ5m`mUYC
+F+N2!hLXP#h>r<0opc*an!m.'~>
+ZMss[s8C[R_Z80]gC""ee'l3/,hq'j?d/N($HujogML<AgML<Arn@Lq?#T_s"1h2,s8:UP!4)RP
+*7rr2&DPsJ!6<hk8]/8)4H%s2)LK`'4EK7o?d-gM"1h3Vm=X-pb[55dgD8"?D;/n-;:D*::",O2
+a4o?G8]/8)4T4"9RK3BcgCJ.(_UH\a3.K\"?d.8A?d/N(!m"Ycrn@Od9n33@gAq;[rR2\:gY2]b
+_q/`6gY2_BgY2]ZT!Z.7D:cX-D:ea@!c;;gr7`E]9npH34H%tK!&VUFD%,0I(oGWV+9:0N!5@4B
+!&2=FE=Dg#"1h3VmJYc@D-=aTdi?ok\5RP)aBN0%Q;*+O^-"O4gAj(Jf51rNgAntbgAq;grS'TG
+"E3%\9npH34H%a&9=2-%B:qq<_Mg[4gMI^;[)BZYgV*YM^:H!egY2_BgV*[BgI46B\gV.EgAj(J
+c([=AJ_Pb1J_S&r!J:@ERKEQURSA;~>
+ZMssVs8CLM]`?@RedDJ[cHa*q+kG4[?HN2t$HZUien\U6en\U6rmh.i>&4,g"1:`$s8:FK!3Q1E
+)qL5bf%.5/`n"$[]tHEdLXp5XGKHL<Dq8]1aj/H>[7Yr6K@U+G?>KPk(<KluenY7XcC=l,cBJ=K
+f%*_k]tHEdrRM%7!<;uJ%r54ZcGbDnHe)t=ajt66ao9im`EI'VecW<PJ,fGt!<B8"cMuH3!&;1<
+CC&MB!56t7!%FGC\QWds]iJpsrRM$c?HN,r,*YiT]mDbpf%'gU^"-s)epA71cD;?Xf%'i7f%'gU
+^".61rRM(Y8q6.)ecKVf^&?4qd^;tof#:g&cBM(V]tHEdf%'gU^"-s)f%'i7qpkcJ^&?MI[/b!n
+PYQkEHT?l0B1fG::1p(dCV>NeK@XfP@^3b_!7ng`3PDgT6Is]f^"0jsf%*/J]sT;!f%'gU]ucp-
+Dh6Jjeq)DhecBjloooOYkEJSh~>
+ZMss^s8CdU`W4TchY[?X0tlH#DdL]fh?qM6Dr,D=c/*AFc2QQ$c!G>fh?1Gd!<;uRqZ%U>hUVt/
+hJ5I7ec="PhSoP.eo+I&hT]AFhJZ`FcJAZ::4M\ah?(r.DuST0c!G>FDZI3%h>jt?h>k7Gec="P
+hSoQ@rn[^H!<;uR!,qf9$5e!3hJZ`FhJZ`Frn[_$?>oi""2.HZs8:aN!"`>jh>jD/hRrpGh>k7G
+h>j)Fh?A7,\XZ]fr8%Kn?HrH*'&%,6f&"hbB@bo>V;C(B!8\QWrn\*K!8cQ4^#%TGV;C(B!<(aV
+]hX(FrS@Nmqu@]gSD%m^_5(+ng1t?PhVQ6PcJAPthVPpGhVJ7Gqq_>R^&?dt]`<!)CM25TdUQq8
+B1B0*g+I_U^#%>>Z/0Co^#%#I!8bBh^#%VR!7p!,^#$F&hUV\?hVOb>hVJ7/hVQL`Dh6brhLXP#
+h>i6#!!;VZ:4N~>
+ZMss[s8C[R_Z80]g\_$U0Y6#nD-tNdgBu/3D;/o7bhHuAbl6>uaB```gB5#]!<;uOqZ%U=gXck.
+gM'+2df@SGgV*Z#eSS0tgWEf=gML<AcJ&H49n2P_gB,T+D>r9+b[55AD#glrgAnP6gAntBdf@SG
+gV*[6rn@LC!<;uO!,_Z7$5dp.gML<AgML<Arn@Lq?#T_s"1h3Vs8:XK!"`;fgAmu&gU[C>gAntB
+gAmiEgBDk(\=?Wdr7_9i?d/K''%^i/e(`)RB@Y`:U>+G6!8AKZrn@mJ!8H6.^>%BBU>+G6!<(XS
+\kR\ArS%<hqu@]fRb;[^^7n\jf4egFgY9FBceAGogY9:>gY2_BqqD,O^AZdr[KLO#Bk>cJb[5#/
+Bh,?*f.M>O]%bW0YhO"j]\CZE!8G3f]%buF!7T[&^>$@%gX?/6gY8/6gY2_&gY9kVD1UGmgO\+r
+gAlis!!;JT9n3~>
+ZMssVs8CLM]`?@Rf),LP.CIaXCL5-^edBN*CY!9-ajt66ao9im`EI'VecW<P!<;uJqZ%U6f$4Pk
+emh%tc2bl8f"D&nc>-1cf#:g.en\U6cIN**8q6,YecNs"C];m$a^/c6CB1Kfec;i'ec<D7c2bl8
+f"D('rmh.8!<;uJ!,MN5$5@Eten\U6en\U6rmh.i>&4,g"1:aNs8:IF!"`&Zec;5kf!PM/ec<D7
+ec;6>ecg7u[?t!Zr71pb?HN/s'%1E&cIU*DA'WX*SCZ9!!7i!OrmhOC!7o^$^"1a7SCZ9!!<(IN
+[7Yr6rRLsaqu@]cPgX>F\XZQVdV!(8f%.M7`mt-[f%.5/f%'i7qpkcJ^&?Ll[/b!jB4K6<a^/Js
+@n*U"dOo`E[FWX"Xk%8_\^nm9!7ng`[FWp2!7'-q^"0jsf$49'f%-&sf%'hkf%.fDCOt&feq)Dh
+ec9d_!!;>J8q6~>
+ZMss^s8:^S#d+'^"kG-)h>k7ch?%V%c2QQ,c!G>FDdL]FDdL]fh?(5kJ,\:,]hSS-r8%GS^&$Ri
+>#O2oSDM9_!"<2YDdL]Fc!G>FDdL]6h?1GdJ*qsG!mP%irn\42?>n\=!577G!577G!577/qZ$W0
+rn[^H!<;uR!cMDiqq_Nq?Hq>F?HrK+!kDKarn[aj:4N<Ah>mViqVDY]^#%VZ!8cQ4^#%TG^&Hjl
+TN7;$>/C-n!cMDirS@S'A,H<7?Hq=,^#%VZ!8[^hrn\*t!8cQ4^#%TG^#%VZ!<(aV]hX(FrS@To
+?HrB(#Fnh^HWn,2A,?66^"rb&hVPpGhVJ7Gqq_>R^&?djPTbP)A,H<6?Hp<-.3N69DdL]dh?e+,
+c/-^Y!8bBhrS@k]`ng^/hRrpG`W6"p$G?Grh>k7GhT]AFJ_kt7J_n9#!/1"E!s%e[:4N~>
+ZMss[s8C[Rf*JPXgBH%WVV;*bqV)'g?-<0$$HcXkgML<AgML<Arn@La>CHM*"1h2,s8:UP!5A<a
+s&B3V(n03sqZ%%1b&(G,gWX#AgML<AcJ&H49n2P_gB,T+D>r9$b[55AD#h<)gAntBgAntB_tsE6
+])LFcRK3BcgB)5!bkp-!D-tNAD-tNdgB+lhIK%t'\kR\Sr7_5P^A?Rn!4pq>^&ZpB!5@4B!4r0a
+"e\qYF'HHXgB)5!bl-8scXH_O$XLp0!4pq>^&Zmf])LFn[K,(:!5@4B!4pq>^&\,d"1h3VmJYc@
+D-tNagBX*GR!DiGcXH\N$bG'm]%buR!8H6.^AHXc!5AEd"I:0YcXH_O$=1fgE@;r@\nt`qr7_Np
+?-:pG^&Zp%!<1^\f)WP>!5@4%!8GBkrn@dk!8H6.]%bu`?YtAKJ_Pb1_V5'Bo`#!nl^COu~>
+ZMssVs8:FK#d+'V"jSQnec<D[ecKVj`W"Eq`EI'.CL5-6CL5-^ecN6[GQ-.q[7UH!r71lK^&$=[
+;?YPfSCYCN!"<&MCKe^.a^/c6CL5-.ecW<PJ*M[;!m+barmhY&?>J,-!56t7!56t7!56ssqZ$W(
+rmh.8!<;uJ!c),aqpkse?HLc6?HN2t!ju'Qrmh1Z8q6m=ec>caqUQ)U[FWpB!7o^$^"1a7[Jn_\
+S5t_m>.sjb!c),arRM"k?Mjd2>/f%m[FWpB!7h.XrmhOd!7o^$^"1a7[FWpB!<(IN[7Yr6rRM$c
+?HN)q#F&,NG?VQ!?Ma^1[FP>cf%.M7f%'i7qpkcJ^&?LbPSeVd?Mjd1>/e$j.3N*-CKe^Ted6+q
+`R`/E!7ng`rRM;U^"*1sf"D(7]`A&_$FKlbec<,/f#_66J_#D'J_%]h!-@f4!s%MK8q6~>
+ZMss^s8:aR9)[TMMu_/[!586c!d@harn\!q<d3D=?Hq>F?HrK+!fKgHrn[aj:&t=lh>mViqVE*l
+&>^6#hUV\XhVQhkakgrBc/-]ODr,D=c-G/J]hX(FKAH[S?>oi"(<p0(hJWD-hVJ7GhVJ7GhUV\X
+hVQhkrS@UG!<;uR!cMDiqq_Nq?Hq>F?HrK+!fKgHrn[aj:4N<Ah>mViqVDY]^#%VZ!8cQ4^#%TG
+^&Hjka^._CHi)Y$DdL]eh@eOXCYIY!`Q?un!577G]`?n+PlBMKPQ9Rs!577G!577G]`A#f"2.HZ
+metuDDdL]chAO:=>$cR4g1tKXhVQhkhVJ7GhVPpGhVJ7Gqq_>R^&?eQ3Fe`9CMVY\g;V1f_8Y9E
+:1nKG^#%>-T\aTnc/-^Y!8bBh^#%VZ!7p!,^#$F&hUV\?hVOb6hVJ7GhVQL`Dh6brhLXP#h>r<0
+p>,qB!:QFQJ,~>
+ZMss[s8:XO:&WfMNW@8W!5A<a!d.Y[rn@dk=*ND9?d.8A?d/N(!fKaBrn@Od9`Y4kgAq;gqV)mb%
+&+TngX?/KgY:2_`nP?;bhL?KD;/o7bg+rF\kR\AKA-IO?Z#es(<g-&gMHr)gY2_BgY2_BgX?/Kg
+Y:2_rS%CB!<;uO!c;;gqqD<l?d.8A?d/N(!fKaBrn@Od9n33@gAq;gqV)GZ^>%DV!8H6.^>%BB^
+Acji`a);=H2H=tD-tNcgCi+PB@Ybg_T(?b!5@4B^&Zn%QN#VJQ2o[o!5@4B!5@4B^&\,d"1h3Vm
+JYc@D-tNagDRe0='^++f4emJgY:2_gY2_BgY9FBgY2_BqqD,O^AZeO4C+K/BkPuNf>>PZ^;AX99
+kA6G]\ChsSD.mfbhL@U!8G3f]%buJ!7T[&^>$@%gX?/6gY8/2gY2_BgY9qZD1UGmgO\+rgAup+p
+=f_=!:-(JJ,~>
+ZMssVs8:IJ9)[<EMu^lK!586[!cqDQrmhFa;KLE)?HLc6?HN2t!f'@7rmh1Z8c\nhec>caqUQO\
+#b2a_f$49@f%/-K_:EC.ak"R?CY!9-aj/H>[7Yr6K@U+G?>KPk(<KluenY9!f%'i7f%'i7f$49@
+f%/-KrRM%7!<;uJ!c),aqpkse?HLc6?HN2t!f'@7rmh1Z8q6m=ec>caqUQ)U^"1cJ!7o^$^"1a7
+^&HRc_-0H/GPfqmCL5-]ee6DDB@>AZ]tr:N!56t7]`?UpPlB5CPQ9:c!56t7!56t7]`A#^"1:aN
+lM]98CL5-[eeu/%;He:qdV!4@f%/-Kf%'i7f%.M7f%'i7qpkcJ^&?MI3EhfuB4oZDd_3KF\\6S%
+8n2X;\^o&fR+?%Zak"SI!7ng`[FWp:!7'-q^"0jsf$49'f%-?&f%'i7f%.rLCOt&feq)DhecBjl
+p=9A2!9]S=J,~>
+ZMss^s8:^]`Xl%U`f(15hVJ7GqVE!d796P1WD5m`hJZ`FhJZH.b.W9VDq=pE"2.G0s8:^S!3Q1E
+rn[\n+`%)6s%3jBc;HBPhJZ`FhT]AFhJZT>cJAZ::4M\ah?(r.DuST/c!G>FDZIK-h>k7Gh>k7G
+hF^D[c;HCqh?'2Is8:^TDdL]ch@+=/c/*A>]un$</T95>h?1GdJ,fH'!<B8"cMu`1!577G]`?pG
+!4C\?!58?f"+(_FV#0!MDcXRNc6UutPY-bSO?nZYh>k7GhRrpGEu;%1XW[]$h>jt?h>k7GhRrpf
+h?1GdJ+!9l!cM,QrQZA5hVNT!7\nntPY-bOc;HCRh>k7GhRrpGh>jt\hF7LIcGm7a&C/k`PY-bS
+O?nZUDcXQZ8o((lF2a)$LYcrUc/-^Y!8bBh3QA`e9&AD)[GJRshVLRc`k<g2hVJ7GhVQL`Dh6br
+hLXP#h>r<0p>,qB!:QFQJ,~>
+ZMss[s8:UZ_[o\J_i>.2gY2_BqV)d]6;shuUeaCWgML<AgMKs#a1?[OCXN.9"1h2,s8:UP!35t;
+rn@Jk+Dq,4&kPg8a&+[KgML<AgWX#AgML09cJ&H49n2P_gB,T+D>r9*b[55AD#h<)gAntBgAntB
+gIY,Wa&+\lgB*fDs8:UQD-tNagC.q+bhHu7\Au1//o/l6gB5#]J,fH$!<B.ta8am'!5@4B^&ZpB
+!4LY:!5AEd"+(kMV#/mJD,n+Fa!B'eP"UVMN'`<SgAntBgV*[BFVq"%WZV;rgAn\:gAntBgV*[d
+gB5#]J*m3h!c:rIrPol)gY6un7\nenP"UVKa&+\JgAntBgV*[BgAn\ZgI;1Ca2b>W&BE2QP"UVM
+N'`<MCK7sO950haEPdYuL"gHObhL@U!8G3f352s\7GHPs[bJLrgY5.Z_n%7-gY2_BgY9qZD1UGm
+gO\+rgAup+p=f_=!:-(JJ,~>
+ZMssVs8:FU]b!f<]o35#f%'i7qUQFT5uOMlUeX4Oen\U6en\0k`jpFJCX2q1"1:`$s8:FK!2]V5
+rmh,f+`%).&jf4(`_%t<en\U6f#_66en\I.cIN**8q6,YecNs"C];m#a^/c6CB2'!ec<D7ec<D7
+ej<!B`_%uaecM'9s8:FLCL5-[edQ>#ajt6*[Dob(/SiZ2ecW<PJ,fGt!<Ato`rFU!!56t7]`?X7
+!4CD/!58?^"*YGBT_m:ACJqS>`[&j\N(/H9LcpCAec<D7f"D(7Eu:b!V',iiec<,/ec<D7f"D(^
+ecW<PJ*R!`!c(]ArPff%f%,$b7\J>`N(/H5`_%u:ec<D7f"D(7ec<,Tej]Y9`l>,Q&B<#HN(/H9
+LcpC=CJqRB7VA)XDnUriK@XgEak"SI!7ng`0tjtL6Is]f[FW"kf%*/J]sT;!f%'i7f%.rLCOt&f
+eq)DhecBjlp=9A2!9]S=J,~>
+ZMss^s81XV]g;u)(j#]5!<Bh/h@6_j'EAhN[GKbY?Hq>FrW!$'-%F2<h?1Gd!<;uRq>^]MhVN#J
+`r=g.ek-2R6H7I1DdL]Fc!G>FM]>L*ce\c;:4M\ah?(r.DuST/c!G>FDZIK-h>k7Gh>k7GhUY:)
+#XZQ0h?'2Is8:^TDdL]ch?7b'c/*C<!!<?MJ'IrK"2.HZs8:aM!"[Z;!577G]`?pG3<5T+!58?f
+"/Ieadehl$Du9S\B@bdu.0q5Qdb`g\^#%VZ!8cRZ(]Z"L!8cQm!1_mG^#%VZ!<(aV]hX(FrS@Nm
+qZ%UOg>8V_A('5jg5m`h#XZPfh>k7GhRrpGhDkS+r8.AP!XM-+rn]ckO=:G]K[S_b:'_8/\_`u>
+#TS?BhJZ`FhT`_6hRro9&-,>JhVL6mS@npZhTe_!#[5g9h>k7GhT]AFJ_kt7J_n9#!JLLHh?9>K
+n!m.'~>
+ZMss[s81OS^-rG1*-(u4!<Bk0gC:;c('GIYZJ4,N?d.8ArW!$'-@sD>gB5#]!<;uOq>^]JgY6EB
+_uAC(cV4ZN6-%C-D-tNAb[55AM&oI(ceAQ59n2P_gB,T+D>r9*b[55AD#h<)gAntBgAntBgWrS"
+#XQN0gB*fDs8:UQD-tNagB;A#bhI"6!!<?NJ^")I"1h3Vs8:XJ!"[Q5!5@4B^&ZpB3!>])!5AEd
+"/7VZbkp,pD>XAZA^f1i.L7;QdG*CU^>%DV!8H7N(]Z+I!8H6f"Ie'F^>%DV!<(XS\kR\ArS%<h
+qZ%UMfA!#V@F*]_eW)*b#XQMcgAntBgV*[BgGf>)r7h/M!XM6/rnBQcN[b;[K[JPY9aVA3[b7*+
+#TeE?gML<AgW[A3gV*Z9&-PSNgY4[jR_AdVgWN"k$sD3:gAntBgWX#AJ_Pb1J_S&r!J:@FgB<rF
+l^COu~>
+ZMssVs81@N]g;u)(i0-%!<Bh/ed\QQ&-*DFXk)'=?HLc6rW!$'-%F&8ecW<P!<;uJq>^]Ef%+=2
+^&HRrc:S?J6G:LlCL5-6a^/c6K,@4gcdi3+8q6,YecNs"C];m#a^/c6CB2'!ec<D7ec<D7f$6kn
+#XZ6'ecM'9s8:FLCL5-[ec]bpajt8,!!<?MJ'%Z?"1:aNs8:IE!"[B+!56t7]`?X70`[Hh!58?^
+".V)PansWhC]"/XA'WM].0q5Lak##C^"1cJ!7o_B(]Z"D!7o^U!0l%7^"1cJ!<(IN[7Yr6rRLsa
+qZ%UKdajpC?HLdLdYoU\#XZ5Uec<D7f"D(7ehI/hr7:fH!XM-+rmj3[N%##YJ'$9D8dGi'Z.>9s
+"<;d1en\U6f#bT*f"D'1&-,&:f%)PUPe@(Jf#C#^#[5O)ec<D7f#_66J_#D'J_%]h!H\;7ec_3;
+kEJSh~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,eKa!j#FXina^+[Jo"`S/CeQ"2.HZm]>7G
+]`<W?J_kt7V;;6+s7Y:PS,i#J:4N~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,eK^!if:VinFL&[f5"^Sf%"P"1h3VmB#%C
+^&W`=J_Pb1V:u$&s7Y1MRK2ZB9n3~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,eKY!i/_Himn-p[Jn_XS/CeI"1:aNlE&P;
+]`<W7J_#D'V:GZgs7Y"HPQ9m28q6~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,eNb"4hZs[Gp$ICFQsR[4,VUh?1GdJ*sDp
+!PJJahLXO7hPK'0K`Cc&"IoJ\S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,eQ`"PM+B<O1W=#&,KogU8M=n_4/W9n2Q3
+gB#"gJ_Pb1J_R$U!J:@FgB<rFl^COu~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,eNZ"3tscXl@n9CE^+:[4,VUecW<PJ*O,d
+!PJJaeq)D'etppuF8tsb"I&oLPY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,eQc"3":ePi1C%@h8VWA(L2,"2.HZm]>7G
+c;K5MJ_kt7V;;6+s7Y:PS,i#J:4N~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,eQ`"Mdq[NnNFH#1m8t!#/knn_4/W9n2Q3
+gB#JtJ_Pb1J_R$U!J:@FgB<rFl^COu~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,eQ["2.SUN8W7j@h8VOA'XVq"1:aNlE&P;
+`_qB=J_#D'V:GZgs7Y"HPQ9m28q6~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc&"IoJ\
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ!"I]>V
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tsb"I&oL
+PY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc&"IoJ\
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ!"I]>V
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tsb"I&oL
+PY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc&"IoJ\
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ!"I]>V
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tsb"I&oL
+PY-H~>
+ZMss^s3KO(]hSS-VVVEg:4M\_hW!AnS,iTLh?1GdJ,cJ("2.HZmXa5GhLXO7hTjsYK`Cc&"IoJ\
+S5+S~>
+ZMss[s3KF%\kN2)VV;3a9n2P]gZ$rhRK3BJgB5#]J,cJ%"1h3Vm=F#CgO\+1gWnOSK)bQ!"I]>V
+RSA;~>
+ZMssVs3K6u[7UH!VUbjW8q6,Wf&G6^PQ:aDecW<PJ,cIu"1:aNl@IN;eq)D'f$;hIF8tsb"I&oL
+PY-H~>
+ZMss^s3@,9:&t<jS,uH8c%2DDS,iWiig^'FJ,cF:!`"6iJXh:]JXh:]cC=ogs7Y:PS,i#J:4N~>
+ZMss[s3@&79`Y3iRK?35b^l5ARK3EgigKpCJ,cF8!_n0gJXV.YJXV.YcC+ccs7Y1MRK2ZB9n3~>
+ZMssVs3?i18c\mfPQFI,aao]8PQ:daifjL:J,cF2!_RsaJWt_MJWt_McBJ?Ns7Y"HPQ9m28q6~>
+ZMsp]JH16$JH16$JH16$JH2#:!JLLHh?9>Kn!m.'~>
+ZMspZJH16$JH16$JH16$JH2#:!J:@FgB<rFl^COu~>
+ZMspUJH16$JH16$JH16$JH2#:!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLHh?9>Kn!m.'~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@FgB<rFl^COu~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLHh?9>Kn!m.'~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@FgB<rFl^COu~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLHh?9>Kn!m.'~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@FgB<rFl^COu~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLHh?9>Kn!m.'~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@FgB<rFl^COu~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLHh?9>Kn!m.'~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@FgB<rFl^COu~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLHh?9>Kn!m.'~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@FgB<rFl^COu~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;7ec_3;kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!JLLGS-&c[S5+S~>
+ZMspZJcC<$JcC<$JcC<$JcD):!J:@ERKEQURSA;~>
+ZMspUJcC<$JcC<$JcC<$JcD):!H\;6PQLpKPY-H~>
+ZMsp]UAkCHDsi*nmXbChs/5l!W%ir%f`),)Dsi*nmeZqbmVdUQrrVV,J'7inmVdUQrrVWF!/(:Q
+c4G&Js+14+rr@`D!!;VZ:4N~>
+ZMspZUAkCHD=)gim=G:gs/5l!W%`euf`),)D=)gimJ?ham;7@NrrVS)J'7inm;7@NrrVTB!/(:Q
+b7JfIs+14+rr@ZB!!;JT9n3~>
+ZMspUUAkCHDsi*nmXbChs/5l!W%ir%f`),)Dsi*nmeZqbmVdUQrrVV,J'7inmVdUQrrVWF!/(:Q
+c4G&Js+14+rr@-3!!;>J8q6~>
+ZMsp]r;Qoo@gEWeXT&HRDsi*nmcaZO&DlOKs+gUR%K!7b$phH(s7bt[#S;(Vrs[IF!!lKks8VOc
+#S;(Vrr@EE!"_0$s8To-$n\:Ps7`0<$phH'rsZ_9$n\:Ps8/p.#S;(Vrrg=j!%GV\rrpt?!!lKk
+r;Qf;!<)p;_+G+fV#12WN$S`]SFcdXXYgMQ\c;^(TIgQ`F8c+AKFeDep\b$l`W5`4#3q-n#VDS<
+rVunQrr3/]G8(a4hY$mKHi3pEF/T$?o5f9UfDc#(Dsi*nmeZqbpT_:,rrVV,J*[+7Hi3pEF8Z%>
+`W1MWrrVV,J,K<JmbRrgs8RlQrrg=j!%GVYrrL+>rr2tFr;[.Fs8UY:!!lJqp\k-lL\q,OL]7;_
+lAR"p/Y)G4qtFS+&9I^J!R:[rs+14+rr@`D]`RYm:4N~>
+ZMspZr;Qoo@0dEeXT&HRD=)gimHFQN&DuXM!r[n2rr4/=X>C>P])Vg'lW"3%EVoe9f0KNF<U9\b
+lW"3%EVoe9H2R^c3kG@k^e5.iV"t&`TIpX<[f-7+^e5.iV"t&fXC2AGFoMCDa!_'=^Ae-9f0KNF
+<U9S_!Q+p9ruJmJ%PFRQs6G[l$8A(Cs8/lS$pqQ*s7N$;$kRFUrr3+Q'F7_1r;Qf8!;?Esl]*;!
+0V7n8rrW.SM>mMYj*)7SF5HTi!."MC!-P4>"7^AVq:GWMIr4S&D=.3"!qie/r;QicD1CmO!."MC
+!-S5>!lG"fn,EIVD1DK`!q"_BcMmtELPc!0"NMnn.),TY!Q+p:rr@?C!"!fJs49O>#Z[Pjrr3&u
+LPbs/!r[n2rr3GnN[>)eT(E!ZpL+==Fo)+=cNJh!JcFR+!.sgN!pc:LJ,~>
+ZMspUr;Qoo@gEWeXT&HRDsi*nmcaZO&DlOKs+gUR%K!7b$phH(s7bt[#S;(Vrs[IF!!lKks8VOc
+#S;(Vrr@EE!"_0$s8To-$n\:Ps7`0<$phH'rsZ_9$n\:Ps8/p.#S;(Vrrg=j!%GV\rrpt?!!lKk
+r;Qf;!<)p;_+G+fV#12WN$S`]SFcdXXYgMQ\c;^(TIgQ`F8c+AKFeDep\b$l`W5`4#3q-n#VDS<
+rVunQrr3/]G8(a4hY$mKHi3pEF/T$?o5f9UfDc#(Dsi*nmeZqbpT_:,rrVV,J*[+7Hi3pEF8Z%>
+`W1MWrrVV,J,K<JmbRrgs8RlQrrg=j!%GVYrrL+>rr2tFr;[.Fs8UY:!!lJqp\k-lL\q,OL]7;_
+lAR"p/Y)G4qtFS+&9I^J!R:[rs+14+rr@-3XTI[M8q6~>
+ZMsp]r;Qr*8onoCafYRHIrFb)Dslih!=7QGrri5]]iKdbs!$*D??'5,jT!Dj;Km1[`W,s^:31JO
+SH&VV;Km1[`W,sM3W<eBNnFBkOCiWCIG"SCF_#W(MrOcrOCiWCIG"SPI7eR!9$.,5DcV'cB)_f6
+G><4#:7V:_!qU=1rr4>)OCiWCIG"S5CM@p%Fij[9I9pnuM<+][F_#W9;T8\9`EI>,9!S?p!qU=1
+pAYQ7CM@p%Fij[\k.OfJrr3/2@V9C_ZM"4uAi]j+!3rI%"7U;YrR_&QIrFb)DsmK%!rLX*r;Qid
+Dh%*Q!G4@kCB1X<rr_k2!.XJ;!q'uVr;Qidh>kq&"T.>p<eLAN"E.=b>%[^4!qU=1rr3"23W<e)
+Z2aiJ:31JOFj9s`k.OfJrr3,uk.OfJrr3JACM@p%Fij[9YtB(U9$-u1!S.7%s+14+rr@`D]`RYm
+:4N~>
+ZMspZr;Qr+8o\cAb,t[IIr4S&D=-Qe!=7NFrri5]]N0^bs!$*E?>s2-jT!Dj<HiL^_Z0R[:N^_S
+RfEDT<HiL^_Z0XK3<!\JNS"3iO(WTCIFnMBG%Pl,MW"NoO(WTCIFnMOIS+Tu9$726EE.9gC&S)1
+Gu&R(:R_7^!qU7/rr4>)O(WTCIFnJ2Che-*Fij[9IU6u!MWFf\G%Pl<;SrJ6``[G,9<eBp!qU7/
+p\t^$]PM>+Ap)5qqrYOlK`:uU\79/d@^H(-rrHalrbDM<VuHkfDg_K7rrmmhm=0!?qYpWnfA-<(
+!psiSli-uu3<![nYl4S(o5+JWn,EIVD1DK`!q"_Bd/O7Gk.F`JrVm%@<I%e_rVc`to5+L,rrHal
+rbE%Ks8@4=F`U?#bl@S&]N0^brtbLo]N0^cs8KZIC3F33aoC#!8o\cAb5;2>eH1=%JcFR+!.sgN
+!pc:LJ,~>
+ZMspUr;Qr*8onoCafYRHIrFb)Dslih!=7QGrri5]]iKdbs!$*D??'5,jT!Dj;Km1[`W,s^:31JO
+SH&VV;Km1[`W,sM3W<eBNnFBkOCiWCIG"SCF_#W(MrOcrOCiWCIG"SPI7eR!9$.,5DcV'cB)_f6
+G><4#:7V:_!qU=1rr4>)OCiWCIG"S5CM@p%Fij[9I9pnuM<+][F_#W9;T8\9`EI>,9!S?p!qU=1
+pAYQ7CM@p%Fij[\k.OfJrr3/2@V9C_ZM"4uAi]j+!3rI%"7U;YrR_&QIrFb)DsmK%!rLX*r;Qid
+Dh%*Q!G4@kCB1X<rr_k2!.XJ;!q'uVr;Qidh>kq&"T.>p<eLAN"E.=b>%[^4!qU=1rr3"23W<e)
+Z2aiJ:31JOFj9s`k.OfJrr3,uk.OfJrr3JACM@p%Fij[9YtB(U9$-u1!S.7%s+14+rr@-3XTI[M
+8q6~>
+ZMsp]r;Qp`GOFTs@aY2\dZAs:c2Y>Qrr4%$c2Z4RIuDSOs1O2?ON7(pkconsW8djWIrFb)DsmH$
+)ZA6lLP)Q"s8RT"R"(4Ks,-l$gAcZRON"c/rr3%]c0"a""Rrg9.=_?s,+_uDlC_Ifqhu\koBL[+
+s6:#goBqP`s7[\0oBL[+s8P6Drou6-qu<[1ZgP_sbPR6+amQKNXT,;7ZgP_sbQ"/;GOFTs@fQ$.
+^%]JOoDe(aV"=#5-2miFPX,<Ks!Fa[ZgP_sbP$EpeF:@\OT1nUZKe)hYksAeamSG@>6"V'Hg:3e
+R/R$dPX,<Drtk*Q@asnb>`f!T[;@@Bs8VnEAD5mPIJNU:!BlPDl2^RVrrVV,J,B6OkconsXQJ<K
+W;cf3ONmgROFN25s8TcfJ"Z60s3d!YMoG\q"b1IYIrFcOrsJJ/^]35hKo)[3J*[+84co[.!;HHl
+"-c(OJ,B7#kconsW8djWi223bVHeWNi223bVRZ^,s*rU]`W,h?LP)Q"s8UN/IuDSOs3d!YMp:Sf%
+e-lC.=_Btq=>$.pVdF0rVlq`5lgoa!BlPDl4<Xhl3sK[mYk82s7!F5.=_?s(@\_K.=_Btp4$Q$n
+AALms.2AtmcI\^qu6]R!.k0$s5!\TK_)kYn!m.'~>
+ZMspZr;QpaH0sd!A^UM_dZK$=bl>2Qrr4%%cMu=TIuV\PrOdu@OiR1qkHK_qW8[dVIr4S&D=.0!
+)ZA6mLP)W$s8RT"R=UFKs,@#$f`-HNO2SQ.rr3%^cK=j#"Rrg9."D6r=.WX&lChUkqhu_loBUa-
+s5slfoC%Vbs7[_1oBUa-s8P?Fl0I[)qZ!U0ZL5Srbkm?-amZQOXoGG8ZL5Srbl=8=H0sd!AcM?3
+]_B>On,MP\V"=&6-N=#IrKKVKrr4=GBX7'CQd#/PA(:%c>EAfU>I3Ug@']Zg@EJ!(HX$OM=*a-%
+Pa_UO"9"HN!;HL0m=&Qpn\SLks7!F5."D9sq1*&0h.M-0pAY:]O6Puror%fkm;7@Mrs7hoLk`%n
+gUO9_rtU[As3d$ZNQhG$]SV36mJm45O+3)+rr3.OD=)gimJ?hip9qa9i2DBeV-AH8rrkZKl0I[.
+rr3-"PX5A"qu8D6Y_Rq2iW&r9W.p/*>CZ\2W.p/*[K-@-J(0Ots80*WK<"\Gs3d$ZNQhG&dZK$=
+bj59=n?m*]J,fQEo+&G-`!Yu4rr`4a63.#b'L7`Dlg+6Dk74<Zmu1D4s7!F5."D6r(@\_K."D9s
+p3pN$n\SLks.2E"mH7\bqu6]O!.k0$s5!\TK(HDPl^COu~>
+ZMspUr;Qp`GOFTs@aY2\dZAs:c2Y>Qrr4%$c2Z4RIuDSOs1O2?ON7(pkconsW8djWIrFb)DsmH$
+)ZA6lLP)Q"s8RT"R"(4Ks,-l$gAcZRON"c/rr3%]c0"a""Rrg9.=_?s,+_uDlC_Ifqhu\koBL[+
+s6:#goBqP`s7[\0oBL[+s8P6Drou6-qu<[1ZgP_sbPR6+amQKNXT,;7ZgP_sbQ"/;GOFTs@fQ$.
+^%]JOoDe(aV"=#5-2miFPX,<Ks!Fa[ZgP_sbP$EpeF:@\OT1nUZKe)hYksAeamSG@>6"V'Hg:3e
+R/R$dPX,<Drtk*Q@asnb>`f!T[;@@Bs8VnEAD5mPIJNU:!BlPDl2^RVrrVV,J,B6OkconsXQJ<K
+W;cf3ONmgROFN25s8TcfJ"Z60s3d!YMoG\q"b1IYIrFcOrsJJ/^]35hKo)[3J*[+84co[.!;HHl
+"-c(OJ,B7#kconsW8djWi223bVHeWNi223bVRZ^,s*rU]`W,h?LP)Q"s8UN/IuDSOs3d!YMp:Sf%
+e-lC.=_Btq=>$.pVdF0rVlq`5lgoa!BlPDl4<Xhl3sK[mYk82s7!F5.=_?s(@\_K.=_Btp4$Q$n
+AALms.2AtmcI\^qu6]R!.k0$s5!\TF7ZL8kEJSh~>
+ZMsp]rVm)n#ho=YYoM3l.echRHY-%ITIp'@iY9N/;J1>g:A;S&F*1r.`VZH+@WPYCqu;.amXK0C
+q>VSdJQdDA:7V@a!-a3J:1!sY!-d/s!,lYdTIp'@iY9MqpA\Llc)+6cs8VnCEU<_XArZJ+!:Tsf
+`YAI8Dtj;3[1rZ,!:Tsf`YAIQ(iOnRW6bA<K3XdtOLslPFa*T[ibaPLK3XdtOLslTI<"!@s03RD
+o7-Z;dL>aIk&:"os0WR?s"1oVU]CGpqh&.@Koiq5p4$`1q8lm$q0d8Ls4CqColYKQs8U(Qs7[)(
+LP),Nrr3)68u)I]rtk*QBAE=)>`JdUc)+6cs8Vo*^&@/5J,/g<"W20-J#N+>rrVP(J,K<sqkRJ:
+EE]*[TIp'@iY9N/;J1>g:A;S&F*CB;s7]D`HYQ%Es8RRemXK0CqYpojDh$]#>&SOo.t?mb"W20-
+J#N,@rrg#-U]>oBs"sVK:1A9HT)7H$>&SOo.t?K4>&SOo<WN1"!,lYds/9+JF&&8*pJPXNAkr*p
+;J1>g:A=YQrsn\GVG;X@s7u89qu>(QoD\al]h5(#rr3ZLDh!88p]'Aop](9$A;U?Yc)+6crr3c+
+c)+6cs8VeBBAE=)>`JQ-#ho=YYoNZ@!oa4WJcC<$hZ!S/o=Y4oS5+S~>
+ZMspZrVm)n#h]1WYTVBo.ecqWH"g"IShBp?itf`1<G?_m:%uA"F`q82`;??)@W>J?qYu%^m=0!?
+q>VSeK3`bD:RqIb!-a9L:0mmZ!-Qro!,lYaShBp?itf_rpA\Llc)+3bs8VnCE9mPUBTMh/!:Bgd
+`>JX:D>!r/Zl&i/!:Bgd`>JXT)KC1VWmLY?K3O^tOM'uRFa!KYibj\OK3O^tOM'uVI;mj=s0*XG
+o7-Z9cj]CCj_a\js0NXBs"1fRU]CGpqh&+?L60(8p3pW-prH^#q0d5Js4:qFolYHOs8U%Ts7[)%
+M1_DSrr3)38Yc@\rtk'OB%m%$>`SjVc)+3bs8Vo*^&7#1IJ<I8"WDB/JZAIBrrVP'J,K<sqkd_?
+EEf0[ShBp?itf`1<G?_m:%uA"Fa$W<s7]A_H"f_?s8RRcm=0!?qYpoiD1CK">]=gs.t?mb"WDB/
+JZAJDrrfo)U]>oBs"sVK9k&*DSbh9#>]=gs.t?K5>]=gs<ri:#!,lYas/K@MF&/>+pJkpQBhe?r
+<G?_m:&"PPrsn\GVG2R?s7u89qu+kMn,E=h\k/[trr3ZNEIED<p]'>lp&G'!ArH]]c)+3brr3c+
+c)+3bs8VeAB%m%$>`SW.#h]1WYTWiC!oF"TJcC<$hZ!S-o<n_dRSA;~>
+ZMspUrVm)n#ho=YYoM3l.echRHY-%ITIp'@iY9N/;J1>g:A;S&F*1r.`VZH+@WPYCqu;.amXK0C
+q>VSdJQdDA:7V@a!-a3J:1!sY!-d/s!,lYdTIp'@iY9MqpA\Llc)+6cs8VnCEU<_XArZJ+!:Tsf
+`YAI8Dtj;3[1rZ,!:Tsf`YAIQ(iOnRW6bA<K3XdtOLslPFa*T[ibaPLK3XdtOLslTI<"!@s03RD
+o7-Z;dL>aIk&:"os0WR?s"1oVU]CGpqh&.@Koiq5p4$`1q8lm$q0d8Ls4CqColYKQs8U(Qs7[)(
+LP),Nrr3)68u)I]rtk*QBAE=)>`JdUc)+6cs8Vo*^&@/5J,/g<"W20-J#N+>rrVP(J,K<sqkRJ:
+EE]*[TIp'@iY9N/;J1>g:A;S&F*CB;s7]D`HYQ%Es8RRemXK0CqYpojDh$]#>&SOo.t?mb"W20-
+J#N,@rrg#-U]>oBs"sVK:1A9HT)7H$>&SOo.t?K4>&SOo<WN1"!,lYds/9+JF&&8*pJPXNAkr*p
+;J1>g:A=YQrsn\GVG;X@s7u89qu>(QoD\al]h5(#rr3ZLDh!88p]'Aop](9$A;U?Yc)+6crr3c+
+c)+6cs8VeBBAE=)>`JQ-#ho=YYoNZ@!oa4WJcC<$hZ!Rso;r)WPY-H~>
+ZMsp]rVm)]!;lfrecaG$.dmA:pY'ugjqQ8DQneL,!3,_HHhUEVlL;uN[/7+if]$F_o)F2XmXK0C
+qYq`;P\-T[mZ]$lrr@Q:s/ZM+rrCpUrr@,opZ<1<s-PP<rUg+amVdUTs6t#VrVu/"Jbb!:V"<l$
+!<;ras7a31HiN[SV"<l$!<;d5CO^7kF3jDu2fj+JGL?5??H_cE5C`6F2fj+JGL>o"IJa'EecbsO
+6[r!Cs8Vuas7a31HiO-":8H_Hs8VY22fj+JGL?H"=C-8R@)_VTIJs32D1VM:?H_d%IfTN2!,m(&
+8u2Leg.nI#!;?Es[ocs^<a`oGrrVV,J,K<K^M-lUpAY?k*,C%B7A-RY!n1P8r;S;AG>urQWk%Q[
+'[m#K1&LD>WV>+npJPqppRl:$pM726aT1K's*ntTIrFcOrsJ14J#68:kj"fqJ,TBJlIPi^!7puG%
+egrYIr@cKs8UeJUtu*$r;SVNZ&mVtA97==<h/C=TJ:qn<h/C=TOIp$rr@,op\QP8oBqhhp[8*]p
+Y'ugmf9?]g3`Skrr3#aWr.>IWp9?Y!q'uVqu6_I;I]Y*(>;NZh>mTUpDdsuDag?!qsOLY]io0ar
+r3&fDh%]b!q'uVrr3J;=C-8R@)_VT!;lfrecbmM!qR,>JcC<$hZ!S/o=Y4oS5+S~>
+ZMspZrVm)^!;ZZpdg"8#.dmM=p"F]cjV6/CQnnL+"K;"IH1t0UlgW&M[/."gfAC(Xnc+)Um=0!?
+qYq`;Q"Zi\n!#*lrr@Q;rN$;)rrCgRrr@2qp#Qn9s-PS;r:L"`m;7@Qs7()Vr;Z"tK)(*;VXs,'
+!rr/bs7a0/HiN[SVXs,'!rqp7D1-CpFjT`$2fs4MGL?5??d.uH5_/HI2fs4MGL>r#I/3gBdg#gO
+7/_O4@K$6'mJlpn=aU2Kg.nBs!<<)jF#S2a?['os[9$XY<a`o:EI@]al"ktIKjW'ml[K!9k5]FG
+F%`>/s4U5BgAq!J#Q;&3?$KCX`W#l=m;7@OrrrD8BNhV=p\tHj*c6=F8><'_"9-bYN;W]+pN]fb
+kGl&[jV6/CQnnL+"K;"IH1t0Ulh-obs7L09q8NEps8RRcm=0!?qYpoiD1AKdSET720n90%!UA85
+IfS!orsn]CD1-CpUAt8I:86JCJ,K='qQQ(5hd^ZrW*#SRlC]k]W*#SRlC_Ves8N(Ag@b=sT^hK8
+,kpa1W:ekip[86`p"F]cqu6TrlDsi4!NPDYrrVS)J,K<erI%UQrVuoO:86JCs8Va5D1-CpUAt,X
+s7a0/C;'WH!psiSr;RJuD1DTcrj>g5GZJ4knSnR)s8UOPqu6`f(;,4uJcFU,!.sgN!pc:LJ,~>
+ZMspUrVm)]!;lfrecaG$.dmA:pY'ugjqQ8DQneL,!3,_HHhUEVlL;uN[/7+if]$F_o)F2XmXK0C
+qYq`;P\-T[mZ]$lrr@Q:s/ZM+rrCpUrr@,opZ<1<s-PP<rUg+amVdUTs6t#VrVu/"Jbb!:V"<l$
+!<;ras7a31HiN[SV"<l$!<;d5CO^7kF3jDu2fj+JGL?5??H_cE5C`6F2fj+JGL>o"IJa'EecbsO
+6[r!Cs8Vuas7a31HiO-":8H_Hs8VY22fj+JGL?H"=C-8R@)_VTIJs32D1VM:?H_d%IfTN2!,m(&
+8u2Leg.nI#!;?Es[ocs^<a`oGrrVV,J,K<K^M-lUpAY?k*,C%B7A-RY!n1P8r;S;AG>urQWk%Q[
+'[m#K1&LD>WV>+npJPqppRl:$pM726aT1K's*ntTIrFcOrsJ14J#68:kj"fqJ,TBJlIPi^!7puG%
+egrYIr@cKs8UeJUtu*$r;SVNZ&mVtA97==<h/C=TJ:qn<h/C=TOIp$rr@,op\QP8oBqhhp[8*]p
+Y'ugmf9?]g3`Skrr3#aWr.>IWp9?Y!q'uVqu6_I;I]Y*(>;NZh>mTUpDdsuDag?!qsOLY]io0ar
+r3&fDh%]b!q'uVrr3J;=C-8R@)_VT!;lfrecbmM!qR,>JcC<$hZ!Rso;r)WPY-H~>
+ZMsp]rVm)a!;lfrecaG$.ed7nK:LNms%7e@4cB@7??_$lf)H<#s8VoQk5XA>QBk-]mf.cTmXK0C
+qYqB(FZXesIr>>HrrC=Ds5!bUrrCpUrrC1?rrbrDs#l;2rtOm>J,fQ>F++#el>;+P_hV!.G?tRS
+s#%oNF+`WTs+a?jG?tRTpR'D/mXJ9'n8V:Fm^l_ks2/SZF_W^bn8V:Fm^l_knoK6Vs8UXQrVltL
+;Hitss#nJVF+`WTo3ue8g&V$Mn8V:Fm^l_ks0Pa1GuS+hnoK6Xs6=HPs2/SZFa%-ts5F$Omd>lc
+s79]@pY#WEp\tH)<*X]J?H)pD!q'uVr;Qo7Bi_84p\tHlR*u$&Ik@W!"7hU[^&7m\ql4F[O1FQU
+s%7e@4cB@7??_$lf)H<#s8V]8s8Tp"R$7U-s8RRemXK0CqYpojDh!IOhZ*W6@"8.T!UA85IfS'q
+rt"jkdf8`b/cYEOF8+AgIJs*D1#T'tQ:c)`Kk0'?s57:7Kk0'?s5:]ns8N)@s8V?aGCP*\!93`Z
+GCuF:s7]iDK:LNjrrMDbr-naIlM(;[mVdUPrtBl[>5S?k@WV:t!;lfjR*u$&IkC[""j)C<K=1:L
+rrVV,J,K<JmVdUSrslD8>^9:T`U\'Mqu?]I"T&-"?:t*Gs+14-rr@`D]`RYm:4N~>
+ZMspZrVm)`!;ZZpeHXJ%.ed@qK:C<hs%7k@4H9C8@<[?ndf0lus8VoPjo4,;QBb'ZmJhZQm=0!?
+qYqB)FushrIr>>IrrC:Cs4[PRrrCgRrrC.>rrbrFrB-)1rtOj;J,fQ>Ed[fbl>;.Q_hV*3H!L^T
+s#%rOF+NHQs+aHoH!L^UopO8,mt"T,n8M7Gn%)_is2/Y_GAAsdn8M7Gn%)_inoB-Rs8UURrr3-"
+IoBSKrr51)K6)V*s79fCo@F!<rU4]&aR?]EQi=?k>^'.S`U\%sr;Z&!K)``)@s<3(#lii`U@7Q*
+0`U`UF7[u`q>L-h#Q;#/>^'.S`W#l=m;7@OrrrD9BihA6p\tHjRF;'&JM*o$"7hU]^&7m\qlFU^
+O14?Qs%7k@4H9C8@<[?ndf0lus8V]7s8B`uQ]qL)s8RRcm=0!?qYpoiD1@:PhZ*W5@"8.T!UA85
+IfS!ort+jkdf&Wc0)tNSF7[u`I/EpBs"aT1X-T#CD=*'ihZ*W5@"3oChZ*W5^]=E7!6G3?lN23Y
+Ir>>IpL/8uS'q?2@<[?ndes+GlDsi4!NPDYrrVS)J,K<\rI7aMqu?8!F7[u`q>KuSdf&Wc0)kkS
+b(FbdZh"+q!psiSr;RJuD1DTcrj5X0G>qqgno=a+s8UURqYpV*9Da;?JcFX-!.sgN!pc:LJ,~>
+ZMspUrVm)a!;lfrecaG$.ed7nK:LNms%7e@4cB@7??_$lf)H<#s8VoQk5XA>QBk-]mf.cTmXK0C
+qYqB(FZXesIr>>HrrC=Ds5!bUrrCpUrrC1?rrbrDs#l;2rtOm>J,fQ>F++#el>;+P_hV!.G?tRS
+s#%oNF+`WTs+a?jG?tRTpR'D/mXJ9'n8V:Fm^l_ks2/SZF_W^bn8V:Fm^l_knoK6Vs8UXQrVltL
+;Hitss#nJVF+`WTo3ue8g&V$Mn8V:Fm^l_ks0Pa1GuS+hnoK6Xs6=HPs2/SZFa%-ts5F$Omd>lc
+s79]@pY#WEp\tH)<*X]J?H)pD!q'uVr;Qo7Bi_84p\tHlR*u$&Ik@W!"7hU[^&7m\ql4F[O1FQU
+s%7e@4cB@7??_$lf)H<#s8V]8s8Tp"R$7U-s8RRemXK0CqYpojDh!IOhZ*W6@"8.T!UA85IfS'q
+rt"jkdf8`b/cYEOF8+AgIJs*D1#T'tQ:c)`Kk0'?s57:7Kk0'?s5:]ns8N)@s8V?aGCP*\!93`Z
+GCuF:s7]iDK:LNjrrMDbr-naIlM(;[mVdUPrtBl[>5S?k@WV:t!;lfjR*u$&IkC[""j)C<K=1:L
+rrVV,J,K<JmVdUSrslD8>^9:T`U\'Mqu?]I"T&-"?:t*Gs+14-rr@-3XTI[M8q6~>
+ZMsp]rVm)r#i>U][2dWp.f7&XLNcqrs.Csp(uG;i_5)j1>5&HEs8VoEgA@a_MkF$fmf.cTmXK0C
+qYqB(FZk)$IsYhnrrCpUs5!bUrrCpUrrCpTrreuHeem97ru:BEJ,fQGIrk&Xg1ZKGmbXI`Mi]Cf
+s060c[J0\##i;)$Mi]Cfk0<o*CrU1Cq0R>Ys5[sLs6dR\KoK?%q0R>Ys5[sLqgW\Ds8TJHs7`>h
+s3_&=s8T?9J$o%Ns3_0_HYWV.`S>fap&F)gL&$4-gA/cmNVe3Hmf2!SNW8F[NeNCQ.KAuBli7"-%
+0+`]@s_tkHc>g\#P3FSgA/cmNW/qdmVdUTs81'gs6+6Dp\4[gk0<o*!QGPHrr_hZ@_M^>/,e>2Q
+@ESHqu<<@eem9Dqn](`G?X_L`W,u0[K#u%J!d/7hZ*V*Dsi*nmeZqjmVdT/B&N^hi*_'$rrM9,r
+r3AG%0+`]@s_tk4eUg6s"sVMCQ"ibDsi<ki;`i8@"3lBi;`i8_#XN8!8dbUl2Z0\IsYhnqn](`G
+?Xb<_5)j1>5.p[rtk*AJ,fQGpS@ihdKK%=dKj?0CB/_#k0<o*$-!DRs060c[J0RsrrVV,J,K<\m
+VdUTs7q.RgA/cmNVe22hZ*V`*;fa<qatr,JcC<$hu<\0o=Y4oS5+S~>
+ZMspZrVm)p$JYU\[NO#u.f7)[LNQbos.V-o(uG;i_PW*2=n`?Es8VoEgA@d`MkF'emJhZQm=0!?
+qYqB(F?FhuIsYhorrCgRs4[PRrrCgRrrCgQrrf&KdMUj3ru:?BJ,fQFIrarVg1ucLn)'^fNK>Xi
+s0??e[e9Y"#iD5)NK>XikKa),Cr^:Fpj78Ys5[pKs6m[_LQ5Z)pj78Ys5[pKqL<P?s8TMMs7N2d
+s3Lu;s8TB=ICAhKs3_6_H"d8(`7fQ_p&F)fL%g%,g%WKkO8=?HmJkmUO8n[_O,&^V.f]#Cli7",%
+0+`_@<lPeH,TOY#Od+Pg%WKkO8f.fm;7@Qs8'sdro\'Bp@nRfkKa),!QP\Krr_k]A%_a>/,e>3Q
+@<JFqu<BCdMUj@qnf4cF]nGI`rH)1[f?)'J![/8g].;'D=)gimJ?him;7?-BA`ahhdCs#rrM<.r
+r3AH%fara@<lPe4J1U3s"sVNCQ"icD=*'jhuE`6@"3oDhuE`6^]=E7!8IPRkl?!YIsYhoqnf4cF
+]nJ9_PW*2=nhgZrtk'>J,fQFoq_Qdcj&n;dL'E.B`NFskKa),$-*PUs0??e[e9LqrrVS)J,K<\m
+;7@Qs7^tQg%WKkO8=>5g].;^+T)0@q+Z#/JcC<$hu<\.o<n_dRSA;~>
+ZMspUrVm)r#i>U][2dWp.f7&XLNcqrs.Csp(uG;i_5)j1>5&HEs8VoEgA@a_MkF$fmf.cTmXK0C
+qYqB(FZk)$IsYhnrrCpUs5!bUrrCpUrrCpTrreuHeem97ru:BEJ,fQGIrk&Xg1ZKGmbXI`Mi]Cf
+s060c[J0\##i;)$Mi]Cfk0<o*CrU1Cq0R>Ys5[sLs6dR\KoK?%q0R>Ys5[sLqgW\Ds8TJHs7`>h
+s3_&=s8T?9J$o%Ns3_0_HYWV.`S>fap&F)gL&$4-gA/cmNVe3Hmf2!SNW8F[NeNCQ.KAuBli7"-%
+0+`]@s_tkHc>g\#P3FSgA/cmNW/qdmVdUTs81'gs6+6Dp\4[gk0<o*!QGPHrr_hZ@_M^>/,e>2Q
+@ESHqu<<@eem9Dqn](`G?X_L`W,u0[K#u%J!d/7hZ*V*Dsi*nmeZqjmVdT/B&N^hi*_'$rrM9,r
+r3AG%0+`]@s_tk4eUg6s"sVMCQ"ibDsi<ki;`i8@"3lBi;`i8_#XN8!8dbUl2Z0\IsYhnqn](`G
+?Xb<_5)j1>5.p[rtk*AJ,fQGpS@ihdKK%=dKj?0CB/_#k0<o*$-!DRs060c[J0RsrrVV,J,K<\m
+VdUTs7q.RgA/cmNVe22hZ*V`*;fa<qatr,JcC<$hu<[to;r)WPY-H~>
+ZMsp]r;QpdK_t@M@ab9+pLi@[YlOCqjqM,ss8Vh+hYXPXo0m`cnB6*UpNL94i*^Egs*ntTIrFcO
+rtkWsBW1OoW.Y-M!8dbUh>mTU!8@JQ!8d_T"6L;(:@\>cmVdUSrtD&7^\=a;YlD\#XnUs]HiN@c
+J):1is8P0=XnUs]HiMMhanP(M@%dOgB>a/H?Cq29SC6huC;'Y9B>a/H?Cq1i@YFXM@UfB3/]mb+%
+.jMa0n8'Zl2gqArdQM<!.VuIRV0P+[pG[%Ipgdq_-2s#TOP\1Wa`44`LPBEk$!-3s#$23mXID"h
+Yr!,DZG:+q>U]kIpgdq_-2s"rs\=6J,fQGP'c-DBRfjPrs$nHanP(M6)X_ag1H9@s"!uMU?pH5H
+27L&'OFQ7s7^0_qlp.m7<@bgTMkgY!7(V\!8@JQIrFb)DsmK%$LVh^VHBGRlCp(arVlo`f)'psf
+(o=OdS@pYl@2,"hYr!-DZE"rir8s7pNL94i*^EgVHBGRlCp(aVHBGRlCqnks8N)Us8VsFW:TVZK
+E([YhYXPXoClnSqlp.mq>UBplDjc3!NPGZrsnI8J,fQGpFXM]`=2A<hYr!8DZG:+dS@pYl@2,"l
+7meFrosLUrr3&fDh%]b'^fmhs8VnE@+=\^>*/cW6%o.,@Uf67!pTdNJcC<$hZ!S/o=Y4oS5+S~>
+ZMspZr;QpgK),"JA^^T.ok3.WXoe.nk8%E"s8Vb)hYF;UnO@TcnB-$Tp3102hdL<ds*nnQIr4TL
+rtkTqBVt=kWeLKQ!8IPRgAq9R!8%8N!8IMQ"6UG,:@\>cm;7@PrtD)9^%SL;ZN%q(Y4^m^HiN=c
+J_g=ks8P0?Y4^m^HiMPlb4k4O@\NgkBuKGJ?Ch,9S^HhuCq]k<BuKGJ?Ch+i@tOOJ@qG]3/B7G$%
+.F5\14e9\lN.%BrdQM:!.W#JRq]h/[U,O!IUU^q_-<$$Tjte0X(8O9`gtNEj^!65s#?J9m=.7uh
+Yr!,D#f(*q>U]gIUU^q_-<$#rs\:3J,fQEO*TU;B79OKrs$qLb4k4O7&U%dg1Q?As"!rKU[-B2H
+2.F&(10i:s7L$]q5seh7W[ngTMkgW!mU\\!8%8NIr4S&D=.3"$LM\[W*,\TlCft_rVlo`f)'pse
+G9+Mdo"9^l[M>&hYr!-D#ceqir8s7p3102hdL<dW*,\TlCft_W*,\TlChbhs8N)Rs8VmEVXa8XL
+&^gYhYF;Unb$POq5sehq#:9olDsi4!NPDYrsnF5J,fQEo.7oU_@5o5hYr!8D#f(*do"9^l[M>&k
+q[hGrp'RWrr3&eD1DK`'^]aes8VhB@FOb_>EJlY7"Y7+@qGQ;!p9XNJcC<$hZ!S-o<n_dRSA;~>
+ZMspUr;QpdK_t@M@ab9+pLi@[YlOCqjqM,ss8Vh+hYXPXo0m`cnB6*UpNL94i*^Egs*ntTIrFcO
+rtkWsBW1OoW.Y-M!8dbUh>mTU!8@JQ!8d_T"6L;(:@\>cmVdUSrtD&7^\=a;YlD\#XnUs]HiN@c
+J):1is8P0=XnUs]HiMMhanP(M@%dOgB>a/H?Cq29SC6huC;'Y9B>a/H?Cq1i@YFXM@UfB3/]mb+%
+.jMa0n8'Zl2gqArdQM<!.VuIRV0P+[pG[%Ipgdq_-2s#TOP\1Wa`44`LPBEk$!-3s#$23mXID"h
+Yr!,DZG:+q>U]kIpgdq_-2s"rs\=6J,fQGP'c-DBRfjPrs$nHanP(M6)X_ag1H9@s"!uMU?pH5H
+27L&'OFQ7s7^0_qlp.m7<@bgTMkgY!7(V\!8@JQIrFb)DsmK%$LVh^VHBGRlCp(arVlo`f)'psf
+(o=OdS@pYl@2,"hYr!-DZE"rir8s7pNL94i*^EgVHBGRlCp(aVHBGRlCqnks8N)Us8VsFW:TVZK
+E([YhYXPXoClnSqlp.mq>UBplDjc3!NPGZrsnI8J,fQGpFXM]`=2A<hYr!8DZG:+dS@pYl@2,"l
+7meFrosLUrr3&fDh%]b'^fmhs8VnE@+=\^>*/cW6%o.,@Uf67!pTdNJcC<$hZ!Rso;r)WPY-H~>
+ZMsp]r;Qr.;L`mcajU2=qbh0UB3+p0s%Wj$s8VsoC3sSoqmfICF^f1+qjLK0LK$gRs*ntTIrFcN
+rt`q/>'G0gOT5=\hZ*W4!<<'BCYJdghYmHU:'drkrrVV,J,]H\g4O*d@Z0=I`J[K8F'@;t\H$.<
+C]FDqMb\J;>2'#A>$cDo>)D&7eph.M@Y*23`GB"+At&)deph.M@Y*23g4N:QG>?9[s'f/U>&XH@
+\H$.<C]+25h>mQT-J!ZUF(0^Qs1;rWF(044s4W*>HX_oos2Ae`F`Ua?s8T3!F)t6ar;QfS!;?Es
+]4bhu@WTZjrrVV,J,]HOY[2$XA@M:4#3oAuGB6ruVuHhbD1DK`/,c>OF)bNbrVumm#d"(+qbh0U
+B3+o?:31VSMuWN7CPR]hDu]ieDsi*nmeZqjmVdU5LK\V?D)$P=rrME9qgSUsq>UZa>$cDo>.OS2
+!o<p,r;R`5RT+Qf<(OLVLK\V?D)$OuLK\V?D.<SGrrCpTrtV21GBZrHs8,]/HY6CVqbh0UB3+p.
+rr3#aWr.>IWp9?Y!q'uVrVm"0>'F.gqu7/_!<<)a>$cDo>.O[D!+YtC!4Dh+!q'uVr;QidDh%cd%
+_HCeF(044s4XkYIs4Z0qu6]R!.k0$s5!\TK_)kYn!m.'~>
+ZMspZr;Qr/;1Ejdb0p;>q,;'SB34p/s%Wp(s8VmnCO'Poq7'1@F^o:-qO(?/LfR*Vs*nnQIr4TK
+rt`t0=a,'iOoPF]g].<.!<<'ACY8Xeg\q-R:("/orrVS)J,]H\g4O'dA;oUL`f3f=F'I;s[K'h9
+C]FDqNDOh?>M/uA>@D_u=GY`3eUM(M@Y!)1`c#C1B:8)ceUM(M@Y!)1g4N7PGtuN^rF8uS>AsK?
+[K'h9C]+25gAq6Q-ImTUF(0[OrjuoYF_#R8s4W*=Ht82ss2JtfF`Ud>s8T0!F)t0^r;QfP!;HKu
+rOZfXF_#R8rr3DoD1DTcrif^BBk=aPp\tH`>@D_u=Lb:/!pj`Qr;S;FVI+@_?`<o&s%Wp(s8Vmn
+CO'Poq7'1@G>F.sofd/HMB[!=s*nnQIr4TLrsJ.1J)H)cDg-%QJ,TBJlIPi^!7^iE#4#K%GBI#t
+r;QiQ!.XqH)u>t&H&,Km\)<$FDg-%QJ)H)cDg-&.!<<'!g]%3fU02\a<K[=W;epYk=8DYjCO'Po
+q>C6l!U?``IfZS6p\tZhD1DTcrr$>0G?]"ar;R8]!<<)b>@D_u=LeC>!+YtC!4Dh+!psiSr;RJu
+D1DTcrjuoYF_#R8s4XnYIsFf3qu6]O!.k0$s5!\TK(HDPl^COu~>
+ZMspUr;Qr.;L`mcajU2=qbh0UB3+p0s%Wj$s8VsoC3sSoqmfICF^f1+qjLK0LK$gRs*ntTIrFcN
+rt`q/>'G0gOT5=\hZ*W4!<<'BCYJdghYmHU:'drkrrVV,J,]H\g4O*d@Z0=I`J[K8F'@;t\H$.<
+C]FDqMb\J;>2'#A>$cDo>)D&7eph.M@Y*23`GB"+At&)deph.M@Y*23g4N:QG>?9[s'f/U>&XH@
+\H$.<C]+25h>mQT-J!ZUF(0^Qs1;rWF(044s4W*>HX_oos2Ae`F`Ua?s8T3!F)t6ar;QfS!;?Es
+]4bhu@WTZjrrVV,J,]HOY[2$XA@M:4#3oAuGB6ruVuHhbD1DK`/,c>OF)bNbrVumm#d"(+qbh0U
+B3+o?:31VSMuWN7CPR]hDu]ieDsi*nmeZqjmVdU5LK\V?D)$P=rrME9qgSUsq>UZa>$cDo>.OS2
+!o<p,r;R`5RT+Qf<(OLVLK\V?D)$OuLK\V?D.<SGrrCpTrtV21GBZrHs8,]/HY6CVqbh0UB3+p.
+rr3#aWr.>IWp9?Y!q'uVrVm"0>'F.gqu7/_!<<)a>$cDo>.O[D!+YtC!4Dh+!q'uVr;QidDh%cd%
+_HCeF(044s4XkYIs4Z0qu6]R!.k0$s5!\TF7ZL8kEJSh~>
+ZMsp]r;QosZ%I\>d/O6nMgpi>rr3%P*:Eh+)pO:jOOjI3[>0Bra7fPiTS98LP/715\+[SGpA+_(
+qpDKtK;A,=s*sJ:s6bC:s.Fkqs*sJ8rrRfmmd^;Yp:%g9rt,.[RY.3es8Vf\S:?IAs8U@@J,fNO
+m[Scbc2R_hg6@)B^#&ehrR7-dSCmf?p;N#FXQKQ_rR7-dSCmf?rRS6+K=V!]#MP8hPiD`Cc23"g
+rrMP;rr4#;e!PcXf_tjB`K5Y:c2%D<es_5_h#IEJ`JoS0c2R_HqlGF&[JTn%!UbI2rs&,7OF`_B
+q>UBqp:%g9rrqbsLP`Y4p&>0KP^eJ%VZ-_cDh%Za"m2n?LU6:FrrRfmmf*5*c&7(5f)PcXLOYub
+s8TcbLW,p=s8TjCp:n*1qYpor\%ht$VM0r9W5%Zu"PT)iLV<Tb!q(QQqu7SkTS98LP/71VVM0r9
+W5&AjVM0r9dXV;sJ+!=9'DJS\K;A,=s36IOOOjI3c&7(5f'329p:%g8rrh&;J!AsirrMP;rr35W
+P^eJ%s8U@@IfR7_rrVo'^\n*5p:%g9rseV>OF`_Bq>^EjZ%I\>qYpTQ!.k0$s5!\TK_)kYn!m.'~>
+ZMspZr;QosY_@eBd/O6oMgpl=rr3%P*q0+.)pX@kOjsF0[YKNuaS5_kTSBDPPJ[@7[e@JEpA+_(
+qpDL!K;S8?s*sG9s6Y=9s.Fqqs*sG7rrRfon+$DZp9qa8rt,.ZRY@Bhs8Vi^SUldEs8U=?J,fNO
+n"##hbl7VgfTgrC]\NMdr6gpbSCd`>pVr8LXl]T_r6gpbSCd`>rRJ-+Kt@9`#MP5gQ/hoEbklnf
+rrMM:rr4#:d[,WWfDYaB`fYn>c2%D<eXD2ah#IEK`fGn7bl7VGq5f4&[/9e$!UYC1rs&/9Ob8tE
+q>UBqp9qa8rrqbsLPib7p&>3JQ%+Y'rMTYsm;7@MrrqPeKo!)"rr3%P*q0+.)pX@kOjsF0[YKF.
+n,NF%K8IUBL&_1f[e@JEpA4drp9qa9hkl*c[Agq,rrq&?Iu1i:r;QicJ%tm\)W%-AW3hc*s50]-
+Mm]P!s50]-Mm^u_s8RT9rr3Z+XG);(oDej9Mgpl=s8UB&J!&7FrrVo&^]"08g5g`Kj88iWm=5-8
+#M>;kM7ifebklki^]+67p9qa6rrVo&^]+6Bou<,HQHf7*rVNgQKt@-\!S[U*s+14+rr@ZB[K>c`
+9n3~>
+ZMspUr;QosZ%I\>d/O6nMgpi>rr3%P*:Eh+)pO:jOOjI3[>0Bra7fPiTS98LP/715\+[SGpA+_(
+qpDKtK;A,=s*sJ:s6bC:s.Fkqs*sJ8rrRfmmd^;Yp:%g9rt,.[RY.3es8Vf\S:?IAs8U@@J,fNO
+m[Scbc2R_hg6@)B^#&ehrR7-dSCmf?p;N#FXQKQ_rR7-dSCmf?rRS6+K=V!]#MP8hPiD`Cc23"g
+rrMP;rr4#;e!PcXf_tjB`K5Y:c2%D<es_5_h#IEJ`JoS0c2R_HqlGF&[JTn%!UbI2rs&,7OF`_B
+q>UBqp:%g9rrqbsLP`Y4p&>0KP^eJ%VZ-_cDh%Za"m2n?LU6:FrrRfmmf*5*c&7(5f)PcXLOYub
+s8TcbLW,p=s8TjCp:n*1qYpor\%ht$VM0r9W5%Zu"PT)iLV<Tb!q(QQqu7SkTS98LP/71VVM0r9
+W5&AjVM0r9dXV;sJ+!=9'DJS\K;A,=s36IOOOjI3c&7(5f'329p:%g8rrh&;J!AsirrMP;rr35W
+P^eJ%s8U@@IfR7_rrVo'^\n*5p:%g9rseV>OF`_Bq>^EjZ%I\>qYpTQ!.k0$s5!\TF7ZL8kEJSh~>
+ZMsp]^]+B,<c>bQ!qTH2JcC<$c2Rn8EI%BPrrVdmDh7qMrrVqr%"\G0s5!\TK_)kYn!m.'~>
+ZMspZ_#FN8o3$"Irr`5k=`8lkJcF!p"7U8Tq=agkrr)FkDh7qMrrVqr%Y=Y2s5!\TK(HDPl^COu~>
+ZMspU^]+B,<c>bQ!qTH2JcC<$c2Rn8EI%BPrrVdmDh7qMrrVqr%"\G0s5!\TF7ZL8kEJSh~>
+ZMsp]_#FMrF#h\/rrMJfqgSWt_<Cn$ic@-.JcC<$c2RqBOAN@^p\tBcic@-.j8T/HXS[JJJ\cp;
+\GlWmGB8?8JcFR+!/0sW!q2XSJ,~>
+ZMspZ_#FMoF#qV,rrMGeqgSWu_W_"%hfCj(JcC<$c2RqBO&37]p\tBbhfCj(j8T/GXS[JJK#3*=
+\GlWnGBJK:JcFR+!.sgN!pc:LJ,~>
+ZMspU_#FMrF#h\/rrMJfqgSWt_<Cn$ic@-.JcC<$c2RqBOAN@^p\tBcic@-.j8T/HXS[JJJ\cp;
+\GlWmGB8?8JcFR+!-@b6!p>e?J,~>
+ZMsp]_#FJqJ#MB,!UQobIfY,:kl1_DJ#IquJcEpn"4`^LqtL*mnD\qrir9&GXS[JJJ\cp;\GlWu
+\`SJCJcFR+!/0sW!q2XSJ,~>
+ZMspZ_#FMqJ#N>+rrMGeqgSWu_W_"%iI@g)JcC<$bl7dqQ+QqfrrhiMJ#N>+rrMGeqgSWu_L_`s
+rrVZ!kCNYas5!\TK(HDPl^COu~>
+ZMspU_#FJqJ#MB,!UQobIfY,:kl1_DJ#IquJcEpn"4`^LqtL*mnD\qrir9&GXS[JJJ\cp;\GlWu
+\`SJCJcFR+!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]`r?=TKA,aCs8RT:JcC<$LAqA)R)/a=rrVo'^[qI+mXP-6!UbI(rrM,RqgS[Km(`LK"+cc_
+oDS[jc$uhmrrqhhLOYE%rr;kF!1<N\!5JG]"H1IaW5JT6!n4*sq#C5@#ds^4J+!@:J+!46qgSX)
+bP;)FrRdcsK:LHggn;FZrr3E(Mm<<Z[>TNiZ1n:;qL8P"s8.9LMp).8LWBAn"4<:@pA"Xr^UNq:
+s82PuMgpYuqu-O#m\knjOMUts`VP&egAcZ3p;m78p:%f#rrMP;f)G`'o=Y4oS5+S~>
+ZMspZ`r?=UK@oR@s8RT9JcC<$LAqA)Qb`O:rrVo&^[qI+m=5$5!UYC'rrM,SqgS[Lm(`LK"+llb
+oDS[jc@<"prrqkkLOYB%rr;kF!13H[!5JG]"cLRbWP\Z6rrUZJe+it?IgEF]s*sG9s*sG5s8.9H
+Mp(nq$iJVLKnPuEqV7aXqYpL'qi.o]q6l32M6Q[Q`qk/cgAh&""cLS(^PKu0rr^Z2[eBLr%)97E
+s8Vrg[#9En]_h[-#k+dKIuhJHs2Onb"PWm*[e@fB!qs(;PQ([NJ(FW"K(HDPl^COu~>
+ZMspU`r?=TKA,aCs8RT:JcC<$LAqA)R)/a=rrVo'^[qI+mXP-6!UbI(rrM,RqgS[Km(`LK"+cc_
+oDS[jc$uhmrrqhhLOYE%rr;kF!1<N\!5JG]"H1IaW5JT6!n4*sq#C5@#ds^4J+!@:J+!46qgSX)
+bP;)FrRdcsK:LHggn;FZrr3E(Mm<<Z[>TNiZ1n:;qL8P"s8.9LMp).8LWBAn"4<:@pA"Xr^UNq:
+s82PuMgpYuqu-O#m\knjOMUts`VP&egAcZ3p;m78p:%f#rrMP;f)G_ko;r)WPY-H~>
+ZMsp]r;QosZ%IhBd/OA3BA2K.s8N)Ug]%>m]Cs\Qs24j9%K4kHKqR6$s82PhK87#:rs\1cItO]o
+s8VhlK87#:rrBb2Ih8.*s8V#QKpL-bs81-.KqR6#rs[h]KpL-bs8CNRK87#:rrh>GJ!Aghrrq\\
+ItO]or;QfWJ,TBVi1u'mdJa+;`KGk>c2%><s24g8&)a7;K;e\Is80'RLUmHbc22tjmeHedoYluG
+QHf7(s8U"9rrqo(M2Ae2o)A]FrVm#tZ%IhBY5\Y#N`Npnh>[M2mcj`QmVdUHrrM7Bqu6]R!:9^u
+i0n_&0fa;rVX/deCNFQ8=DsT*rr[0J1&LtM$hJRGF)PP\^&S*4A,UHKOSAbVIkba<EsmQ>i+-io
+s8W%^<knG0!<?X.EsT&NrrCpUrrCpQrrN11C]8AUJ]IQc$e'T9F`Ur3akC?7eGfIZ]bIIGW)dt`
+Dc2i"_/j[-!<.$AgA_._rGrF!a8^VpHh.4:qiDM1meHf&IrFcTqnIqjDf]YsPl(L\o64AZDduDQ
+s1rbt@fZLL"PWkUDsl9X!Jg+7rrVV,J,'$F_n5X8rrL#ml2LqHP^eqSmb@aBL[Od6!T!hNrrU*M
+pA"XloYloCQI#I"rr@`D]`RYm:4N~>
+ZMspZr;QosY_._Bd/OA6A_?$(s8N)Rg]%>m]D'eS!rg*Urr4/?eX;,ah#IENor<Y"\GcI-l_&f]
+WqHDlor<Y"\GcI-]`!=&SD=/Ehkc'ndJX%@c^'9WgA_-Phkc'ndJX%CeZa[]])M^4j-,%XhZ!NY
+l_&f]WqH;i!TAP,rsdk^L6g6bs7OBpKU:![rr3'!_o2NR&)X4<K<"bIs80$QLV!NccMN(kmJ-\c
+ou</JQd5F+rrW2;`;]c?n[j[9\aK(h!W@lRrri5'K87%@rri+U<PA=drrIoDl2LhPD1D0W!TQ6<
+rrLjSm/I^VRr`@"3HK8=l[LX)F)u;)E1$V(")eZ+qu6U'o6FV]DdcASs8N(/rGqsup\t;E0l-c0
+$\67SAT6r7s88$\^\Ig0!+YtK#d44-!8IPR!8IDN!WZ_Grc8*j`q]QAdXGbMFCK=5g1OgBrr3PB
+(omV5=*&S*;j76uF)tgkrc81orr?R-Et*Z>s*kB(oDejfNtcHuq#;@aD=.B"]nKU+EGJ[Aqu?]f
+H!PE.@84K9_K0d.!<.$Bf`(qgmF_F>L[Xj7!psiSq#:E5]D)%!!rg)ol2LqIPC\qSmb@aBL[Xj7
+!S[VKrrU*Mp\=amou3#EQI#F!rr@ZB[K>c`9n3~>
+ZMspUr;QosZ%IhBd/OA3BA2K.s8N)Ug]%>m]Cs\Qs24j9%K4kHKqR6$s82PhK87#:rs\1cItO]o
+s8VhlK87#:rrBb2Ih8.*s8V#QKpL-bs81-.KqR6#rs[h]KpL-bs8CNRK87#:rrh>GJ!Aghrrq\\
+ItO]or;QfWJ,TBVi1u'mdJa+;`KGk>c2%><s24g8&)a7;K;e\Is80'RLUmHbc22tjmeHedoYluG
+QHf7(s8U"9rrqo(M2Ae2o)A]FrVm#tZ%IhBY5\Y#N`Npnh>[M2mcj`QmVdUHrrM7Bqu6]R!:9^u
+i0n_&0fa;rVX/deCNFQ8=DsT*rr[0J1&LtM$hJRGF)PP\^&S*4A,UHKOSAbVIkba<EsmQ>i+-io
+s8W%^<knG0!<?X.EsT&NrrCpUrrCpQrrN11C]8AUJ]IQc$e'T9F`Ur3akC?7eGfIZ]bIIGW)dt`
+Dc2i"_/j[-!<.$AgA_._rGrF!a8^VpHh.4:qiDM1meHf&IrFcTqnIqjDf]YsPl(L\o64AZDduDQ
+s1rbt@fZLL"PWkUDsl9X!Jg+7rrVV,J,'$F_n5X8rrL#ml2LqHP^eqSmb@aBL[Od6!T!hNrrU*M
+pA"XloYloCQI#I"rr@-3XTI[M8q6~>
+ZMsp]r;Qr*8onoCajL+o!7LoA\c;[0hV8&3K6-J2rri5]]iKdbs!$*D??'5,jT!Dj;Km1[`W,s^
+:31JOSH&VV;Km1[`W,sM3W<eBNnFBkOCiWCIG"SCF_#W(MrOcrOCiWCIG"SPI7eR!9$.,5DcV'c
+B)_f6G><4#:7V:_!qU=1rr3\lOCiWCIG"S5CM@p%Fij[\k.OfJrr3PhOCiWZ9!SErYtB(U9$.+T
+rG)Ht+n#.*%)$FjF_#X:s81rl<eLDO"h.rRBje7>rr`#HU^6r!"gL[@DbA-Trr_b1IJqt$!=7QH
+rrVV,J+N[@pUU2$!T!hCrt>;)oAXJ0oCMeXIqdp6oB`ka-3!oIo-%iOdf07SV)>OCma>9)s8N)I
+rUU$`p\t;EC#]-`$haDoN`O'ts6+<:kkP/Y!7Li;#lFZ%!8dbU!8dVQ!W^[.rpp0`qtU15QsR>k
+m_;q^q6a%Xo)J;N>5/%ON99lsQlPktoCLB1rq$0i!<CRHo*tBis*kYldJs7-Gnb2bq#;@aDsmYT
+D`+?MoA5id_>jP326lH7dTSs:qt'F-!<2TirrN1=mb%O?#i>1Q!q'uVq#:DJF7/i'"T.>p<X@si
+"`IFc>%Y(prrED^oD\jJ!;HKpK6-JUrs$)E?uo^uc1Cr8K_)kYn!m.'~>
+ZMspZr;Qr+8o\cAb0g4p!mgo>])Vd1gY;`0K6$D1rri5]]N0^bs!$*E?>s2-jT!Dj<HiL^_Z0R[
+:N^_SRfEDT<HiL^_Z0XK3<!\JNS"3iO(WTCIFnMBG%Pl,MW"NoO(WTCIFnMOIS+Tu9$726EE.9g
+C&S)1Gu&R(:R_7^!qU7/rr3\lO(WTCIFnJ2Che-*Fij[\k.F`Jrr3PhO(WTX9<eHrZ:]+T9$71T
+rG)Hs,454+%K3qUC3F33aoD8#]N0^brs#uCB51n^rq??opXZ&GrVm&,8o\cAb-1gImr*UOh#@B\
+h<Fq@m;7@ErrMf(qu6]O!:9^urV,pCBR04@q#5bViq)d/[8eRQrrhp9CC&;drsPV^ZK^i)>=AGi
+!7Cc:!;6*d!e4nCrppNiqYH4R_Z0YuCi8J3rrE,IrUU<js8N)Rs8N)Rqu6]tdGk/s!VH6`ru[S5
+\F8n$>`/<`:Q4oFo0lsZs"K>npZIndp&"@Pd/a1;"9&6"dJ`YGo_ST;'4oSks5S><D=.,u*Ihqn
+s3ba@UuCk!QS-)Rs.hW[l0lu'7/d#So?dR;o*#$l!,_,UrrED]oD\mZD1D?\!eYO]q#:Kok.F_%
+l2Ls-<I%e_Zi8b[!=7NQrrLjSp\t;IEpic'#QD>G@WZ%#bk(i7K(HDPl^COu~>
+ZMspUr;Qr*8onoCajL+o!7LoA\c;[0hV8&3K6-J2rri5]]iKdbs!$*D??'5,jT!Dj;Km1[`W,s^
+:31JOSH&VV;Km1[`W,sM3W<eBNnFBkOCiWCIG"SCF_#W(MrOcrOCiWCIG"SPI7eR!9$.,5DcV'c
+B)_f6G><4#:7V:_!qU=1rr3\lOCiWCIG"S5CM@p%Fij[\k.OfJrr3PhOCiWZ9!SErYtB(U9$.+T
+rG)Ht+n#.*%)$FjF_#X:s81rl<eLDO"h.rRBje7>rr`#HU^6r!"gL[@DbA-Trr_b1IJqt$!=7QH
+rrVV,J+N[@pUU2$!T!hCrt>;)oAXJ0oCMeXIqdp6oB`ka-3!oIo-%iOdf07SV)>OCma>9)s8N)I
+rUU$`p\t;EC#]-`$haDoN`O'ts6+<:kkP/Y!7Li;#lFZ%!8dbU!8dVQ!W^[.rpp0`qtU15QsR>k
+m_;q^q6a%Xo)J;N>5/%ON99lsQlPktoCLB1rq$0i!<CRHo*tBis*kYldJs7-Gnb2bq#;@aDsmYT
+D`+?MoA5id_>jP326lH7dTSs:qt'F-!<2TirrN1=mb%O?#i>1Q!q'uVq#:DJF7/i'"T.>p<X@si
+"`IFc>%Y(prrED^oD\jJ!;HKpK6-JUrs$)E?uo^uc1Cr8F7ZL8kEJSh~>
+ZMsp]r;Qp`GOFTs@ab8fO8sLYmXP9:!8dbQZ%mt1p\4\;kconsXQJ<Be,THgY3+rQLP;hl`C2ke
+m/?gdLP)Q"s8RSjMgr:ZLP*/$rrhi!D(0u6s!"%<ZKe)hYksA&T_%Gq>6!jrV"=#5-3*]_T_%Gq
+>6"UcOT+N"nGE6cBs[6FQHT/a@*.iCCTRQ9Bs[6FQHT<">'KDs>%7O'%))DS#kS)]%&EL_N$\H&
+!gGtNrr3\4Bs[6FQHSuO@asnb>`f!T[;@@Brr3P0Bs[7!PaMLN4a6>V>%7O/rosR=:71hV([cc^
+eF:@\OT4gXD(0u7s7q.Tg>6Fiq=agjieUJ4rVm$aGOFTs@^#e5mVdUPrsAYTS;!9Tqu<V&rr3_#
+_>jD;LP)Q"s8RT"R"(4Ks,-l$gA([_kconsXQK5c^]4?-\%h?LAu^QNchmM;$1<<Cs1sVCPdpeY
+rrVV,J,TBKIrFcSrrV=s"TJE(\IdUDJ,]HK23e(>"k%JlrrCpHrrR[gmed"i]iLHts1_[%rV6Bn
+!8dSP"T[EZrrCpQrrN2WmdpGsLK`%&s80F?qsK/?_>g/Sdf9=YV#12lpODr:rrLsVr;QcthYR6Z
+IlUo6s8T]R3H+?\rs!skmf/_^M#I>XqdNn3s#$&>rrLPhrVloT!;uiu!,q<#s!%EmS;!9TqpV_%
+s8U9Di;M63LP)Q"s8RT"R"(4Ks,-l$gA([j_2Ef"VHeWNkconsW8dir76@I7kconsW8djWn?m*^
+!:'Rho*i>,`<^nfr;Ru>esqG[chl1ogAh2rXPj'.S;!9Tp](8CesLrKf)LX.GM;il,/K1ePdpeo
+s6-_CKrF#2`C2kem-(^0KrF#2oQs]`n@_qeoD\fDo=Y4oS5+S~>
+ZMspZr;QpaH0sd!A^^SiNrX=Tm=509!8IPNZA4(4p\4\;kd$#!Xl\<BeGoQiYib/TLk`%n`^W"e
+li$^dLP)W$s8RSiNIe[`M1`>%rrhi!D('o5s&YdrZg+5lZMTS)T_%Jr>Q<jrV"=&6-NEfaT_%Jr
+>Q=^gO6PurnG<0cBX7'CQd#>c@EIuECT[W;BX7'CQd#K$>C#W!>@mj+%_VPS$Le#X%]&^bN$eQ(
+"9"HN!<3!4X(\g,_O&L?IUgmt_HW*$n?m*]J,]HZX(\g,nW]LBs#t_qk?DNtq>T[]fh@e.rtk'O
+A(:%c>EAgR[;@=As8VnFA_GmPI/!@7"6#)6!<)p$5'cPY>@k#<!psiSqu7!$esqG[d/3jA[/U(?
+Qbre"ZA4(4p](8CesV)MeGkL.FkHKh($MrZL99S2[_MkBp9qa'D.]i'Q-T7$rsA(Bs8TrqJ!7;@
+l2LhPD1DNa!e5(Srr3&^C'ah="Lo#u."2*p!B-2@rrp\jqu6ZNo)Ac@D=.6##ea9(rVsW9Qi6^Z
+!<CmNrriDWs8N)Rqu6]tg[4V4)M_J@rVu`+]DCoJ=Mb$3,gu_m&>K(%s7Ls9rr3#R!;uit!8IAM
+$@b'EVZ6\.FZF=+q#:PJD=.=j?AAFY#5_n9s8P!ArVlrEFo21<!S[VPrrN1;mJ-]*rRRKmQI,NX
+Y1`jTbH9_$f!:'`WqZPnJ(C$=O4=2h!-Qrhruf1<Iu1"+J,e]9LP;\cs2IMhVsENMLP;\cs8VSr
+D(#DLrs/-*]_B>OI/!R=,5p)_KpL*_e#qC(s3%P&rRRKmQI,C+s*rUfJWJ=\N<"+Rq#;PTNIR/#
+!<<)^Y_Rq2iW$ne3iD<,Y_Rq2iW&Lq=j-?K=d&CV!.sgN!pc:LJ,~>
+ZMspUr;Qp`GOFTs@ab8fO8sLYmXP9:!8dbQZ%mt1p\4\;kconsXQJ<Be,THgY3+rQLP;hl`C2ke
+m/?gdLP)Q"s8RSjMgr:ZLP*/$rrhi!D(0u6s!"%<ZKe)hYksA&T_%Gq>6!jrV"=#5-3*]_T_%Gq
+>6"UcOT+N"nGE6cBs[6FQHT/a@*.iCCTRQ9Bs[6FQHT<">'KDs>%7O'%))DS#kS)]%&EL_N$\H&
+!gGtNrr3\4Bs[6FQHSuO@asnb>`f!T[;@@Brr3P0Bs[7!PaMLN4a6>V>%7O/rosR=:71hV([cc^
+eF:@\OT4gXD(0u7s7q.Tg>6Fiq=agjieUJ4rVm$aGOFTs@^#e5mVdUPrsAYTS;!9Tqu<V&rr3_#
+_>jD;LP)Q"s8RT"R"(4Ks,-l$gA([_kconsXQK5c^]4?-\%h?LAu^QNchmM;$1<<Cs1sVCPdpeY
+rrVV,J,TBKIrFcSrrV=s"TJE(\IdUDJ,]HK23e(>"k%JlrrCpHrrR[gmed"i]iLHts1_[%rV6Bn
+!8dSP"T[EZrrCpQrrN2WmdpGsLK`%&s80F?qsK/?_>g/Sdf9=YV#12lpODr:rrLsVr;QcthYR6Z
+IlUo6s8T]R3H+?\rs!skmf/_^M#I>XqdNn3s#$&>rrLPhrVloT!;uiu!,q<#s!%EmS;!9TqpV_%
+s8U9Di;M63LP)Q"s8RT"R"(4Ks,-l$gA([j_2Ef"VHeWNkconsW8dir76@I7kconsW8djWn?m*^
+!:'Rho*i>,`<^nfr;Ru>esqG[chl1ogAh2rXPj'.S;!9Tp](8CesLrKf)LX.GM;il,/K1ePdpeo
+s6-_CKrF#2`C2kem-(^0KrF#2oQs]`n@_qeoD\f3o;r)WPY-H~>
+ZMsp]rVm)n#ho=YYoM3l&<Hm9g>2i0rrCpUW*4Oh:7V+Z/Gl5JEH,0Vb@[";n9]*3Ug.nZ>,&i%
+4/hMpW*4Oh:7V@a!-a3%3Hp*^3V2M8?hDU?:4N<Dq0d8Ls4CqColU9's8U(Qs5n7os8TJ@s6B[R
+s8U(Qs8NpSIt+ECqtl"NR"^X6m.GLFp]'5iM>Mp1R"^X6m.l'LgAh2X*<5V[qu>(QoDdrkp](9$
+'`S+a]h5(#s8VtK>aU5,]Bo6@BAE=)>`JdUc)+6cs8VtK>aU4tSD+#7#ho=YYoN]A!fL^cq#;/u
+IqRR4a]si*oZa7.J,fQE\\7t*Dh%TVrr_PkS,iQg#4i,Ss8T>DYQ"[jD1DH_,1D*YG@5R<s*m33
+s6:H/s/9+JF&&8*rr@7uInj>MMZ@tTq>V6-Ug.nZ>,(;#J,fQ:Dh%1n2fj%DER":Y$/P[^_+nTd
+F&i;*rrVV,J,TBQIr4KJqt.R02?*U^?;CNE.Js/:"QK@Z"Rc<i!8@AJp\t;ED<h)s$2snfD/JM8
+PZl!!rrE,RrVQTo"T[EZrrCpQrrN2SlM^S[rV6BsZrge!Ze4pLrrpe\Cpc!Zrr3.:7=UuLlMUY_
+h>mKR!<CjOq[EH'IpQrBo)4_q@W1]0rs!skmeM3LhYdBW\JYA<"QK@Z!:Kgc!T!hSrrN1=meHf+
+dt):Y@!0`/?Cq2hJS3]cJQdDA:7V@a!-a3J:1!sY!-d/mruo3RAp8B..t@Gl:1A9HT)6Jq4/hA=
+:1A9HT)8Q[c)+59lMh+\J,B8o%"J*Ns!#pCCNj0/c+dSVs7CkTg=(UgG@5Q`s8N(CLOW'*s,-l$
+gA1an_+nTdF&i;@qkQtrF',%2`C2kekbLs_F',%2nuB%ns4V"?oD\fDo=Y4oS5+S~>
+ZMspZrVm)n#h]1WYTVBo&<?g6f\6E+rrCgRWa0mk:Rq4[/Gl;OEH,3Wb%?n:nU,94VI+=_>GAu(
+3iD;nWa0mk:RqIb!-a9*3d69b3:lD7?hDU?9n33Cq0d5Js4:qFolU9%s8U%Ts5e+js8TGCs6B[P
+s8U%Ts8O!WI=\EFqtl"MR"g^8mIbUFpAa,iMu/-2R"g^8mJ20Lf`1uU+TM%_qu+kMn,MKdp&G'!
+)#jOe\k/[ts8VtK>F:/,]^>EAB%m%$>`SjVc)+3bs8VtK>F:.tT%j;:#h]1WYTWlD!fLX_q#;/t
+IV.=/aBXc*oZa7-J,fQE\\7q'DLM9Qrr_MkRK3?e#4i,Qs8T;GYQ"[jCk)?^,1M6\G%#O<s*m62
+s6CN1s/K@MF&/>+rr@8"Inj;LN<"+Rq>V6-VI+=_>GCA!J,fQ9D1Cqi2KNtDE6\1X$/5I[_G=li
+F&rA+rrVS)J,TBQIr"9Dq=D7.3<&pa>u(ED.f',7#3#O\"o[ogrrC[Lq#L<drrR[ckl1AbqYgHW
+D/JJ7P[)0$rrE,OrV?Hm"T[<WrrCgNrrN2Pkl1AYqYg3h#..HAOL*R3rr3/K@r8Y0NrK%^Bh!TH
+`9[@$!S[VPrrE,OrV6p!rVq@RD1_BWOa(AQmJ-\cIr4TIH?%d=rronNs7$<PrVlrtn,<7c!S[VP
+rrN1;mJ-]*e:VO[@<Ki0?_.2hJS3]dK3`bD:RqIb!-a9L:0mmZ!-Qriruo6TBm4]2.t@Gl9k&*D
+Sbg>q3iD/:9k&*DSbiBYc)+28lMh+\J,B2k%"7mJs!#sFCNa-/c+dVVrq1hTg=1ajG%#N`s8N(C
+M189+s,@#$f_POl_G=liF&rAAqkQqqEEA_-`^W"ekG1g]EEA_-nu8njs4M"BoD\fBo<n_dRSA;~>
+ZMspUrVm)n#ho=YYoM3l&<Hm9g>2i0rrCpUW*4Oh:7V+Z/Gl5JEH,0Vb@[";n9]*3Ug.nZ>,&i%
+4/hMpW*4Oh:7V@a!-a3%3Hp*^3V2M8?hDU?:4N<Dq0d8Ls4CqColU9's8U(Qs5n7os8TJ@s6B[R
+s8U(Qs8NpSIt+ECqtl"NR"^X6m.GLFp]'5iM>Mp1R"^X6m.l'LgAh2X*<5V[qu>(QoDdrkp](9$
+'`S+a]h5(#s8VtK>aU5,]Bo6@BAE=)>`JdUc)+6cs8VtK>aU4tSD+#7#ho=YYoN]A!fL^cq#;/u
+IqRR4a]si*oZa7.J,fQE\\7t*Dh%TVrr_PkS,iQg#4i,Ss8T>DYQ"[jD1DH_,1D*YG@5R<s*m33
+s6:H/s/9+JF&&8*rr@7uInj>MMZ@tTq>V6-Ug.nZ>,(;#J,fQ:Dh%1n2fj%DER":Y$/P[^_+nTd
+F&i;*rrVV,J,TBQIr4KJqt.R02?*U^?;CNE.Js/:"QK@Z"Rc<i!8@AJp\t;ED<h)s$2snfD/JM8
+PZl!!rrE,RrVQTo"T[EZrrCpQrrN2SlM^S[rV6BsZrge!Ze4pLrrpe\Cpc!Zrr3.:7=UuLlMUY_
+h>mKR!<CjOq[EH'IpQrBo)4_q@W1]0rs!skmeM3LhYdBW\JYA<"QK@Z!:Kgc!T!hSrrN1=meHf+
+dt):Y@!0`/?Cq2hJS3]cJQdDA:7V@a!-a3J:1!sY!-d/mruo3RAp8B..t@Gl:1A9HT)6Jq4/hA=
+:1A9HT)8Q[c)+59lMh+\J,B8o%"J*Ns!#pCCNj0/c+dSVs7CkTg=(UgG@5Q`s8N(CLOW'*s,-l$
+gA1an_+nTdF&i;@qkQtrF',%2`C2kekbLs_F',%2nuB%ns4V"?oD\f3o;r)WPY-H~>
+ZMsp]rVm)]!;lfrecaD#&-1Seh>mTU!8dT)T_%T9-2768/GF?fd-.L?mX90?b@Hq3G>urQWk&"V
+DsmRg/YM_'PU6)(!1<Z;!1<Z;!932A:$uqLs8VS.IJs32D1VM:(o6cgIfTNGmf3$p>'p;@(o6cg
+IfTNC*,C%B7<?fGF#S/_??afmKjMsj[6K03F#S/_??afdEII`as4.>Os!3(l@fQK*mf3$p>'p;L
+g.nI#!<<)iF#S/_??afs[ocs^<a`oGrtOm>J,fQ>F#S/_F%W8.iW/lUs4.>OrrUV/f(T+J[ocs^
+<a`oGrrVV,J,K<K^M-lUoD\jJ!<3!&iW/lUs4.=VrrUYWMu<T!rKLp9nA/@ipX0K,s/7C<q^nK4
+mZ]$lrr@Q:s/ZM+rrCpNrtkER<7'j/\a"*_s8VM*J*q5E^$N:1OSekR$/P[^:0uZKhI6K_rrCXI
+IfZS7p\t<_Dh%`c'n8)^H[Bm/@\!Jul56W&c2budk5b8PrrE+8rHeOHp\t;E208bD$C'-ArKp^#
+k\kP/p\t6oC]8Y\KDtlS!8dbU!8dVQ!W["Wrd+[1f(f7Um^.CXB5*[is8Vtp82Wm)rr32ZMf36@
+CVfuL!T!hSrrE+8rHf!<f)L5<O)r_2H&d5imeHedIrFcHF*mZZrrpsRs5sCVp\t9N!;uiu!,q<$
+s!%E+B$'PY>`Rl`Fmd^lNq\cMT_%T9-27E>J+!?<#ljo)hY@*i:0uZKlC]k]qlu78iad-$s*ntT
+qlu78iad-$rr3&fDZKY6!7q$s!7plD"+O3XYl+MFrKLp9nA/@ijDT2/dqFd9P\/&,_-A;\rr@Q:
+s/ZM+rrCpNs!(9Fg@sH5!<;r$OP&Q'F7T?\DsmM-OP&Q'F7T;%pA<R%C;'QF!7q$s!nRC)o=Y4o
+S5+S~>
+ZMspZrVm)^!;ZZpdg"5"&-1JbgAq9R!8IB)T^hK8,kq-7/GFEjcKD4;mX0*>b@Qt2Gui5RWjqqU
+D=.:e0VIt)PU-#'!1<Z;!1*N9!9*,@:$leIs8VV/I/O$/CkDJ:(oHojIffZImJlpn=aU2?(oHoj
+IffZC*c6=F89N;NF#S2a?['onKjW'm[6T96F#S2a?['ofEI@T^s3h2Os!@Vl;doY)qsFFX]NKU]
+s4U5BgAq9Ro5cj4G$fI@rj>g5GZJ4krr3]"D1DTco5cj4G&p<Ps5O+Ts8UOPrVlrG3n3p(#Q;&3
+?$KCX`W#l=m;7@OrrrD8BNhV=o`"sH!<3!&irJoTs3h1Vrr`8L@Z:6b,5md?aRI#NNVCj4gAe*"
+oD:57naD\fp\t5Cn,9<ns8N)Rq#;0)Gui5RWjq;1J,fQ9D1Cqi7_S3!<fd(Prs@E[s&!.WpYKB[
+r;QcJqgSXHl1b2Zm;7@OrtU#?EHuhN94FFks6CN's2kJcs5O+Rq>UHqC&N;WY4qqtIl)0EGm]bd
+s8A<f^$'BTlhCD[!,;FX!.k.L"T[<WrrCgNrrN17EW14aPLfO/&+-cQCM7FKi;`iRVaiX6mJd+i
+gl6/bB5>B_rrLjSr;QctC&N;dPLfb`D2iS`j`ul5D=.,u#(LLWnSrpMr;QrL"TRK^p\4[ggAq0O
+!W[*)q>VZ;Q"\8._-Du\EHUWsBT;bOBV=naPU-#'!.XJ9X9ek+!8I;K)c9trpZeD+J,6C2fAC(X
+nc+)UmJ=&KfAC(Xnc&Oim;2k"rrCXIIfS!mrrr@L;dlm/rVn)?Q"\8._-Du\EHUWsBT;bOBZT\Z
+>U9(D!.XJ9X9ek+!8I;K,>hh%pYKB[s8&s]fAC(Xnc+)UmJ=&KfAC(Xnbr+Rqq6jA^&7m1f)'pu
+eGk-l[K>c`9n3~>
+ZMspUrVm)]!;lfrecaD#&-1Seh>mTU!8dT)T_%T9-2768/GF?fd-.L?mX90?b@Hq3G>urQWk&"V
+DsmRg/YM_'PU6)(!1<Z;!1<Z;!932A:$uqLs8VS.IJs32D1VM:(o6cgIfTNGmf3$p>'p;@(o6cg
+IfTNC*,C%B7<?fGF#S/_??afmKjMsj[6K03F#S/_??afdEII`as4.>Os!3(l@fQK*mf3$p>'p;L
+g.nI#!<<)iF#S/_??afs[ocs^<a`oGrtOm>J,fQ>F#S/_F%W8.iW/lUs4.>OrrUV/f(T+J[ocs^
+<a`oGrrVV,J,K<K^M-lUoD\jJ!<3!&iW/lUs4.=VrrUYWMu<T!rKLp9nA/@ipX0K,s/7C<q^nK4
+mZ]$lrr@Q:s/ZM+rrCpNrtkER<7'j/\a"*_s8VM*J*q5E^$N:1OSekR$/P[^:0uZKhI6K_rrCXI
+IfZS7p\t<_Dh%`c'n8)^H[Bm/@\!Jul56W&c2budk5b8PrrE+8rHeOHp\t;E208bD$C'-ArKp^#
+k\kP/p\t6oC]8Y\KDtlS!8dbU!8dVQ!W["Wrd+[1f(f7Um^.CXB5*[is8Vtp82Wm)rr32ZMf36@
+CVfuL!T!hSrrE+8rHf!<f)L5<O)r_2H&d5imeHedIrFcHF*mZZrrpsRs5sCVp\t9N!;uiu!,q<$
+s!%E+B$'PY>`Rl`Fmd^lNq\cMT_%T9-27E>J+!?<#ljo)hY@*i:0uZKlC]k]qlu78iad-$s*ntT
+qlu78iad-$rr3&fDZKY6!7q$s!7plD"+O3XYl+MFrKLp9nA/@ijDT2/dqFd9P\/&,_-A;\rr@Q:
+s/ZM+rrCpNs!(9Fg@sH5!<;r$OP&Q'F7T?\DsmM-OP&Q'F7T;%pA<R%C;'QF!7q$s!nRBmo;r)W
+PY-H~>
+ZMsp]rVm)a!;lfrecaD#&-1Seh>mTU!8cu@GCP*\!93hS/GlG_I?1r(s.j2?Sn,h;Wb[$D\a'3E
+Dsm7?!-`pBDZJes!8@JQ!8@JQ!8co='^fmhs8VY2IJs32D1V`)LJDo7?3pQ129CJlKBE46LJDo7
+?3pT*R*u$&Io_m)EDX^D]3La'_eNS%C,:M3EDX^D]3L`oF+*rcs4.>Orr[aK>5S=!*Q`qTKBE4*
+@WV:t!;lfcEDX^D]3La'ZrC:U<*mQCrtOm>J,fQ<EDX^DmYEUtjoG;Ys4.>OrrHVVp&>6'<*X]J
+?H)pD!q'uVr;Qo7Bi_84o`"sK!<3!&joG;Ys4.=Wrr_hT>eU(8,4p">H[g5uET6jQOT.n)s69T.
+It)A:ir9#'s8UpUs8N)Uq#;0-Wb[$D\a&U$J,fQ:Dh%1nFnG_+F`m!Frrh0YrsZU?rrKq9r;QcJ
+qgSXHlM(;[mVdURrtU#BGCP*h=Bp@Us/5p9IsV06s76BQrVm&uR,\,GDuG.cZ1n8"IlDTNIgMLp
+s8U,CNkJhlpAY-nDuP4dL]7;W!8dbU!8dVQ!W[._rdOs9f_POXrT<>9fX$'(SGW?dk\1%%rr39$
+df8UOTO'tZrr3#U!;uit!,qgc%@GfJIrDr?VS.,]IrFcMrs!skmeM3LhYdBW]bLM<"QKC[!rJAE
+rr3#U!;uiu!,q<$s!%)X4*uI$2f\8Q@`P9V_=Vk3GCP*\!94"Yc2[h#!<<'!hY@*O%))Z?(>rSM
+s59oCQ:c)`s*ntTs59oCQ:c)`rr3&fDZKY6!7q$s!7plD"Fj<QWr;nr,4p">H[g5uEUK3'a/!=`
+oQ<6BIs3gOir9#'s8UpUs8N)Uq#:@'^&J$Q_#XN8i2W*/8oO.tIrFcTi2W*/8oO.ts5^&(HaWGB
+rrCXIIfe4$K_)kYn!m.'~>
+ZMspZrVm)`!;ZZpeHXG$&-1JbgAq9R!8Hf@FanmZ!9<nT/GlMbI?1l$s.j8AS7T_;XDE<G\*3jA
+D=.">!d0!BDZJht!8%8N!8%8N!8H]:'^]aes8VY1I/O$0D1_f*LJ`2>>mUH029LPmJ`Zq3LJ`2>
+>mUK'RF;'&JQS6-E)F^F\m(O$_e`h,CGLP3E)F^F\m(NlEd[]_s4%>Qrri:M;d9.uruK77F+NHQ
+o4<"7f)YXFmr2.Fn%)_irj5X0G>qqgrr3]"D1DTcn8M7Gn*bubs5a7Vs8UURrr3&u@<qSH#Q;#/
+>^'.S`W#l=m;7@OrrrD9BihA6o`"sH!<3!&jT,,Vs4%=Xrr_hT?G6::,5$+@H@L,tET?pUO8hh)
+s6B`/It)A:j8T,'s8UgRs8N)Rq#;0-XDE<G\*33rJ,fQ9D1CqiFS,V)F*-[Brrh'VrsldBrrKn8
+r;QcJqgSXHl1b2Zm;7@OrtU#AG(5!g=Bg4Rs/5p7IsD*8s6g*LrVm&sQf7rED>eqaZM4A#Il;KL
+IgVRqs8U,EO1eqkrqHEn!,_^b!/LRR"T[<WrrCgNrrN1;G5cslR+V67&,bPQo[gI":n@L`s6"%q
+Y5\G,q9o<-`hHa+p\t0ngAq0O!<@!8Igqdts*nmqEi-Nm[sr8^q#:PJD=.(CE8CHl"hGQNmf_VJ
+rrW"_iVriXgAq0O!W[*)q>VZ3Fut#"G;jO1R:O@6B>O7a4*?%&DZJht!6kKCgAq9R!8I;K!=ljC
+rtaL"J,\<*QBb'ZmJhZQmJbtCQBb'ZmJd+em;2k"rrCXIIfS!mrrr@N;d6=$rVn)7Fut#"G;jO1
+R:O@6B>O7a4*lC#2ZVn<!6kKCgAq9R!8I;K!=ljCruSrUs8LlUQBb'ZmJhZQmJbtCQBb'ZmJm4I
+VgE`ro)/Lff)'pueGk-l[K>c`9n3~>
+ZMspUrVm)a!;lfrecaD#&-1Seh>mTU!8cu@GCP*\!93hS/GlG_I?1r(s.j2?Sn,h;Wb[$D\a'3E
+Dsm7?!-`pBDZJes!8@JQ!8@JQ!8co='^fmhs8VY2IJs32D1V`)LJDo7?3pQ129CJlKBE46LJDo7
+?3pT*R*u$&Io_m)EDX^D]3La'_eNS%C,:M3EDX^D]3L`oF+*rcs4.>Orr[aK>5S=!*Q`qTKBE4*
+@WV:t!;lfcEDX^D]3La'ZrC:U<*mQCrtOm>J,fQ<EDX^DmYEUtjoG;Ys4.>OrrHVVp&>6'<*X]J
+?H)pD!q'uVr;Qo7Bi_84o`"sK!<3!&joG;Ys4.=Wrr_hT>eU(8,4p">H[g5uET6jQOT.n)s69T.
+It)A:ir9#'s8UpUs8N)Uq#;0-Wb[$D\a&U$J,fQ:Dh%1nFnG_+F`m!Frrh0YrsZU?rrKq9r;QcJ
+qgSXHlM(;[mVdURrtU#BGCP*h=Bp@Us/5p9IsV06s76BQrVm&uR,\,GDuG.cZ1n8"IlDTNIgMLp
+s8U,CNkJhlpAY-nDuP4dL]7;W!8dbU!8dVQ!W[._rdOs9f_POXrT<>9fX$'(SGW?dk\1%%rr39$
+df8UOTO'tZrr3#U!;uit!,qgc%@GfJIrDr?VS.,]IrFcMrs!skmeM3LhYdBW]bLM<"QKC[!rJAE
+rr3#U!;uiu!,q<$s!%)X4*uI$2f\8Q@`P9V_=Vk3GCP*\!94"Yc2[h#!<<'!hY@*O%))Z?(>rSM
+s59oCQ:c)`s*ntTs59oCQ:c)`rr3&fDZKY6!7q$s!7plD"Fj<QWr;nr,4p">H[g5uEUK3'a/!=`
+oQ<6BIs3gOir9#'s8UpUs8N)Uq#:@'^&J$Q_#XN8i2W*/8oO.tIrFcTi2W*/8oO.ts5^&(HaWGB
+rrCXIIfe4$F7ZL8kEJSh~>
+ZMsp]rVm)j!;HNnc3Vht#lri^h>mTU!8cT0!!(UFru'[G/L5Pos1)U;LM#EChLdC*GM<(HDsm%3
+qZ%#TrrCpUrrCpUrrCp=rtOm>J,fQCGC05ek%fVLmbU81(k`J"rr\K&C[_9&"l;QG(k`Its!#Hq
+KCa/.p]'AkKE(A$+Uh+<L\#S2p]'AkKD0S:p](9=#lO](V$QhpruI=@C[_<'k7GZ-ec>IEo5f-M
+s5n*Ls,0IZo;"sJrr3]#Dh%feo5f-Ms8U@Ms6fs^s8U@MrVlmA^%MC0Mb1JNUe.*UrrVV,J,B6J
+dT1kpo`"sK!<3!&mf<+^s3:nSrr_CrA)dFd!Uan(!"!Gls'oR=(q'D#qZ%#TrrCpUs5!bUrrCpM
+rt+%>/L5PomVdUTs6afTmVdUSrrR[ghYI0Sh>mQUf)G[Mec=t7!q'uVrVm7TDsmZ*pT7%:s8RHD
+!!GXgrs6pKrrr-O`r?%qo)Ac@DsmK%"l<R0Uggb*rrE,VqYp^!hZ*TUhY[<S!8d/9rrW)Cdf07K
+hHkF#rr3%L!8d_T!V`GhrrTk6n,E=fh>mKR!<D!QrsF6odW:MKGKkVUmeHedIrFcTK4i4%rro5J
+s8NAMrVlrn0uj4m!T!hSrrN1=meQk`mVi"'$#Ah2A$Lr(g?rnV!"7BX!8dbUh>mTU!8dMN!<C^M
+rtam8J,e)<0gR7,mf.cTmf1jV0gR7,mf*4fmV`*frr])'J,B3E!Uan(!"!H+Z"(%sB%lZkqZ%#T
+rrCpUs5!bUrrCpNrrE,Nrr4"i!<<)MD_XO,DsmXTDsmYVD_XO,DsmZ*a]:^0p[\=aK_)kYn!m.'~>
+ZMspZrVm)f!;$6jcOA5$#lr`[gAq9R!8HE.!!(XGru'[I/gPSls12d?KkK9BhM!R-FkH_DD=-e1
+qZ%#UrrCgRrrCgRrrCg:rtOj;J,fQAFa<f_kA>qQn)$P:*.eb$rr\Q(D<q3$"lD`O*.eb!s!#Kr
+KCNr*p]'>hKE(D',S3aCL[fA.p]'>hKCsA4oDej:%/g,,V@<4uruICBD<q6%k7ki*dfB":mr<RG
+s5dsIrJO@Zn"`XJrr3]"D1DTcnSrdIs8U7Js6B[Vs8UCRrr3&s+M.:H#Q'EQ\F64eSc8Wjm;7@M
+rr^\PJc#*>!S[VRrs%choDej:%']a6k@nGbr;QfdDu9SACY/StAcEaYs53\R$ePCYg].<.!<<'!
+g\:^`hM!R-FkH(uJ,fQ9D1CqiIJs3EI;e$=rrh'VrrC[MrrL^Ol2LhPD1DNa$\*$\s8Vhp81=N<
+H2IXF7K<5jbPhGEo.\)^!8I)E!e5(SqYp`U@<nYW[.aM#!8IAM"T[<WrrCgNrrN2TmI^D[q97:d
+rr_%^GPD+:!e14)rr3#jVZ$Mr\cD3urrLjSr;Qctg\UpWIr3MQOf3EHIr4TJrs!simJVTI_u0N<
+U+H?A#g<2H!qS+`rr3#R!;uiu!,_-!rrMS,qu@%=l`t*-NG7,8Du0MBfDbj*s8UgRs8N)Rq#:?p
+fDbdclYD"Me8I*/.W+SQIr4TQe8I*/.W+SPrrVS)!9X:`V@8%QrVloeDu9SAC[89;ZAiSPmr/('
+$ePCYg].<.!<<'!g\CdL!8%5M*S1;ks3tsB67Qj>s*nnQs3tsB67Qj>s8U5C6EKkNrr@ZB[K>c`
+9n3~>
+ZMspUrVm)j!;HNnc3Vht#lri^h>mTU!8cT0!!(UFru'[G/L5Pos1)U;LM#EChLdC*GM<(HDsm%3
+qZ%#TrrCpUrrCpUrrCp=rtOm>J,fQCGC05ek%fVLmbU81(k`J"rr\K&C[_9&"l;QG(k`Its!#Hq
+KCa/.p]'AkKE(A$+Uh+<L\#S2p]'AkKD0S:p](9=#lO](V$QhpruI=@C[_<'k7GZ-ec>IEo5f-M
+s5n*Ls,0IZo;"sJrr3]#Dh%feo5f-Ms8U@Ms6fs^s8U@MrVlmA^%MC0Mb1JNUe.*UrrVV,J,B6J
+dT1kpo`"sK!<3!&mf<+^s3:nSrr_CrA)dFd!Uan(!"!Gls'oR=(q'D#qZ%#TrrCpUs5!bUrrCpM
+rt+%>/L5PomVdUTs6afTmVdUSrrR[ghYI0Sh>mQUf)G[Mec=t7!q'uVrVm7TDsmZ*pT7%:s8RHD
+!!GXgrs6pKrrr-O`r?%qo)Ac@DsmK%"l<R0Uggb*rrE,VqYp^!hZ*TUhY[<S!8d/9rrW)Cdf07K
+hHkF#rr3%L!8d_T!V`GhrrTk6n,E=fh>mKR!<D!QrsF6odW:MKGKkVUmeHedIrFcTK4i4%rro5J
+s8NAMrVlrn0uj4m!T!hSrrN1=meQk`mVi"'$#Ah2A$Lr(g?rnV!"7BX!8dbUh>mTU!8dMN!<C^M
+rtam8J,e)<0gR7,mf.cTmf1jV0gR7,mf*4fmV`*frr])'J,B3E!Uan(!"!H+Z"(%sB%lZkqZ%#T
+rrCpUs5!bUrrCpNrrE,Nrr4"i!<<)MD_XO,DsmXTDsmYVD_XO,DsmZ*a]:^0p[\=aF7ZL8kEJSh~>
+ZMsp]r;Qp3`rH(/1"$"3!8db4!<<'!hY.$Es8Vi=q#;oBhW"Rh>'K`'CKbA4s81[4s4UY#pO@,L
+qg/>;s8Vi=s8N)Us8N)Us8N)UkPkVODh%cd'8LA_s35/Cs6eb<s8STUs8QRhkPY>chY7'MS3m8$
+SGrO7`bUA0K6QqeibO>Lmcs]Lc#99TK6QqeibO>LLMOp0s-thDmn3TZ"p!ids'n(PrVll2qZ%1d
+`IiC+s5IgLo5f9Us6=BLrr3&fDh%cd%YJuss8U(Ms8NYMs8STDrr3#$+nbj?kAu"Is6=BLrr3Dp
+Dh%fepRJ&Zs*o+]o`"sK!<)p$&B=bMS2%5I!m+o=r;Ru<H[GYiqr6c<s2GV`)#sX1!;HNnpWig=
+!8dbUh>mTU!8dMN(]3(Ks4UY#k&5bLs5%(3mVcn+s6=BHp\Fglh>mQmXoA>$XT7Vc!q'uVrVlqK
+DsmW)#3ot(s8Nphrq?Sm!:Tqk>5eI)V#]ua!8d;H!e5.Vq>USU<_d;epAY-nhYR6U!8dbU!8dVQ
+!W_*Fo`#6lGAHLDs7^_]p\t0oIfS@)rrVWhf)G[Nmf;hUrrLsVr;QcthYR6ZIrFb1CM/"gIrFcM
+rs!skmf0Om9)\bopF2($s&rV)rrT"sn,E=fh>mKR!W[0,q>VZ9H[GYiqr6c<ibN.@MuW[$Hh[R?
+pWig=!8dbUh>mTU!8dMN!>qs<rta0dJ+n/"k5TpLmf.cTme:p<k5TpLmf*4fmV`*jrrMR\rr3$"
+F7]A1,5Z_6qu?QQk5XFVAnm8(qg3\es81g$s8N)Us8UpUs8N)Uq#:@3XoA>>XT8CqGA$(<IrFcT
+IrFcLGA$(<IrFcTYtgDPnG`KAo=Y4oS5+S~>
+ZMspZr;Qp7_uKb.1su=6!8IP.!<<'!g[bF:s8Vi>q#;oBhrFah=a0W'CKY50s81^6s4CIupO@&I
+q0;u3s8Vi>s8N)Rs8N)Rs8N)RkPkVND1DQb'8^M`s3>>Hs6nk>s8SZZs8QXmj8Ao_htR0NSji\*
+T)SaCa)-\5KmE:ij(jGMn*BlNc>fTYKmE:ij(jGMM/1$/s.2(IlUh!RqZ,[Vs(+=QrVll3qZ%1f
+`eA^0s5RmMnSrpQs64<Mrr3&eD1DQb%Y]3"s8U+Ns8NeNs8SZIrr3#%+SGa>j)KGCs64<Mrr3Do
+D1DTcopVWRrI&\Uo`"sH!<)p$'Z9tNSi!YN!m5#>r;Ru:H$T5cqr?l>s2,D^*<6'1!;$6jpWrm>
+!8IPRgAq9R!8I;K(]3+Ms4CIuj_]MIs5%+4m;6Y)s64<Ip\FglgAq6nWrE#!WW;;`!psiSrVlqK
+D=.?&#4$%)s8O'jrpp;f!:0Yf=oJ@(V?#r^!8I)E!e5(Sq>USU=&EVhpAY-ng\UpR!8IPR!8IDN
+!W_!Bo`#6lGAHOEs7^_[p&=smIfS7&rrVWhfDbdOmf;\QrrLjSr;Qctg\UpWIr4S0CLqeaIr4TJ
+rs!simJjCj8cAYnpFM4%s&iM'rrT%tli-nbgAq0O!W[*)q>VZ7H$T5cqr?l>iFuqANW8g"H1V(9
+pWrm>!8IPRgAq9R!8I;K!?A-=rta*aJ+n5$jo9gImJhZQmItm=jo9gImJd+em;2jgrs.j]qu?Nn
+EUj#-,5HM0q>^?PkPsLTB5NY.q0@8]s81j&s8N)Rs8UgRs8N)Rq#:@7WrE#;WW<(nH"Z7=Ir4TQ
+Ir4TIH"Z7=Ir4TQZ;?VPnG`K?o<n_dRSA;~>
+ZMspUr;Qp3`rH(/1"$"3!8db4!<<'!hY.$Es8Vi=q#;oBhW"Rh>'K`'CKbA4s81[4s4UY#pO@,L
+qg/>;s8Vi=s8N)Us8N)Us8N)UkPkVODh%cd'8LA_s35/Cs6eb<s8STUs8QRhkPY>chY7'MS3m8$
+SGrO7`bUA0K6QqeibO>Lmcs]Lc#99TK6QqeibO>LLMOp0s-thDmn3TZ"p!ids'n(PrVll2qZ%1d
+`IiC+s5IgLo5f9Us6=BLrr3&fDh%cd%YJuss8U(Ms8NYMs8STDrr3#$+nbj?kAu"Is6=BLrr3Dp
+Dh%fepRJ&Zs*o+]o`"sK!<)p$&B=bMS2%5I!m+o=r;Ru<H[GYiqr6c<s2GV`)#sX1!;HNnpWig=
+!8dbUh>mTU!8dMN(]3(Ks4UY#k&5bLs5%(3mVcn+s6=BHp\Fglh>mQmXoA>$XT7Vc!q'uVrVlqK
+DsmW)#3ot(s8Nphrq?Sm!:Tqk>5eI)V#]ua!8d;H!e5.Vq>USU<_d;epAY-nhYR6U!8dbU!8dVQ
+!W_*Fo`#6lGAHLDs7^_]p\t0oIfS@)rrVWhf)G[Nmf;hUrrLsVr;QcthYR6ZIrFb1CM/"gIrFcM
+rs!skmf0Om9)\bopF2($s&rV)rrT"sn,E=fh>mKR!W[0,q>VZ9H[GYiqr6c<ibN.@MuW[$Hh[R?
+pWig=!8dbUh>mTU!8dMN!>qs<rta0dJ+n/"k5TpLmf.cTme:p<k5TpLmf*4fmV`*jrrMR\rr3$"
+F7]A1,5Z_6qu?QQk5XFVAnm8(qg3\es81g$s8N)Us8UpUs8N)Uq#:@3XoA>>XT8CqGA$(<IrFcT
+IrFcLGA$(<IrFcTYtgDPnG`K0o;r)WPY-H~>
+ZMsp]r;QqA6MKXlPgTLA!8db4!<<'!hZ$JWkN?#/q#;oBIq%-[<dX`DO;LF"s8.:Tg<s#KqgWDH
+s/8h!kN?#/s8N)Us8N)Us8N)UkPkVODh%cd'"M29mtb;ls-u)Zn'2cXs4.1irRV#K3]U^=c5<th
+ec:s'ei?dAs05UhhMY:>s-ui`hK*;_s05UhhMY:>s1)<"pZEuis8NXpmu/+`s4.1irRUoH!T!hU
+rsl;7Phq<r[Ju.RXl>^?T`4rmmVdUSrsl;7Pht7WC]FEU6MKXlPlC[`;KML1#)bpPig<?2rr3&f
+Dh%cd"c$!l]i'd[rrLsVrVm%B6MKXlPct)gl>(nHrs#E&T]_t>SGrNi(a48*rt/.4kN?#/s8N)U
+s8UpUs8N)Mq#;-,Iq%-[<dXF^;UXuk*.RBp+ctQ=8Z_^e$/P[^KG_,c]cdCRrrB1u!!--Op\t<_
+Dh%`c!e5.Vrr32jDZKgW!8d_T&,-?os5sqscKD#8C]FD7`r,#orrR[[f)=b3oD\al\Nppfp&>$m
+hYR6U!8dbU!65!#s8N-#`n(+O!;$!c#H0e,db^3\T`+llIfS@(rru@M^$!sE6N-obh>mKR!<C.;
+k7$t^IrFb_8i<:AIrFcMrtg0'mf3$6(eVg2]f@hAs8V6n>0c<-&8V7E!T!hSrrN11f)Fh4oDJV3
+W)fSSTLk[Rs,.jl^&S,2<a+\L=ulW_!8dbUh>mTU!7prF)h]'9n()CgJ+n/"k.sB"lMl?LlM#L8
+k.sB"lMgebmV`+%rrB1u!!'.rrrisumu/*Aqu7h<<hSWK8Y#h\M]>L*s8T#uT]_t>3WK*ZhZ*W4
+!<<'!f(f7eKG_,c]cdCUpNL94_*Vr&s*nhLpNL94_*Vr&l>'nTrmh)7r;Qc!qZ$]"s+L!W!q2XS
+J,~>
+ZMspZr;QqC61a7fQI5^C!8IP.!<<'!g](8Vj6']1q#;o@I:LpT=*scCOW6p+s7q(QfZmQFq1!,C
+s/K(%j6']1s8N)Rs8N)Rs8N)RkPkVND1DQb'"V;9m>#&ks.)8`lcU9Rs3gtgrR_)L3]q!>b8dhf
+f*%E.f/QgBs0>dnh2+t8s.)ubgN.#[s0>dnh2+t8s12E#oB.Nfs8*@jmtqtZs3gtgrR^uI!S[VR
+rsl>;QJIBo[/GnPXQ,aBT`4rmm;7@Prsl>;QJL:TC&e3U61a7fQN$mb;/u:/#Q'EKXQ,aBT`4s"
+m;7@Qs8@XK^q<O$rUg*jgAq3P"a*-&k9uY"rrVM%J,B6MW`PeRU.h-WrrO/cIK'6Y<E\AF>s//e
+!8IPRgAq9R!7U`C(AWAgfZmQFmr_LSmu&08m;4&1h2+\(q#:ZT!<7cj[dUpQ!;uisY582"<RgdC
+!psiSrVlqKD=.?&#467-s2+iorr3N'#a55J'OB&FU(D2ArrC+;kP+uXIq.+/k5b,Qrr]i!(6/"e
+!<CmNrriDWs8N)>rTF4\!W^9mrT=1Pq#:St5'><0P"D>FrrRZMg\q-V;(THEdnrF0rrLjSr;Qct
+a8G*/oDa;WmBfD@T`9LYmJ-\tIr4TQon+5Y_rJ<f2#%%MitPeFj.[*%rVloQ!;uiu!+XX[k5b,O
+runCDT&l\?ScA_L+AffPs/K.'j6']1s8N)Rs8UgRs8N)Jq#;:f(q/naD\.EkF_BgO6YYfbIqe0?
+F_BgO6YYfarrVS)!;c]qY582!WqlZ"q[eqZMAV3Kr;Rq?=.\NJ9V)4`N?D'3s8T*#T&l\?4TGE]
+g].<.!<<'!e+iqbL)@Af^*!FUolXp/^dDi#s*nbIolXp/^dDi#l"OYRrmq/9r;Qc"qZ$\ts+9jN
+!pc:LJ,~>
+ZMspUr;QqA6MKXlPgTLA!8db4!<<'!hZ$JWkN?#/q#;oBIq%-[<dX`DO;LF"s8.:Tg<s#KqgWDH
+s/8h!kN?#/s8N)Us8N)Us8N)UkPkVODh%cd'"M29mtb;ls-u)Zn'2cXs4.1irRV#K3]U^=c5<th
+ec:s'ei?dAs05UhhMY:>s-ui`hK*;_s05UhhMY:>s1)<"pZEuis8NXpmu/+`s4.1irRUoH!T!hU
+rsl;7Phq<r[Ju.RXl>^?T`4rmmVdUSrsl;7Pht7WC]FEU6MKXlPlC[`;KML1#)bpPig<?2rr3&f
+Dh%cd"c$!l]i'd[rrLsVrVm%B6MKXlPct)gl>(nHrs#E&T]_t>SGrNi(a48*rt/.4kN?#/s8N)U
+s8UpUs8N)Mq#;-,Iq%-[<dXF^;UXuk*.RBp+ctQ=8Z_^e$/P[^KG_,c]cdCRrrB1u!!--Op\t<_
+Dh%`c!e5.Vrr32jDZKgW!8d_T&,-?os5sqscKD#8C]FD7`r,#orrR[[f)=b3oD\al\Nppfp&>$m
+hYR6U!8dbU!65!#s8N-#`n(+O!;$!c#H0e,db^3\T`+llIfS@(rru@M^$!sE6N-obh>mKR!<C.;
+k7$t^IrFb_8i<:AIrFcMrtg0'mf3$6(eVg2]f@hAs8V6n>0c<-&8V7E!T!hSrrN11f)Fh4oDJV3
+W)fSSTLk[Rs,.jl^&S,2<a+\L=ulW_!8dbUh>mTU!7prF)h]'9n()CgJ+n/"k.sB"lMl?LlM#L8
+k.sB"lMgebmV`+%rrB1u!!'.rrrisumu/*Aqu7h<<hSWK8Y#h\M]>L*s8T#uT]_t>3WK*ZhZ*W4
+!<<'!f(f7eKG_,c]cdCUpNL94_*Vr&s*nhLpNL94_*Vr&l>'nTrmh)7r;Qc!qZ$]"s)[e6!p>e?
+J,~>
+ZMsp]r;Qoo@gE?]d/OUVhZ)F4s8N)Us6j+s#YO:Ss!u>t$kR(&s8TbqDsmZ*butMeB@d*U+^3Uo
+mofu&9'?6S!8dbU!8dbU!8co=!q'uVrr3Q,XYgAI\c;]thDkQQSH&VZqZ-Zr"Pu-=(nCU*-+,0%
+&:;+js8/`L#W]0es6bdb$sLpUs8/`L#W]0es8/p.#RGMNrs,qT!%Gqfs.&rdr;QfS!<3!.qku4T
+3O/J]lAQkh/Y)G3rrVV,J,]HWqku4T#]'27s7^"/#]otE!=6+*rs%bI+TsBeoD\akmVdUSrrq+l
+&/9?JoD\jJ!<)p#pL=I7F0>NEmVdUPrs&4n0aK4qoD\akHN<7.rt=d(#RF&cs8N)Us8UpUs8PCc
+[J9b:butMeB@d+%:'_\T<e'OU:0%cTT_J6]$/P[^s+D3h0r4m7rrVV,J,TBKIrFcSrrr.@!<6gp
+r;R(,3WK-9;@!7GK`;#J!!2ikq>UGEqZ$kJqu?]]CH8rurrE,VqYpWthZ*WQ!!2Qgq>^PCqt^6s
+qlrEq#W\mYrVlqK!8d\S#5;mM!"`Z/rVloT!;uln!"=5OIrFc7@nOlCIrFcMrsXBqmf3=Yk@5&'
+(j#HMrrq7W#QQ$$r;QfS!;ulo!!.<<rVn)9UbN-(R.L@X]fgH.s8Vhh=pPC+kPtP^hZ*W4!<<'c
+!4DV%)MAq-(i*$!s1L],:1kl*s.CN=g:]c\:1kl*rr3&fDZK&%"goKR.E:BEs!%350aK4qoDej(
+4`g5ps7`<D#Uu/(s8N)Us8UpUs8PCc[J9bAKGX\DV#^Pq]g3'%B-i31THRLm]g3'%B-i2T:Ab(l
+J+N[?K_)kYn!m.'~>
+ZMspZr;Qoo@13Qed/OUVg]-".s8N)Rs6j)!#YjLVs!uB!$kd4&s8T_oDt!`+c<C\iB@QsS,$W^o
+mo^&):$;QV!8IPR!8IPR!8H]:!psiSrr3Q,X>UJP])Vg!h`M#]RfEDVqZ-Zr"Q)<E*1Hm,-*f'%
+'R@:gs7rNG$9GEgs6kpi&6mBYs7rNG$9GEgs8/m+$k.:Xrs,tT!%c1js-ifbr;QfP!<3!.q5,hQ
+3jAM]l]*4r/tDP4rrVS)J,]HWq5,hQ$u,J9s7]q1%!DRL!rE8/o`#-]N[+l_SFca[!psiSrr3/U
+CCh8,j7E9OgAq3P"SZ=5%!A`Q!psiSqu6lpUbW9,Re-OY!dOe+rr3W"=UYR1kPtP^g].<.!<<'b
+"L@h&(!^"l&nf_o`_d-aDcM;SD,4:E/u&+8rs@E[s8RZf!&18Ml2LhPD1DNa!e5(Srr3/rG6%YW
+3;idb=ZHH]gJJ@Z+G0Ljs7u]roD/4^!.XkG#C6.Fs645W\Fok&!8IAM!s%*Us8)csli6e]!I=M:
+rs/A(64=2^VY0of!e14)rVm)nD&<6e@I*ml!S[VPs7u^(H22r,mGVJHb5Zs.mJ-\iIr4TQs7>Db
+'EB+qoDS[ngJJ@Z+G0LhrrLjSr;ZWo!Hn)6s!%351(#M"oDej'4E9oks7`<l$j]Sjs8N)Rs8UgR
+s8P@fZM=G<Jf"J)CK#`_^-W<,Bde]8TH[Um^-W<,Bde]7rrVS)!9sLe[NGQ$a5d's,57lg$7_M9
+s8T_oEUj)/pS9PO.[oQ#rrCgRs4[PRs$6dnq#;=c(]Z7e!<<)564Qk,.#%\o,$W^664Qk,.##l>
+qu?_HoD\fBo<n_dRSA;~>
+ZMspUr;Qoo@gE?]d/OUVhZ)F4s8N)Us6j+s#YO:Ss!u>t$kR(&s8TbqDsmZ*butMeB@d*U+^3Uo
+mofu&9'?6S!8dbU!8dbU!8co=!q'uVrr3Q,XYgAI\c;]thDkQQSH&VZqZ-Zr"Pu-=(nCU*-+,0%
+&:;+js8/`L#W]0es6bdb$sLpUs8/`L#W]0es8/p.#RGMNrs,qT!%Gqfs.&rdr;QfS!<3!.qku4T
+3O/J]lAQkh/Y)G3rrVV,J,]HWqku4T#]'27s7^"/#]otE!=6+*rs%bI+TsBeoD\akmVdUSrrq+l
+&/9?JoD\jJ!<)p#pL=I7F0>NEmVdUPrs&4n0aK4qoD\akHN<7.rt=d(#RF&cs8N)Us8UpUs8PCc
+[J9b:butMeB@d+%:'_\T<e'OU:0%cTT_J6]$/P[^s+D3h0r4m7rrVV,J,TBKIrFcSrrr.@!<6gp
+r;R(,3WK-9;@!7GK`;#J!!2ikq>UGEqZ$kJqu?]]CH8rurrE,VqYpWthZ*WQ!!2Qgq>^PCqt^6s
+qlrEq#W\mYrVlqK!8d\S#5;mM!"`Z/rVloT!;uln!"=5OIrFc7@nOlCIrFcMrsXBqmf3=Yk@5&'
+(j#HMrrq7W#QQ$$r;QfS!;ulo!!.<<rVn)9UbN-(R.L@X]fgH.s8Vhh=pPC+kPtP^hZ*W4!<<'c
+!4DV%)MAq-(i*$!s1L],:1kl*s.CN=g:]c\:1kl*rr3&fDZK&%"goKR.E:BEs!%350aK4qoDej(
+4`g5ps7`<D#Uu/(s8N)Us8UpUs8PCc[J9bAKGX\DV#^Pq]g3'%B-i31THRLm]g3'%B-i2T:Ab(l
+J+N[?F7ZL8kEJSh~>
+ZMsp]V#LM8@[r#LJcDMF!q'uVJcC<$JcC<$f`(r)o=Y4oS5+S~>
+ZMspZV#LM9AY"DPJcDMF!psiSJcC<$JcC<$f`(r'o<n_dRSA;~>
+ZMspUV#LM8@[r#LJcDMF!q'uVJcC<$JcC<$f`(qmo;r)WPY-H~>
+ZMsp]V>gYhKO`G]s+13Frr_k6F7Xt_JcC<$JcFF'!/0sW!q2XSJ,~>
+ZMspZVZ-etnV(K"JcC<$U]1GfF*$r(s+13$s+14'rr@ZB[K>c`9n3~>
+ZMspUV>gYhKO`G]s+13Frr_k6F7Xt_JcC<$JcFF'!-@b6!p>e?J,~>
+ZMsp][f6?8q>^O!KDYZNiaXF9JcC<$U&P4r/U-sDrrBJ'!!*4Tm/I+?[JBk'#daO3[9EG-!<e&F
+rrLhWq>^L$jSo87>5J:#"G=hr!SU`S!!*4TYl=^2q>^L$RK!8pq>^L$ci3uuo=Y4oS5+S~>
+ZMspZ[f6?5q>^O#L&:lQiF+.3rIP!"s.]MqX=SSig]%8Zq>^O#L$\g?fWt>R!"?46!O>l*!!*:X
+nc&XB=o&*u%-7EhfNJ(O!="8"rrLbTqZ$X$Ks:RWZMFP$%%7+qZMFP$%+"qRK(HDPl^COu~>
+ZMspU[f6?8q>^O!KDYZNiaXF9JcC<$U&P4r/U-sDrrBJ'!!*4Tm/I+?[JBk'#daO3[9EG-!<e&F
+rrLhWq>^L$jSo87>5J:#"G=hr!SU`S!!*4TYl=^2q>^L$RK!8pq>^L$ci3udo;r)WPY-H~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]UAkCHDsi*nmcsfQh>i-,JcC<$JcC<$JcD#8!/0sW!q2XSJ,~>
+ZMspZUAkCHD=)gimHX]PgAlg)JcC<$JcC<$JcD#8!.sgN!pc:LJ,~>
+ZMspUUAkCHDsi*nmcsfQh>i-,JcC<$JcC<$JcD#8!-@b6!p>e?J,~>
+ZMsp]r;Qoo@gEWeXT&HRDsi*nmcsfUmrSO/&DlUMs+gUR%K!7b$phH(s7bt[#S;(Vrs[IF!!lKk
+s8VOc#S;(Vrr@EE!"_0$s8To-$n\:Ps7`0<$phH'rsZ_9$n\:Ps8/p.#S;(Vrrg=j!%GV\rrpt?
+!!lKkr;Qf;!<)p;_+G+fV#12WN$S`]SFcdGN$/<UT_JKGG8(`?^&J$8ej9?B;XaP`!QG-5rs%bI
+,mZ)moDS^hL]7;Wicc(NF5HTi"SZC3&9EF&JcC<$JcC<$qYpPKo=Y4oS5+S~>
+ZMspZr;Qoo@0dEeXT&HRD=)gimHX]TlZN7-&Du^O!r[n2rr4/=X>C>P])Vg'lW"3%EVoe9f0KNF
+<U9\blW"3%EVoe9H2R^c3kG@k^e5.iV"t&`TIpX<[f-7+^e5.iV"t&fXC2AGFoMCDa!_'=^Ae-9
+f0KNF<U9S_!Q+p9ruAgI%PFRQs6G[l$8A(Cs6GUf"tlSAs5S;=(+?orrrq"?":/#nr;Qf8!;?Es
+l]*;!0V7n8rrW.SM>mMYj*)7SF5HTi"SZ=1&9WR(JcC<$JcC<$qYpPIo<n_dRSA;~>
+ZMspUr;Qoo@gEWeXT&HRDsi*nmcsfUmrSO/&DlUMs+gUR%K!7b$phH(s7bt[#S;(Vrs[IF!!lKk
+s8VOc#S;(Vrr@EE!"_0$s8To-$n\:Ps7`0<$phH'rsZ_9$n\:Ps8/p.#S;(Vrrg=j!%GV\rrpt?
+!!lKkr;Qf;!<)p;_+G+fV#12WN$S`]SFcdGN$/<UT_JKGG8(`?^&J$8ej9?B;XaP`!QG-5rs%bI
+,mZ)moDS^hL]7;Wicc(NF5HTi"SZC3&9EF&JcC<$JcC<$qYpP:o;r)WPY-H~>
+ZMsp]r;Qq91#C2!PcarhIrFb)Dslcf!<D!Arri)AHR41@s!"jGLXpZQaoA##;WlUcN;rnp>3Fa7
+9)noX;WlUcN;roUF8j`=iqNJl?A%+!<jht#8t=aj?H)r`?A%+!<jht8:,1VN+dE$,(kh@:&H;\5
+(g?+Z8kT'^!p:C#rr4"X?A%+!<jhsh9!.*C:8%WF3M>Ar8u2KF::\&s&H;\5(g?+Z8kT'^!p:C#
+pAYP_9!.*C:8%X]c?gjerr3.[::\&5L\:ZNCGF\k+d@QXJcC<$JcC<$qu6YLo=Y4oS5+S~>
+ZMspZr;Qq;1u$>!QEC/jIr4S&D=-Kc!<Cm>rri)AHR++?s!"mJLXgTQb5\2)<ThsjMZ<Pn?0C*:
+8cSfZ<ThsjMZ<]VEW4QEiV!5j?\@0t=18.'9qL6r?c;ua?\@0t=18.;:c-qQ+I<'-*.mX>'`7q-
+**qab8P/m\!p:C#rr4=b?\@0t=18'e9!73E9q_HC4JLl#8YlBG:Un-!'`7q-**qab8P/m\!p:C#
+p\t^"NCpA6S5#[VpWe+2J,]HPNDI'u;2>,Drrm6rgWq".JcC<$JcC<$JcGWI!.sgN!pc:LJ,~>
+ZMspUr;Qq91#C2!PcarhIrFb)Dslcf!<D!Arri)AHR41@s!"jGLXpZQaoA##;WlUcN;rnp>3Fa7
+9)noX;WlUcN;roUF8j`=iqNJl?A%+!<jht#8t=aj?H)r`?A%+!<jht8:,1VN+dE$,(kh@:&H;\5
+(g?+Z8kT'^!p:C#rr4"X?A%+!<jhsh9!.*C:8%WF3M>Ar8u2KF::\&s&H;\5(g?+Z8kT'^!p:C#
+pAYP_9!.*C:8%X]c?gjerr3.[::\&5L\:ZNCGF\k+d@QXJcC<$JcC<$qu6Y;o;r)WPY-H~>
+ZMsp]r;Qp3^&S+s1"$"+V',gUSH!Y.rr4#_SH#E/!#V7+s*G:_+cu-ldUNgs;T8\9IrFb)DsmH$
+(&P+C&-u2&s0WF$s2GW,h>mQm!"cR(rrhVW?7g[+s!!51hZ(],R.ke)n,NF-.K@s!n,NF5!<;Kf
+n,NF-.KBDsXo&,NOE9F]o@DpqGB`f]icgXeOE9F]o@Dq$LM"7"s-,8<k5b8VrrD6^ec>1=s3:WC
+rrPN&!<3!FOE9F]o@DphDgVB]l>(n7CNoOQk%B28F*mfarrD6^ec>1=s3:WCrrPN&!;HL0hJ[c<
+s6=BLs6?+\/V!g#o5f9Us*o+]pAY:-^&S+s0nK@Us+13$s+14Irr@`D]`RYm:4N~>
+ZMspZr;Qp3^An5!1su=.VBc-]Rf@A-rr4#bT)YZ5!$%I-qfrka,`qEncs[Io;8iM7Ir4S&D=.0!
+(&P.F&-u;)s0`X)s2P].gAq6n!"cI%rrhSV?S$^+s!*;3hZ(`0RJ1n*li7"&/H=0!li7"2"TRoj
+li7"&/H>`$Y5A.s/rt#2s7=k&pNLcQs5A0es,V0Ys7=k&s+b7$s8SBAs5sCVs8)fVs3gu6s8UCJ
+rr3)t6#?W$s!EeHiW&N$j6po5qu>npJ*CZip&F2hJb*r0qu-Blj8[R.li7"2"TJE'qa#'!p\u&e
+DgVB]l"PYIl'u*3J,fQ?F*mf_I<"fNrritJs8SBAJcC<$JcC<$JcGWI!.sgN!pc:LJ,~>
+ZMspUr;Qp3^&S+s1"$"+V',gUSH!Y.rr4#_SH#E/!#V7+s*G:_+cu-ldUNgs;T8\9IrFb)DsmH$
+(&P+C&-u2&s0WF$s2GW,h>mQm!"cR(rrhVW?7g[+s!!51hZ(],R.ke)n,NF-.K@s!n,NF5!<;Kf
+n,NF-.KBDsXo&,NOE9F]o@DpqGB`f]icgXeOE9F]o@Dq$LM"7"s-,8<k5b8VrrD6^ec>1=s3:WC
+rrPN&!<3!FOE9F]o@DphDgVB]l>(n7CNoOQk%B28F*mfarrD6^ec>1=s3:WCrrPN&!;HL0hJ[c<
+s6=BLs6?+\/V!g#o5f9Us*o+]pAY:-^&S+s0nK@Us+13$s+14Irr@-3XTI[M8q6~>
+ZMsp]rVm)b!;HNnc3Vku.dmA>pU("ic3X1E`X)>-!3Q"'!:PRif&EJsSG.4f[G"r2p]#_]mXK0C
+q>V/1<`8,;8kT-`CJ+=EV>oBPs8N)Ukl2IeDh%feo5f9Us5n*Lo5ap#s8U(=s7bCLs"^)ns5sCN
+s8U(=s8N?Z!!#oip\/l$:(/_Ip[`HMp]'5_J+n.V:(/_Ip[`HQp](9=#lO]+V&974pYPoL!LtV<
+ruHGah>mTUpNK)%$n\.Hs,^-lo;PKTqs*VLs35#;rVm)MV&974pYPoL!LtV<rr[UGh>m9L#*;`r
+o;PKTrr3&fDh%Za!n(D5pAY?[!;HNnc3T"$JcC<$JcC<$qu6YLo=Y4oS5+S~>
+ZMspZrVm)b!;$6jb7)i!.dmMCo<nYfb6[kB`sD;*"Kq@)!:PLjfAWGpS+h+f[+8N*p&BMYm=0!?
+q>V/3=]OM>8P/s^Bhe=IVZ5BNs8N)Rkl2IdD1DTco5f3Qs5e$Mo5ap#s8U+Bs7b:Is"^#os5sCN
+s8U+Bs8N?]!!H;rp\/l#:C]"Op[`HMp]'8bJbO@W:C]"Op[`HOoDej6%/p21qkb5-s7b:IrrJQ>
+rr4!a;;2*Ns7^_+:C]"Op\g(K]()^oSbq[=s8U;QQ2^dgrQqDYqu?EFrr3"f/H5YOGu<;rp\tKq
+ND[:WW(ro_rrVS)J,K<LrQno.rV-<rk5b,Rs2th%s+13$s+13$s82frK(HDPl^COu~>
+ZMspUrVm)b!;HNnc3Vku.dmA>pU("ic3X1E`X)>-!3Q"'!:PRif&EJsSG.4f[G"r2p]#_]mXK0C
+q>V/1<`8,;8kT-`CJ+=EV>oBPs8N)Ukl2IeDh%feo5f9Us5n*Lo5ap#s8U(=s7bCLs"^)ns5sCN
+s8U(=s8N?Z!!#oip\/l$:(/_Ip[`HMp]'5_J+n.V:(/_Ip[`HQp](9=#lO]+V&974pYPoL!LtV<
+ruHGah>mTUpNK)%$n\.Hs,^-lo;PKTqs*VLs35#;rVm)MV&974pYPoL!LtV<rr[UGh>m9L#*;`r
+o;PKTrr3&fDh%Za!n(D5pAY?[!;HNnc3T"$JcC<$JcC<$qu6Y;o;r)WPY-H~>
+ZMsp]rVloT!<3!!h>l"(.dmA6p](!frunNECKgc,!2]Gip\uDEs8V],c2[(kqs%s8mf.cTmXK0C
+qYq<-H["rYs5!bEs7[Zk>6"WZ!<<'!hWXtRmVdUTs6afTs8VM*J,blj>3FHs!<)pNms>nss8OfW
+kLMWns6h\=s5#b)W:"RQR,3p"XT+YVT\bGDJ*q5(R,3p"XR:"Vrr3#U!<)rt!!'/!ruCKS(s`0]
+[3>;$!<<)eD^h(1OA;nWhHg0^"EX#1rri)(8TX%nrr[`N!3Q2!$L`<YcN!pP+nsgnpAY?R?2ss.
+F70&-!q'uVr;QkK!*7\ErrLsVrr3#U!.k0$s+13$s+14Irr@`D]`RYm:4N~>
+ZMspZrVloU!<3!!gAo\%.dmM7p]'jbrueKEBjLc-"JYYjoD]rAs8V]+bl-ehqrqg3mJhZQm=0!?
+qYq<-I<Y#Ws5*hFs7[cm?2srZ!<<'!gZ\YOm;7@Qs6jlUs8VJ'J,bih?0Bg!!<)pNms,bns8OcY
+kLVZns6DM=qqjM,WpajURbs3$XT+VVU>L_GJ+%;*Rbs3$XRC(Wrr3#R!<3!#qZ$Vrr;Rc*Go4a)
+s0a3EgAq9Rmr'\EhiLR6s4gl[!!I</rr3B#Zq,2us8W%G!!'%srsJ4?(sDsZ[NtJ!!;?Esgg'm[
+"EEi.rrVS)J,TBMrI"ZGeFrnChZ3ZU!S[U*s+13$s+13$s82frK(HDPl^COu~>
+ZMspUrVloT!<3!!h>l"(.dmA6p](!frunNECKgc,!2]Gip\uDEs8V],c2[(kqs%s8mf.cTmXK0C
+qYq<-H["rYs5!bEs7[Zk>6"WZ!<<'!hWXtRmVdUTs6afTs8VM*J,blj>3FHs!<)pNms>nss8OfW
+kLMWns6h\=s5#b)W:"RQR,3p"XT+YVT\bGDJ*q5(R,3p"XR:"Vrr3#U!<)rt!!'/!ruCKS(s`0]
+[3>;$!<<)eD^h(1OA;nWhHg0^"EX#1rri)(8TX%nrr[`N!3Q2!$L`<YcN!pP+nsgnpAY?R?2ss.
+F70&-!q'uVr;QkK!*7\ErrLsVrr3#U!.k0$s+13$s+14Irr@-3XTI[M8q6~>
+ZMsp]rVm)j!;HNnc3Vht'tm3N3OSneF&N#L^&S,G8e="jrrCXIrsdOt0gR7,mf.cTmXK0CqYpTa
+Du0MDf)Pc7!7q2Mh>mTU!8cr>'^fmhs8Vh;Hi*j*CP2ZThEh2ZKFn._"-aX<n,E=jhEh2ZKFn%\
+,0"8Jo5f-Ms5n*Ls6bsl$r0EMo5f-Ms5n*LpNLuYs8U@Mr;Qhp#l">u,a9-]n,NFN&B=Iq!;HNb
+F*IBYk%fVLMb1JNUe.*Vs2e;-XnVbn"4F"Op\t1$PSe3)s8V6n`qS$ap\4[lMb1JNUe.*UrrVV,
+J,B6JdT1kpp\tHd!;HNnc3T"$JcC<$JcC<$qu6YLo=Y4oS5+S~>
+ZMspZrVm)f!;$6jcOA5$'u!BR33rSaF]J;M^An5I9b9:irrC[JrsdIr1.!I-mJhZQm=0!?qYpTb
+Du0MDfDkl:!7UuJgAq9R!8H`;'^]aes8Vb7H27L'D2&#YhaIYfJe7q]"-sd@li-nfhaIYfJe7hZ
+,0+>KnSrdIs5dsIs6l*r&5PlQnSrdIs5dsIolYQOs8UCRr;Qhq%/9c$,aK9ali7"J'Z9Ok!;$*V
+EHh0Wj_9AGMbLYLUeI?Zs2nD0XS)Mk"4F%Tp\t1%Q5FK)s8V6r_t2=WoDA@`#Q'EQ\F64eSc8Wj
+m;7@Mrr^\PJc#3A#3u9\s8UCRJcC<$JcC<$JcGWI!.sgN!pc:LJ,~>
+ZMspUrVm)j!;HNnc3Vht'tm3N3OSneF&N#L^&S,G8e="jrrCXIrsdOt0gR7,mf.cTmXK0CqYpTa
+Du0MDf)Pc7!7q2Mh>mTU!8cr>'^fmhs8Vh;Hi*j*CP2ZThEh2ZKFn._"-aX<n,E=jhEh2ZKFn%\
+,0"8Jo5f-Ms5n*Ls6bsl$r0EMo5f-Ms5n*LpNLuYs8U@Mr;Qhp#l">u,a9-]n,NFN&B=Iq!;HNb
+F*IBYk%fVLMb1JNUe.*Vs2e;-XnVbn"4F"Op\t1$PSe3)s8V6n`qS$ap\4[lMb1JNUe.*UrrVV,
+J,B6JdT1kpp\tHd!;HNnc3T"$JcC<$JcC<$qu6Y;o;r)WPY-H~>
+ZMsp]r;Qp3`rH(/1"-(OpW!75[/f[qc3UNqs8Vi5s8TJ,mhiJ4s7<4tpNL94s*ntTs*ntTIrFcO
+rtYEXHh[R?pWig=mheYWs8UpUs8N)Ukl1_PDh%cd'8LA_s35/Cs6eb<s8STUs8QRhkPY>chY7'M
+S3m8$SGrO7`bUA0K6QqeibO>Lmcs]Lc#99TK6QqeibO>LLMOp0s-thDmn3TZ"p!ids'n(PrVll2
+qZ%@i`IiC+s5IgLo5f9Us6=BLs05=\oD\akpRJ&YrrrJds8QRhkPbD\^&%d0N;<JYkAu"Is6=BL
+rr3DpDh%fepRJ&Zs*o+]pAY:-`rH(/0nK@Us+13$s+14Irr@`D]`RYm:4N~>
+ZMspZr;Qp7_uKb.1t)CRpW*=6Z2j@ncNpNns8Vi6s8TA)mhiM5s7<8!pN^E5s*nnQs*nnQIr4TL
+rtY?TH1V(9pWrm>lPN>Ys8UgRs8N)Rkl1_OD1DQb'8^M`s3>>Hs6nk>s8SZZs8QXmj8Ao_htR0N
+Sji\*T)SaCa)-\5KmE:ij(jGMn*BlNc>fTYKmE:ij(jGMM/1$/s.2(IlUh!RqZ,[Vs(+=QrVll3
+qZ%@k`eA^0s5RmMnSrpQs64<Ms0>I^nc&OsopVWRrVHTTs8QXmj8JuX^A@m1Nqr\[j)KGCs64<M
+rr3DoD1DTcopVWRrI&\UpAY:1_uKb.1kG[Xs+13$s+14Irr@ZB[K>c`9n3~>
+ZMspUr;Qp3`rH(/1"-(OpW!75[/f[qc3UNqs8Vi5s8TJ,mhiJ4s7<4tpNL94s*ntTs*ntTIrFcO
+rtYEXHh[R?pWig=mheYWs8UpUs8N)Ukl1_PDh%cd'8LA_s35/Cs6eb<s8STUs8QRhkPY>chY7'M
+S3m8$SGrO7`bUA0K6QqeibO>Lmcs]Lc#99TK6QqeibO>LLMOp0s-thDmn3TZ"p!ids'n(PrVll2
+qZ%@i`IiC+s5IgLo5f9Us6=BLs05=\oD\akpRJ&YrrrJds8QRhkPbD\^&%d0N;<JYkAu"Is6=BL
+rr3DpDh%fepRJ&Zs*o+]pAY:-`rH(/0nK@Us+13$s+14Irr@-3XTI[M8q6~>
+ZMsp]r;QqA6MKXlPg]R]pB\J,XT8+qruhr#s8Vg!^%\W/pN&(?ihT/9pNL94_*Vr&s*ntTIrFcN
+rtMD4>3G'P3WK+OF8m\Js5!bUrrCX6rrVV,J,]H\\QYNlLgJ4'S2k*Jc5<thec<_gf)Pb23FhO'
+(q'Cp!0ls'3EE]jYu[+GMc-t_S5-'?F(X/+Yu[+GMc-t_\QV>ok:)Yqrt(F`N#;Tpec<_gf)5OK
+h>mQT'!YK%hMY:>s,0=Jig<?2l>'nTrmhMCs+aLg]o3g.s4.1irRUoH!T!hMrs"BMXl>^?T`4rm
+mVdUSrrn0U_7`a)p&>2:6MKXlP_&jcs+13$s+14Irr@`D]`RYm:4N~>
+ZMspZr;QqC61a7fQI>d_o*E)%WW_qns!/;,s8VZr^@S?-o5ub=iM&l4olXp/^dDi#s*nnQIr4TK
+rtMJ7=l\[N4TGFQEVh/As4[PRrrCO3rrVS)J,]H\\m(WjLL84(SNLKLb8dhfdf@GefDkk34D!j%
+*4#Ur"IAN.3**WjZ<<LLM,:SZSPZ9>F(a/*Z<<LLM,:SZ\m%Jlk9uYrq[eqZMAZ6jdf@GefDPXL
+gAq6Q'!bZ+h2+t8rJO.Hj-iW6l"OYRrmqSErIn+a]S[R's3gtgrR^uI!S[VKrs/FZ7]bX=9;):a%
+..n]s8W%O;8BhAM>d/J"a*-&k9uXIs+13$s+13$s82frK(HDPl^COu~>
+ZMspUr;QqA6MKXlPg]R]pB\J,XT8+qruhr#s8Vg!^%\W/pN&(?ihT/9pNL94_*Vr&s*ntTIrFcN
+rtMD4>3G'P3WK+OF8m\Js5!bUrrCX6rrVV,J,]H\\QYNlLgJ4'S2k*Jc5<thec<_gf)Pb23FhO'
+(q'Cp!0ls'3EE]jYu[+GMc-t_S5-'?F(X/+Yu[+GMc-t_\QV>ok:)Yqrt(F`N#;Tpec<_gf)5OK
+h>mQT'!YK%hMY:>s,0=Jig<?2l>'nTrmhMCs+aLg]o3g.s4.1irRUoH!T!hMrs"BMXl>^?T`4rm
+mVdUSrrn0U_7`a)p&>2:6MKXlP_&jcs+13$s+14Irr@-3XTI[M8q6~>
+ZMsp]r;Qoo@gE?]d/O6=(]Y_]rr3%H!8d_T)k7`F+g(eECCgapORE.^5n$M$-%l5IDsi*nmeQkt
+pS:su#YO:[PUZA,c3W"X!<<'c!4D(k!q'uVrr3Q,XYgAI\c;]thDkQQSH&VZqZ-Zr"Pu-=(nCU*
+-+,0%&:;+js8/`L#W]0es6bdb$sLpUs8/`L#W]0es8/p.#RGMNrs,qT!%Gqfs.&rdr;QfS!<3!0
+qku4T3O/J]lAQkh/Y)FW:Ab)!J,e5<&/6S5s8SVd!;uith>m9L#3q-j">-/8rr3&fDh%cd"km`'
+'R/R0rri(+#RGL&s+13$s+13$s8)`qK_)kYn!m.'~>
+ZMspZr;Qoo@13Qed/O6?(]Yh]rr3%F!8meU)kIlH,c^nAD%I%"P4/Fb64Qk,.#%\ND=)gimJ6bs
+pS:q##YjL^Q72M-cNr"S!<<'b"L@:l!psiSrr3Q,X>UJP])Vg!h`M#]RfEDVqZ-Zr"Q)<E*1Hm,
+-*f'%'R@:gs7rNG$9GEgs6kpi&6mBYs7rNG$9GEgs8/m+$k.:Xrs,tT!%c1js-ifbr;QfP!<3!0
+q5,hQ3jAM]l]*4r/tDOW:&FtuJ,e5<&/Hh;s8SPb!;uitgApsI#4%9p#VMY=rr3&eD1DQb"km`'
+(4"s5rri()$k.90s+13$s+13$s8)`qK(HDPl^COu~>
+ZMspUr;Qoo@gE?]d/O6=(]Y_]rr3%H!8d_T)k7`F+g(eECCgapORE.^5n$M$-%l5IDsi*nmeQkt
+pS:su#YO:[PUZA,c3W"X!<<'c!4D(k!q'uVrr3Q,XYgAI\c;]thDkQQSH&VZqZ-Zr"Pu-=(nCU*
+-+,0%&:;+js8/`L#W]0es6bdb$sLpUs8/`L#W]0es8/p.#RGMNrs,qT!%Gqfs.&rdr;QfS!<3!0
+qku4T3O/J]lAQkh/Y)FW:Ab)!J,e5<&/6S5s8SVd!;uith>m9L#3q-j">-/8rr3&fDh%cd"km`'
+'R/R0rri(+#RGL&s+13$s+13$s8)`qF7ZL8kEJSh~>
+ZMsp]^Ae4m3J%3]s+13$s+13$s+14*rr@`D]`RYm:4N~>
+ZMspZ^Ae4o4G!N`s+13$s+13$s+14*rr@ZB[K>c`9n3~>
+ZMspU^Ae4m3J%3]s+13$s+13$s+14*rr@-3XTI[M8q6~>
+ZMsp]^]+B,<c<QhJcC<$JcC<$JcC<$h#@A-o=Y4oS5+S~>
+ZMspZ_#FN8o3$!_s+13$s+13$s+13$s4mVSK(HDPl^COu~>
+ZMspU^]+B,<c<QhJcC<$JcC<$JcC<$h#@@qo;r)WPY-H~>
+ZMsp]_#FMrF#h\/rrMJfqgSWt_1DW;s+13$s+13$s+LCPK_)kYn!m.'~>
+ZMspZ_#FMoF#qV,rrMGeqgSWu_L_`<s+13$s+13$s+LCPK(HDPl^COu~>
+ZMspU_#FMrF#h\/rrMJfqgSWt_1DW;s+13$s+13$s+LCPF7ZL8kEJSh~>
+ZMsp]_#FJqJ#MB,!UQobIfY,:JcC<$JcC<$JcC<$K`;%*o=Y4oS5+S~>
+ZMspZ_#FMqJ#N>+rrMGeqgSWu_L_`<s+13$s+13$s+LCPK(HDPl^COu~>
+ZMspU_#FJqJ#MB,!UQobIfY,:JcC<$JcC<$JcC<$K`;$no;r)WPY-H~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]q#:Ek[C1YdJcC<$JcC<$JcC<$U]1=Io=Y4oS5+S~>
+ZMspZq#:Ek[C1YdJcC<$JcC<$JcC<$U]1=Go<n_dRSA;~>
+ZMspUq#:Ek[C1YdJcC<$JcC<$JcC<$U]1=8o;r)WPY-H~>
+ZMsp]qu6iq[7^iXpOW?qs+13$s+13$s+13Frr@`D]`RYm:4N~>
+ZMspZqu6iq[7^iXpOW?qs+13$s+13$s+13Frr@ZB[K>c`9n3~>
+ZMspUqu6iq[7^iXpOW?qs+13$s+13$s+13Frr@-3XTI[M8q6~>
+ZMsp]rr36![7_;H!#k$Os+13$s+13$s+13$s.]MnK_)kYn!m.'~>
+ZMspZrr36![7_;H!#k$Os+13$s+13$s+13$s.]MnK(HDPl^COu~>
+ZMspUrr36![7_;H!#k$Os+13$s+13$s+13$s.]MnF7ZL8kEJSh~>
+ZMt*bq6`j3&,lP0'[;4/JcC<$JcC<$JcC<$U&P+Go=Y4oS5+S~>
+ZMt*_q6`j3&,lP0'[;4/JcC<$JcC<$JcC<$U&P+Eo<n_dRSA;~>
+ZMt*Zq6`j3&,lP0'[;4/JcC<$JcC<$JcC<$U&P+6o;r)WPY-H~>
+Zi:-T;$mI(!!*\-JcC<$JcC<$JcC<$JcDDC!/0sW!q2XSJ,~>
+Zi:-T:^R@'!!*\-JcC<$JcC<$JcC<$JcDDC!.sgN!pc:LJ,~>
+Zi:-T:'q.%!!*\-JcC<$JcC<$JcC<$JcDDC!-@b6!p>e?J,~>
+ZMt3V^4er`"TSsOJcC<$JcC<$JcC<$JcDAB!/0sW!q2XSJ,~>
+ZMt3S^4er`"TSsOJcC<$JcC<$JcC<$JcDAB!.sgN!pc:LJ,~>
+ZMt3N^4er`"TSsOJcC<$JcC<$JcC<$JcDAB!-@b6!p>e?J,~>
+ZMt3es4'2(!<tpjJcC<$JcC<$JcC<$JcDAB!/0sW!q2XSJ,~>
+ZMt3bs4'2(!<tpjJcC<$JcC<$JcC<$JcDAB!.sgN!pc:LJ,~>
+ZMt3]s4'2(!<tpjJcC<$JcC<$JcC<$JcDAB!-@b6!p>e?J,~>
+ZMt0bN&oK[!%%;hs+13$s+13$s+13$s.95jK_)kYn!m.'~>
+i;`iV!WDrqqu?QprVk[R#MG%seOTZdon!-os+13$s+13$s+13Arr@ZB[K>c`9n3~>
+i;`iV!WDrqqu?QprVk[R#Ln\neOTZdon!-os+13$s+13$s+13Arr@-3XTI[M8q6~>
+Zi:9e3I^l*)AV81rrp0Hp:n*1JcC<$VuHkJR)/aRrrp0Hp:n*1qYpWj\%hk@!qs+<_uBf3mXP-6
+!UbGirrV><\Ujd3s5j7\K_)kYn!m.'~>
+jSoJaqt^$\p%7nToDeFdp%S7Wr;PdW#MqFhqu7QLii)k\^UEjN[e>:PJcDYJ"4NUPr7M#Q^UEjN
+[eBRt!qs(;r;Qil[_K`[!qu#2qu6]aItRb&jbLEus+143rr@ZB[K>c`9n3~>
+jSoJaqt^$\p%7nToDeFdp%S7Wr;PdW#MqCgqu7QLii)k\^UNpO\+YCQJcDYJ"4NXRrRh,R^UNpO
+\+][u!qs+<r;Qil\%fi\!qu&3qu6]bItRb&k(gKus+143rr@-3XTI[M8q6~>
+[/UQ'26d,\p'AY7Z%IhBXT&HRDsi*nmcaZOL[O:(s24j9%K4kHKqR6$s82PhK87#:rs\1cItO]o
+s8VhlK87#:rrBb2Ih8.*s8V#QKpL-bs81-.KqR6#rs[h]KpL-bs8CNRK87#:rrh>GJ!Aghrrq\\
+ItO]or;QfWJ,TB`i1u'mdJa+;`KGk>c2%D/]8;BTmf2FHqgSk=s6?80K;eD@rrg/nK;e\Ars&,7
+P(T(Fq>L?n_uBZ>n@OO6\aK.j!58>\!4f$-"Sn'Y^\ugb"b1IYIrFcOrrVbQSG`BgmVdU=rr@iP
+rscf"K;d2rs7F9lJX4XZnG`RXh>mHQ!T!h#rr@iQrrh>GJ!AgerrM,/rr2u3rI4j<h#79Q_uBZJ
+qp1R^T\TSIrRREkT\TSIhS&l;!4i+/"MokGW;HMm!p4D]JcC<$jo5=6o=Y4oS5+S~>
+kPknfqY9dVo'l,8mHjf;$LI0Jn*oo?pA"Rbkl2'[26QuZp'AY7Y_._BXT&HRD=)gimHFQNL[XC*
+!rg*Urr4/?eX;,ah#IENor<Y"\GcI-l_&f]WqHDlor<Y"\GcI-]`!=&SD=/Ehkc'ndJX%@c^'9W
+gA_-Phkc'ndJX%CeZa[]])M^4j-,%XhZ!NYl_&f]WqH;i!TAP,rtjRhL6g6bs7OBpKU:![s7*^Y
+MRi0Tk,8*+#OVQWU4\0"oD\am^km]Dq=jmnou</JQd5F+rrW2;`;]c?n[j[9\aK.j!5/8[!4o*.
+"SdpU^&6O_"b1CVIr4TLrrV_NSG`Bgm;7@;rrN(Tr;R5AM1_hUr;ZH/OFieEqXFLdmFqX<rrLjS
+c2RhCM>dGWj-,%XhY[<RiICk,!5/8[!M%sErrW2;`;]cKqTkI]TA';ErRI<iT\TSIh7W]9!4r10
+"MfkHWqlSm!p+>_JcC<$jo5=4o<n_dRSA;~>
+kPknfqY9dVo'l,8mHjf;$LI0Jn*oo?pA"Rbkl2'[26-]Vp'AY7Z%IhBXT&HRDsi*nmcaZOL[O:(
+s24j9%K4kHKqR6$s82PhK87#:rs\1cItO]os8VhlK87#:rrBb2Ih8.*s8V#QKpL-bs81-.KqR6#
+rs[h]KpL-bs8CNRK87#:rrh>GJ!Aghrrq\\ItO]or;QfWJ,TB`i1u'mdJa+;`KGk>c2%D/]8;BT
+mf2FHqgSk=s6?80K;eD@rrg/nK;e\Ars&,7P(T(Fq>L?n_uBZ>n@OO6\aK.j!58>\!4f$-"Sn'Y
+^\ugb"b1IYIrFcOrrVbQSG`BgmVdU=rr@iPrscf"K;d2rs7F9lJX4XZnG`RXh>mHQ!T!h#rr@iQ
+rrh>GJ!AgerrM,/rr2u3rI4j<h#79Q_uBZJqp1R^T\TSIrRREkT\TSIhS&l;!4i+/"MokGW;HMm
+!p4D]JcC<$jo5=%o;r)WPY-H~>
+[f6m#96'^_s8U69s051;DbA-RrrmmjmXK0Ckl1YhhWXtBqrYRmKDtlpfR7(G>`%PAbEu1OF&L!W
+s*%4ZF&&8*s-Q].F&L!Ws(4:jCFG4qs5K,PF^TXMs3#OqF^g9gs5K,PF^TXMs4D`lF)O[ms8R"<
+G?SVXrrmUAF)t*HrVlrjDZKe:(ugWhF^TXMs1N2^F_#X:s0lHMBje7HjI6$_&Nq<*s*IpnF&nP*
+s2A/_G=o.7rsZSVBm!s/aoD8#]iKdbrrol@B5(bZp&>&)3W<doZ)@U(n8WmTfDc#(Dsi*nmeZqb
+qq0^%rrVV,J*[+:pXZ,GrVmAH>'"m[IG"S3@UO7bFj9FU!q+nFqu6]R!71ZIpXZ,GrVm"=<d._Z
+r;QiiDZKe:!G4@kCBomPs81rl<eLDO'$GE.F^g9gs4Da+EEn@]s0?5srbDeEs8U&AF*C6]qu6]J
+!.k0$s5j7\K_)kYn!m.'~>
+l2Me%q=aFMmd06&kN:mejQ#:]jQ5Oel0@X'nalJNrp9Xqk"B^gg].;rUAqMkEGnIlXoAQSD=)gi
+mHFQN#i4_E"T.>o<eUJP,1q?NE*\@^s3$d0GB6[!s8@4=F`U?Is8SHdGB6[!s8Q^krbF6JfDjik
+B6@U1fDj$;Ap%U@i;_etB6@U1fDjKP8o\cAb5_K]<I%e_rVuhA:N^_SRf36fo5+L,rtsaVB6@U1
+fD`F!C3F33aoAk\B51n^ro9IGCCrZQmJVB;GBHuOs8U)AF`g?]q#:g%]PM>+Ap)5qqrYOlK`:uU
+\79/d@^H(-rrHalrbDM<VuHkfDg_K7rrmmhm=0!?qYpWnfA-<(!psiSli.(]etNNMrsm%OF`g?*
+fD`Bm@WZ%#bjbW6mFqX<rrLjSci4+AetNNMrrmCBH!>"]rVlrjD#jS8!G=CkCBojNs81rk<eUJP
+'$GH1F^p<es4Dd,E*\@^s0H>trbDeDs8U)AF`g?]qu6]I!eLB&s5j7\K(HDPl^COu~>
+l2Me%q=aFMmd06&kN:mejQ#:]jQ5Oel0@X'nalJNrp9Xqk"B^gf)PcmUAqJjF)O[mXoAQSDsi*n
+mcaZO#i=eF"T.>p<eLDO,1q<MEEn@]s3$d-GB6[$s8R:<F)t*Hs8SHaGB6[$s8Q[krbEpBf`0rm
+Ap%L0f`0-;A9D@>irA#"Ap%L0f`0TP8onoCaoDBZ<d._Zrr3.G:31JOSGiHho5=X.rtsaWAp%L0
+f`/X#Bm!s/aoAhZB5(bZs5]XICCr]Qmf.W;GB6fLs8U&AF*C6]p\tZ8CM@p%Fij[\k.OfJrr3/2
+@V9C_ZM"4uAi]j+!3rI%"7U;YrR_&QIrFb)DsmK%!rLX*r;QidDh%*Q"8CBB#lXc5`EI>,8q#@l
+]4,/h@!0``rrVWF!;lcsh>kn%"8CBB#lXc+DcV'cB)MZ1o5=X.rrH^lrbDb!f`1j2]iKdbrt<Lt
+A9D@>ir@YZ??'5,jSuMt3W<e"Z2ajC>'"m[Z2=P%ec::$JcFj3!-@b6!p>e?J,~>
+\,R#;1;NqihZ*WJs8P6+mcI\^dJjI"OFN25s1,*-ruR9Hs3d!YMp;;%]n_6%a7fPsZ%n%3irB%.
+Dsi*nmeQl$rRS6/K;ePEs*rUeIur7]MZ@tTs*rU]`OVrHrrS;,k4\fXn?m*^J,]HlSm&GbTO+l"
+N$4kcl?c_7l3sK[mYiIlpE?4$l?c_7s#lJCl7qf*s/Ke>m_b@6qi"q)m^$]1s/Ke>m_b@6s.3D<
+mcI\^s76Z4pVdF0s6:#goBqP`rVlq`5lgoa/uiWlm_b@6p4$Q$nAALmq0ur/hI_33rUT7=in@.p
+s6^H+oBqths8Q,HlLU7-q#;/uIq$ps_d&<'n?m*^J,fQEIq79iApsLKrrG9ErosLXVuHhdDh%Za
+#jAOKKrjFl\Z#N-'p-]?dZAs:c2[gWLOYubs8UN/IuD;FrrmmjmXK0CqYpor\%ht$VM0l(>^u)>
+"6,,7!<)p-<dX-'Pa9MbHW\J\]i^Hqs"`fCLP;\ds8V#SKo)\;!<<)8Mgpu%!<<(Ker[lNqltp/
+W;$>ldZAs:c0#&iZ%n%7k3N$LieUJ4rr32o%))DS#kS#p!gGtNrr3!^OT+McnGE7T[;@@Bs8VtT
+@*.iCCTRQ->-dFd?EjI$4co[.#l"B!<dX-'PaM@J!T!g-s+143rr@`D]`RYm:4N~>
+li.Flq"=4Hm-3]pj5JnPh>>t:h;7&Jj5oIgm-jN<qYos`&>q;!s8UjRs7H?k5'cPY>@l4^#L\`a
+NQhF4WrE#>Oj=!TOaiA7s8BTeKosFLs6$VAKrEu1s*nnQIr4TKru1jeZA4(4p](8CesV)MeGkL.
+FkH_De;qPXWrE#"Oj<+_rrhi!D('o5s&YdrZg+5lZMTS)T_%Jr>Q<jrV"=&6-NEfaT_%Jr>Q=^g
+O6PurnG<0cBX7'CQd#>c@EIuECT[W;BX7'CQd#K$>C#W!>@mj+%_VPS$Le#X%]&^bN$eQ("9"HN
+!<3!NX(\g,_O&L?IUgmt_HW)sJ7[EiB70IOo'>W$fh@e5m1?_tn!5*rs&XL3nW]L;rtk'OA(:%c
+>EAgR[;@=As8VnFA_GmPI/!@7"[J.5lg+5ArrVS)J,B6Okd$#!Xl\<IWrE#5Oj=!TOaiA7s8BTe
+JYMQ3s3QgVMo>Vp"b1CVIr4TLrsJJ.^]35jL5Da2J*[+:iJCD3rVm@/H0b!bQd#&I=j-?K=d&^_
+1?YlsKrEu1s59i1M5@W\s8TrqJ!7;@s8RSuO2V(qZA4(4p](9AOaiA7jo=PMLk`%nli.(GM,=9P
+rs&')]_B>On,E=hrKKVKrr4T9O6PurnG<1S[;@=As8VtT@EIuECT[W.>I3Ug@']g)5`b0qlh1;X
+=*a-%Pa_LL!S[U*s+143rr@ZB[K>c`9n3~>
+li.Flq"=4Hm-3]pj5JnPh>>t:h;7&Jj5oIgm-jN<qYos`&>q;!s8U[Ms7H?k4a6>V>%5nZ#L\]`
+Mp;:4W;cf<ONmgROFN25s8TcfK94.Is6-_CKrF#2s*ntTIrFcNru1jeZ%mt1p](8CesLrKf)LX.
+GM<(Her[k]W;ceuONlq]rrhi!D(0u6s!"%<ZKe)hYksA&T_%Gq>6!jrV"=#5-3*]_T_%Gq>6"Uc
+OT+N"nGE6cBs[6FQHT/a@*.iCCTRQ9Bs[6FQHT<">'KDs>%7O'%))DS#kS)]%&EL_N$\H&!gGtN
+rr4UNBs[6FQHSuO@asnb>`ec2AD5mPIJNj4lK[B_:72(L&@M,tQm)M0<dX-'PaM7G([cc^eF:@\
+OT4gXD(0u7s7q.Tg>6Fiq=agh4co[.!;EDk!q'uVqu6rcZ%n%7k1mMGrr3^pc2Z4RIuDSOs1O2;
+T^Mj[dZAs:`W#l@IrFb)DsmK%$MLsDs59c.M5FO-li.(HLf+6Orsi(VlLU7+bOg-`bOE2IP5P>8
+kconsW8djWi223bVRZ^,s1sVCPdpeos*rU]`W,h?LP)Q"s8UN/IuDS6s6-_CKrjG&rr_8:;?6^r
+#4i8:pVdF0rVlq`5lgoa!BlPDl5fBks7!F5.=_Btqi"q)m^$]1s.3E"lC_Ifs.2B8rosd`s8Q,H
+lLU7-qu6]R!.k0$s5j7\F7ZL8kEJSh~>
+\c2d!=(Ch#rrCpSrs&'#gAh2X*7Fj:pJPXNAkr)n/c5S-'Zp)IB7"5cpVBaKF^f1+qkQtrF',%2
+s*ntTIrFcNrufdA>'k<cSH&ThGDCZC?N5o`GM<&sDem%Z/c5S-'ZoG0s'PECVG;X@s7q(_m/P^M
+NV.Don,NF-'`[<6p](9$'`[J!n,NF-'`\1MDh!88chmTl>aU5,]Bo35GPD-sD2J.B>aU5,]Bo?A
+ESCHmYoNf8J,B8o%.jM]Dtj;3[1rW?*PG(@!<<)rK3XdtOLslQIqRR4a]si$\\7t*Dh%T]rtEA0
+BD;Go&A@u8S/hS'&?1G;SD*c<([ccch"f&sNW8XqVG;X@s7s4=rTJ0Lq=agl(iOnRW;!4i!pjcR
+r;S;EUg.nZ>,'35/c5S-'Zp)IB7"5cpVBaKG>=(rpJOV1C.@sts*ntTIrFcOrsJ14J)H)cDfoS@
+J*[+:lEQiZrr3N'&?1G;S@e.YWjDU&g16'=s"sVK:1A9HT)7H$>&SOo<WN09:1e]k<WN1"!,lYd
+s/9+JF&&8*pJPXNAko)pUg.nZ>,(o\rr_PkS,iQg#4m?As3_>Irr3)68u)Ids"5.,It+ECqu?<5
+VG;X@s7LMYp]'5iM>;R>m/P^MNW4nRDh!88p]'t!WJ?+rgACmOiW/k,s+144rr@`D]`RYm:4N~>
+mJd^qq=X:Glf[Bhhqd&?f[eUNeGn&.f%A[1h;I;Skj.[-pA4@["790"o)AXhg\q-Vo*F"Ks0*Wo
+s!mbCBmFDepRX#7s5Om9pJkpQBhe?9;K[.mCrH4H9k&*DSbiA9D=)gimJ6c)e:V%PF&/>+rr@8"
+Inj;LN<"+Rrr?tQ\t1POs5Om9j7`L[oZa7-J,fQEI;nNPf4^6<FTCh/s2>iTj_a\js0NXClN$>P
+s2>iTru,m*JZ@)oqh&+?L60(8olYHOs5IpSqh&+?L60(8q0d57s8T;Gs7:a;rQkuAs5e+js8TGC
+rr4"M8Yc@ds8.FQR"g^8mIl!@gA&`oNqp6!r8qmFp\k+*`J\=#s6UB1q=g=!s7[)%M1_DSq#;/t
+IV.=/aBXc*oZa7-J,fQE\\7q'DLM9Qrrj<\I=\EmVuHhbCk)B_/,Q2NEH,3Wb+:6_s5Om9pJkpQ
+Bhe?9;K[1ZM?!<I8pP,>p&G&AD=)gimJ?him;7@2Lg4nAALi8rrr_MkRK3?e&,-X4M1_D4mII6]
+qZ#5\MuEZ4qkQqqEEA_-i.tWWF_+VSs2%QGGB6gcs8N(;CV'PG?$UKeSH&=`BmFDeUA(NlEH,3W
+qs==bl*?`Xrr32oJ,B2k%.F2q"1h("!<3!N)KC1VWmLYCoZa7-J,fQAFa!KYibj\MI;nNPf4^6F
+N#H\aJZAJEpCO3YK:^iprrV'Xqgncus5s=]K(HDPl^COu~>
+mJd^qq=X:Glf[Bhhqd&?f[eUNeGn&.f%A[1h;I;Skj.[-pA4@["790"o)AXhf)>UQo*F(Ms03Ql
+s!mb@B7"5cpRj,8s5Fa7pJPXNAkr*:;KHtiCrQ:I:1A9HT)8P;Dsi*nmeQl*dt(\LF&&8*rr@7u
+Inj>MMZ@tTrr?tQ]q?tSs5Fa7jS&U\oZa7.J,fQEI<"WRfOg-9FTCn1s2GcQk&:"os0WR@lN$DR
+s2GcQrto[(J#L]jqh&.@Koiq5olYKQs5ImPqh&.@Koiq5q0d8:s8T>Ds7:a;s3_>Is5n7os8TJ@
+rr4"P8u)Ies8.FRR"^X6m.PpAh"f&sNVU,urTJ0Lq>L=,`J\C's6^H3qtHU#s7[)(LP),Nq#;/u
+IqRR4a]si*oZa7.J,fQE\\7t*Dh%TVrrj6XIt+EkVuHhbD1DK`/,Q,IEH,0VbFgHas5Fa7pJPXN
+Akr*:;KI%WMuWNL8pb;Bp](8CDsi*nmeZqjmVdU5LK\V=A1N/qrr_PkS,iQg&,-X7LP),/m..0_
+qu>A\M>dH2qkQtrF',%2i.kKSF_"MQs1qHBGB6dbs8N(;CVBbH>'k<cSH&=]B7"5cUA(HgEH,0V
+qs==blEQiZrr32oJ,B8o%.jJu"2.=&!<3!N(iOnRW6bA@oZa7.J,fQAFa*T[ibaPJI<"WRfOg-C
+M\pA^J#N,ApCO<ZK:LZmrrV0[qgncus5s=]F7ZL8kEJSh~>
+])Mi=0splY!8d\S#3#X[s8UXQdf1fc!3,_HHhZY:df5[hqsONapY'ug;K(jibD!>#Z&mVtA97>A
+IrFb)DsmK%+oRX;T_%T9-27E>J+!?<#ljo)hZ*TUF5$BN'[m#K1&LqAs%Vp"J,fQ<EIIfcl>;+J
+Kc$WWl@/g6qsOLY]iod_o,+:pl@/g6pDdsuDae`nnoHa2F^B:>q1W.um^59/noHa2F^B:>n8WmR
+s8UXQrVn-m;I]\+qsOLY]iod_s4U5Dh>mTUnoHa2F^B:>s0l*:Gue=lrr3)8Bj.b>rr_J=3S+30%
+<"R[G;Y<YjoB=DF%W8&rs#r7??oRZ`W#l=mVdUQrr^#M>-R`##59*QIr@cKVuHhI@#Os_/,+6ed
+-.L?mcG53s-PP<mf9?]g3`QlDsI(iCB+$D[JS&Gk5YI2Dsi*nmeZqjmVdTP<h/C=TJ:rprrME9q
+gSUspAY0M!<3!/joB=DF%UZ(rUfg\g5B^ZrVn_OZ&mVtA97==<h/C=TOIp$:0uZKhI6Kbrr@,op
+\QP8oBqhhp[8*]pY'u)o640\kc22jrr3#aWr.>IWp9<X!T!hRrrR[J@fHB;g.nI#!<<)n*,C%B7
+<?fSs!7#NJ,fQEKjMsj[6K01EIIfcl>;+LM&^;\Dag?!joB=DF%W8*rrVd+]n-37s5s=]K_)kYn
+!m.'~>
+mf*mrp[[b<kN(RWg=Y!*da6=cc2Giuc-FY^daZk#gYUoMkNhU.p\jdb!jj\hr;QcOrVm)^!;ZZp
+dg"8#.dmM=p"F]cjV6/CQnnL+"K;"IH1t0UlgW&M[/."gfAC(Xnc+)Um=0!?qYq`;Q"Zi\n!#*l
+rr@Q;rN$;)rrCgRrr@2qp#Qn9s-PS;r:L"`m;7@Qs7()Vr;Z"tK)(*;VXs,'!rr/bs7a0/HiN[S
+VXs,'!rqp7D1-CpFjT`$2fs4MGL?5??d.uH5_/HI2fs4MGL>r#I/3gBdg#gO/cC)r@K$6'mJlpn
+=aU2Kg.nBs!<<)jF#S2a?['os[9$XY<a`oHs8K]F>-Ir)rtOXM3n430rG=iGG;P6Xk5]FGF%`>(
+rs/M1='^&O@)`-F!psiSrVm'#]kCTQrqHEsoc@suECch&rr`8L@Z:6b/,+<icKD4;mc>/2s-PS;
+mf]T^g3NEiEU3:jC&djA[e[oCj8]./D=)gimJ?him;7?O=IeU?TJ:rprrME9qgSUqpAY0J!<3!/
+k5]FGF%^`)rUfg\fnsOXrVn_NY`RJo@r_%;=IeU?TOS!%;.&&OhI?Qcrr@2qp%pG9naD\fp[86`
+p"F]$o6FB^kGl&hrr3#aX8IGJWp06W!S[VPrtYK\;doY)s4U5BgAq9Roc@suECb6!rr482D1DTc
+q1W2"n$PE2nSrsSs64?OqM?81I;qfPs5sB#H#lWSqu6`f(;,4uJcFm4!.sgN!pc:LJ,~>
+mf*mrp[[b<kN(RWg=Y!*da6=cc2Giuc-FY^daZk#gYUoMkNhU.p\jdb!jj\hr;QcJrVm)]!;lfr
+ecaG$.dmA:pY'ugjqQ8DQneL,!3,_HHhUEVlL;uN[/7+if]$F_o)F2XmXK0CqYq`;P\-T[mZ]$l
+rr@Q:s/ZM+rrCpUrr@,opZ<1<s-PP<rUg+amVdUTs6t#VrVu/"Jbb!:V"<l$!<;ras7a31HiN[S
+V"<l$!<;d5CO^7kF3jDu2fj+JGL?5??H_cE5C`6F2fj+JGL>o"IJa'EecbsO,_&^$s8Vuas7a31
+HiO-":8H_Hs8VY22fj+JGL?H"=C-8R@)`-F"2APRYl4S(k_2%Jrr3FG6@3o6MuVo>Dg-7pV"aln
+[ocs^<a`oGrrVV,J,K<K^M-lUpAY?k*,C%B7A-RY!n1P8r;S;AG>urQWk%Q['[m#K1&LD>WV>+n
+pJPqppRl:$pM726aT1K's*ntTIrFcOrsJ14J#68:kj"fqJ,TBJlIPi^!7plD!T!hUrt"5lDg-7p
+GL?B]pA<R%C;'TG2#FP>f]$F_ntoHXkj"gM!<5f#g@sH5!<<'!F5$Bc/YM_'PU6(m!3,_HHb&`l
+<7'j/\blC+!U?]_IfZS7pAY0M!;lctIo9bTrsmaXUtu+Os7[LKIr@bsci3qimVdUTs7q@TbO2c&
+J+.H+rVu/"Jbt9DCO^7kT`=-SDg-7pV#1/no+\lhs+144rr@-3XTI[M8q6~>
+]`/*)A6/'orrCpSrs%Tcqu?]I"Od<"pKi&rSC[`?8q6k(MuWNXGCuF:rt*0Ls7tU8s59oCQ:c)`
+s*ntTIrFcOrtk<M4*Q1(DZJes!6tQDh>mTU!8dbU!6P6?"A41D4cAn2'^fmhs8VY2IJs32D1V`)
+LJDo7?3pQ129CJlKBE46LJDo7?3pT*R*u$&Io_m)EDX^D]3La'_eNS%C,:M3EDX^D]3L`oF+*rc
+s4.>Orr[aK>5S=!*Q`qTKBE4*@WV:t!;lfcEDX^D]3La'ZrC:U<*mQCrrg)N<iZ,trrTHDHi<sR
+C-?of0oQ(k!2/cJLb\Z(#..?7GuS+hrr3&fDh%]b"M\YOWr;\l#5=M5s6b@gW;ctjP$G]us"!uH
+COM8SlMplVJ,_Zis7]iDK:LNm&B4\Lo?I=8_3C=O!8dbUIrFb)DsmK%$LVh^Kk0'?s57:7rVlo`
+f)'psf(T+Eh>mQT&)mS^md>m9R/d3IVL*Zto)/M"i2W*/8oO-OAD[@di5#En%))Z?*PhaUrrC1@
+s69T.It)A:iqHc'K:LNXql4F[O1FQSrrMDbr-naIlLt5Yh>mHQ'Rs"aqu?7sF8+Agqu?DXdf8`b
+<gNab!q'uVrr4%WC1)1!1P>7>IJs32D1VT)R*u$&IkC][!2/cJLb\c+!a\LrJcC<$kPkO8o=Y4o
+S5+S~>
+nGa1$q=X7DkiC[Xg"+X"cHOGPa2Z*s`"L&/a2lEIcI(+lg>1`Kkj7j4r:p9onmkefqu6ZNrVm)`
+!;ZZpeHXJ%.ed@qK:C<hs%7k@4H9C8@<[?ndf0lus8VoPjo4,;QBb'ZmJhZQm=0!?qYqB)Fushr
+Ir>>IrrC:Cs4[PRrrCgRrrC.>rrbrFrB-)1rtOj;J,fQ>Ed[fbl>;.Q_hV*3H!L^Ts#%rOF+NHQ
+s+aHoH!L^UopO8,mt"T,n8M7Gn%)_is2/Y_GAAsdn8M7Gn%)_inoB-Rs8UURrr3-"IoBSKrr4Lk
+K6)V*s79fCo@F!<rU4]&aR?]EQi=?k>^'.S`W,u;^1gZLrVuosYAJRarso!C5'_9+MuV`9U@7Q*
+0_kYQrNoO/G>qqgrr3&eD1DNa"oc5M=0);ors&.adf&Wc/u\dPnrd=mr;S;EXDE<G\*3kl8qHq'
+NW8`]GCuC5rt*3Ms7=J7rP4\bPQ9J<s*nnQIr4TLrsJ.1IthRls8UtaJ,TBJlIPi^!7^`B!S[VR
+rt"&gU@7Q*>F5BijJR?NZh"(p')pagQBb'Zm=o60s8Uul!<3PCrr4"S!<<'!aT);+!d0!BDZJhl
+@<[?ndcgS0CjhARkl(M^lDsi4!NPDXrrLjSr;RN1IoBSKs79fCo@F!<rUlT,rU5;>QN$mcm;7@P
+ruT'o@s;]DKCX&1r;Z&!K)3NUdf&Wc0)sl1U@7Q*0`(eN@8$KKs+145rr@ZB[K>c`9n3~>
+nGa1$q=X7DkiC[Xg"+X"cHOGPa2Z*s`"L&/a2lEIcI(+lg>1`Kkj7j4r:p9onmkefqu6ZIrVm)a
+!;lfrecaG$.ed7nK:LNms%7e@4cB@7??_$lf)H<#s8VoQk5XA>QBk-]mf.cTmXK0CqYqB(FZXes
+Ir>>HrrC=Ds5!bUrrCpUrrC1?rrbrDs#l;2rtOm>J,fQ>F++#el>;+P_hV!.G?tRSs#%oNF+`WT
+s+a?jG?tRTpR'D/mXJ9'n8V:Fm^l_ks2/SZF_W^bn8V:Fm^l_knoK6Vs8UXQrVltL;HitsruK46
+F+`WTo3ue8g&V$Mn8V:Fm^l_ks0Pa1GuS+hrr3,9Bi_84rr3&)DgVH_%;J%QG;5$UiW,Y>mYEUl
+rs#i0>^9:T`W#l=mVdUQrrg)N<iZ,mrs&4bdf8`b/ZA[Onrd7kr;S;EWb[$D\a'4p8q6k(MuWNX
+GCuF:rt*0Ls7=M8s1sqePQ9S?s*ntTIrFcOrsJ14It_Fis8V"bJ,TBJlIPi^!7plD!T!hUrt")h
+T^M6(>aYQkjJI9N[IX7q&`B[TQ:c)`Kk0'?s5:]nrsZU?ruJoUs8N)@s8V?aGCP*\!93`ZGCuF:
+lMISsI?1r(rVlo`Wr.>IWp9<X!T!hRrtKr\>5S?k@WV:t!;lfjR*u$&Io_m7rrVV,J,]Hh_eNS%
+C,:M5F++#el>;+La-b<TmXHhgiW,Y>mYEUorrQM!qgncus6'C^F7ZL8kEJSh~>
+^&J/L18amI!8d\S#58D[s8TJHdf1fo_5)j1>5/&i/_1cqs80X.LNcqr%)r8Hq:+-qVJD*_<,_4)
+IrFb)DsmK%(\Di5H[gNlBBoKshZ*W4!<<'!hZ*TUhZ!NXTIn_3hX^[cmVdUTs8.:emf2!SNW8G'
+S:?HY.KBFQAq.5_rr38\S:?HY.KAPTrr6-@BncA0GP2!sCPDfV]oIf+>a5&2GP2!sCPDY8F5Hrs
+[2f5@V#UJC"RlBjZ"AKnp](9A#\/3s!.2]?H[#/_jD0JFIq%.-a'+K"c-cRTCO,[Ss6=r\hZ!Nb
+o*i2,pQus#o*"CZs2kcFrs/.F@bUXu>)iO]%.8%`s8Vu@dJrEGH2%(5!TqZ+rrL+JW;ctjQt!c,
+s""')Z^-)SW;HUf/_1cqs80X.LNcqr%)r8Ho<nVm<e$L8!8dbUIrFb)DsmK%$LVh^KkB9Cs57:7
+l2Le@!<3!.o*"CZs2o,2s4E6NRb%B6rt>4+CQ"ibDsi<ki;`i8_#XKD_>aHU_#XN8!8dbUl2Z0\
+IsYhnqn](`G?Us@hQrMtBW1gnrrLsVrr3T)V#UJC"RlB=#\/3s!.2]Ic2R_E`bC/+rrVV,J,]H[
+m_+X7NEh_FIrk&Xg1ZK:g<KWs$-!DRo*"CZs2kcIrr`-jF8LOgJcFp5!/0sW!q2XSJ,~>
+nc(0=q"*q=jl,%Kf$_mgaiD?:_8!^t]tD"k]tV7t_o9[<bg4bhg>:iOlL4B@qYpW418amI!8IJP
+#5&>Xs8TMMdf1fo_PW*2=nhrj0%(Tns80[1LNQbo%*&>Iq:+-qVe_3`<Gh.'Ir4S&D=.3"(\Df3
+H%1<jBC#Qtg].<.!<<'!g].9Rg]%3UU+Xk2hX^[cm;7@Qs8%4cmJkmUO8n\+Sq2l_.f]OSBmmG_
+rr38]Sq2l_.f\\Wrr6-AC52M1GkM*tC5)]V^5n&0?'P,2GkM*tC5)M6EngWo[NPVCV#C>?#4;Hj
+Z>"`qp&G'?$=S3o!-uN:H[,5`jD'DCIUq.+`a"T$bg?@PCO,XRs64iYh#@<`mgcr)op?m%nHS=Z
+s2b]Ers/"AAD-^s>`\ma%..n]s8Vr>d/N3DH1q"4!U%c-rrL.MW;ctkRUa#.s""')[$H/RW;HUh
+0%(Tns80[1LNQbo%*&>Io="\n=+?R:!8IPRIr4S&D=.3"$LM\[L1fEDs5.46l2Le=!<3!.nHS=Z
+s2f#0s4E<PRFV03rt>4,CQ"icD=*'jhuE`6^]=BE_#F?T^]=E7!8IPRkl?!YIsYhoqnf4cF]k[=
+hR&StB;k^mrrLjSrr3T'V#C>?#4;H=$=S3o!-uNGcMmhFa(gA.rrVS)J,]H[n%Oj<Na7nGIrarV
+g1uc@g<T]t$-*PUnHS=Zs2b]Hrr`'kFo-aiJcFp5!.sgN!pc:LJ,~>
+nc(0=q"*q=jl,%Kf$_mgaiD?:_8!^t]tD"k]tV7t_o9[<bg4bhg>:iOlL4B@qYpW418amI!7q,K
+#58D[s8TJHdf1fo_5)j1>5/&i/_1cqs80X.LNcqr%)r8Hq:+-qVJD*_<,_4)IrFb)DsmK%(\Di5
+H[gNlBBoKshZ*W4!<<'!hZ*TUhZ!NXTIn_3hX^[cmVdUTs8.:emf2!SNW8G'S:?HY.KBFQAq.5_
+rr38\S:?HY.KAPTrr6-@BncA0GP2!sCPDfV]oIf+>a5&2GP2!sCPDY8F5Hrs[2f5@V#UJC"RlBj
+Z"AKnp](9A#\/3s!.2]?H[#/_jD0JFIq%.-a'+K"c-cRTCO,[Ss6=r\hZ!Nbo*i2,pQus#o*"CZ
+s2kcFrs/.F@bUXu>)iO]%.8%`s8Vu@dJrEGH2%(5!TqZ+rrL+JW;ctjQt!c,s""')Z^-)SW;HUf
+/_1cqs80X.LNcqr%)r8Ho<nVm<e$L8!8dbUIrFb)DsmK%$LVh^KkB9Cs57:7l2Le@!<3!.o*"CZ
+s2o,2s4E6NRb%B6rt>4+CQ"ibDsi<ki;`i8_#XKD_>aHU_#XN8!8dbUl2Z0\IsYhnqn](`G?Us@
+hQrMtBW1gnrrLsVrr3T)V#UJC"RlB=#\/3s!.2]Ic2R_E`bC/+rrVV,J,]H[m_+X7NEh_FIrk&X
+g1ZK:g<KWs$-!DRo*"CZs2kcIrr`-jF8LOgJcFp5!-@b6!p>e?J,~>
+^]+E1ED,EgrrCpRrrk]Aqt"9+df1fkBAWNj!;$6Q'OFQ7s7^0_qlp.m7<@b`bB^&\GA$'r?u>91
+IrFb)DsmK%(]BM1W:TVZKE(rOhZ*W4!<<'!gAh0QhZ!NWjqM,snc&[YDh%cd';/gLpSq],s2Bnu
+pZ>Y+s6;=ghYug?s#Z.@pZ>Y+s3aZapZd69T`:Hn_sY!?T)Zd"ddEcC^&OO6_sY!?T)YHmK_t@M
+@fQ0SanNa_oDe)1J):1i!WV$UIirY0J&UE9B>a/H?CptB@+=\^>*/WEHf3aoJ,0-E^LX/=rsnW/
+[I`gN+ohR"R-sBl4o#$^o7(/tnA/:irr3DpDh%feqiZ<ahIqE7p\tHG:<E7qImL"4!nq7Er;S;E
+YG1C7=F'`BjqM,ss8Vh+hYXPXo0m`cpRkFamf:Z5_#W3hs*ntTIrFcOrsJ14J#6>>kj"luJ,TBJ
+lIPi^!7plD!T!hTrsgoRmd>R2T(J%FYN5!6o_neHpNL94i*^EgVHBGRlCqnks%[%WpYKN_s8N)U
+s8VsFW:TVZKE([YhYXPXH1eA8m+,9aq>UBplDjc3!NPGYrrLsVrr38u/]mb+%.jMUrdP;o!.Vu9
+:<E7qIperKrrVV,J,]Hh`LPBETPD1?TOP\1Wa`3rOA<pll@2,"s#$23mXICsrrVHcl@Jtds5s=]
+K_)kYn!m.'~>
+o)C??p[[_8jPS_De'H4Y`PTC']=GDZ[C*BK[C*HQ\\#Pj_SsU?cdUM#i8j.joD/@b"8?e.jnSiU
+g\h'T7"Y7+@qF*g.eRH2q5sehs5t/):B1@eBAWHe!qAa$lgW&BW:kFJjkjK^li2HOm=0!?qYqB0
+O_CW^o;[NErrCgRs4[PRrrC[NrrCgQrr_F"?V^.k!psiSrr3Y*A%hT:A?u6TNNVs9?$lV914e9\
+li6uHNNVs9?$lV#;9JY!Iq#,ORq]h/[U,O)`gtNETkqFBRq]h/[U,O)Tjr]Mo4)A3o.7oU_@5o5
+kq[hGrp'UbhYr!ID#f(*igXZ#m^?GmpO6Q"n\JFkq2]gXgh2'0s8TiEU](3&mgc_rn!#$rs#?J9
+m=.7nrs/"A@FOb_>EJja%..n]s8VnUH/@=hIJ<L9#1HGlpZm;sVuHhPB8c]f/,HEDldJs]q#BLm
+?V^Y$ok3.WXoe,_F6iLl;ZH+cc2GKZfDkl#D=)gimJ?him;7?O=e4dATe_,rrrME9qgSUqpAY0J
+!<)p-31B='IpS]<NEWOHlg+6Bs"sFnBBA#ZC[7p%S`o@4AH;a-@G:J4AH;c1!8IPRq'r93o;[NE
+ok3.WXo`n?Y+t=3=F']@rrMDcr-naIl1Y,XgAq6Q#kKUepVI@-s5*a)$Z,ln`m[f-pZm<<U&P&n
+m;7@PruT1NdI!WD^&Od9^%SL;ZK[NLb4k4O70!9HRd]Wn4T#-[k5st#s+144rr@ZB[K>c`9n3~>
+o)C??p[[_8jPS_De'H4Y`PTC']=GDZ[C*BK[C*HQ\\#Pj_SsU?cdUM#i8j.joD/@b"8?e.jnSiU
+f)5OO6%o.,@Uddc.edT4qlp.ms5k#%:B1@gBAWNj!:rX#lL;uBW:tLKk29Wam/MQRmXK0CqYqB1
+P%^fco;I<ArrCpUs5!bUrrCdQrrCpTrr_Bt?;C%j!q'uVrr3Y)@__Z;@^,mOMlla9>'p;70n8'Z
+lMplGMlla9>'p:t:<E7qIperLRV0P+[pG[+`LPBETPD1?RV0P+[pG[+TONTOo3u2/pFXM]`=2A<
+l7meFrosOahYr!IDZG:+igOMtm^HMoq0uf%nA/:iqiZ<ahIqE7s8TiEV#C<'o*i%umZ\mps#$23
+mXICprs/.F@+=\^>*/a`%.8%`s8VtZHf3aoJ,/j=#1?8gpZd5oVuHhPArHTe/,QNEm+,9aq>]Rk
+?;CP#pLi@[YlOAaF6`Lm;ZH1ccMt]\gAh2&Dsi*nmeZqjmVdTP=J"aAU,.;trrME9qgSUspAY0M
+!<)p-243h"IpS`=N``LGlK\$?s"sIoBBJ,[D="-%T'5I6B)qs,@bUS5B)qu3!8dbUq^JK8o;I<A
+pLi@[YlK(BYG1C7=F'`ArrMDbr-naIlLt5Yh>mQT#kopmpVdR4s5*a)$Z?#p`R7N'pZd69T`4rm
+mVdUSruT.LddEcC^&Oa7^\=a;Yiq0DanP(M63$sBR-sBl4o>6\l2^+#s+144rr@-3XTI[M8q6~>
+_#FJZ24=1<!8dYR"gq6XG>?9.s!mnDC3sSoqu?[k#d"(+qbh0UB3+o?:31PeCrQ:?<-a6u8@SVK
+Dsi*nmeQkuc[Au@G>aP&rrCpUs5!bUrul13rrCpSrrPq$XRZ;lmVdUSrt=%<BmX<IjT!2W:3Ub_
+gAe\`A,U3Cs#Q'5GB6sAs6<coGB6rEh#GrT@WQ"0f`/p,@Wc:Om/PXd@WQ"0f`0ZX;L`mcaoDBM
+>'F.gs8TV0A,U3@rrLsVrr3_aIq!J.J_:"7BP2BqF34Hd?>4+a\,QC/Q=.i4rsa0UF)t6Ds8T3!
+F)t6ap\tH0BP2BqF34F]!q'uVrr3/+?>4+a\+]h+l<7M<F'?,PrrVP(J,K<srMEnBEF,UBs8Ph"
+XT/=t;JLPk<r9F&F*CB;s7\ZlLPR*ls8RRemXK0CqYpojDh$]#>&SV%0n90%!UA85IfS'nrrLsV
+rVm5,;KHnWJ_8a_0k^K$!4De*)uH('H&#?i\)<$FDg-&.!<9l1Ap8H/!<<'!hZ!NiTNZP`;NUqU
+;JLPk<iGnm??:*mW;Z_q!U?]_IfZS7pAY0M!<)p#@TmtZDu9PBh>mTUl<7M<F'=FUrr3&fDh%cd
+*lVr)F_7*/s4W*>HX_oooV,MqGB6rus8T3!F)t6aqu6]R!.k0$s5j7\K_)kYn!m.'~>
+oD]U(p[RV5in`;;d*0SL_7mOk[Bm-BYHIi+)Qp9JZEq!L]=u,#aNW#]g"tcQmIL&Ps3!9fpAY-I
+r;Qr/;1Ejdb0p;>q,;'SB34p/s%Wp(s8VmnCO'Poq7'1@F^o:-qO(?/LfR*Vs*nnQIr4TKrt`t0
+=a,'iOoPF]g].<.!<<'ACY8Xeg\q-R:("/orrVS)J,]H\g4O'dA;oUL`f3f=F'I;s[K'h9C]FDq
+NDOh?>M/uA>@D_u=GY`3eUM(M@Y!)1`c#C1B:8)ceUM(M@Y!)1g4N7PGtuN^rF8uS>AsK?[K'h9
+C]+25gAq6Q)qBFJF(0[OrjuoYF_#R8rif^BBk=aPs8J6iaSl,KrHVUiF]4P)s/].?F&9+9rs/M7
+C1qa#F34F]%..n]s8W)&?>+%a[f6%$#4#K%GBI#tVuHhbCk)B_/,Z8OEc>Bar;Zdl$EjF/q,;'S
+B34o=:31VTMuWH6CPRckDu]ieD=)gimJ?him;7@2LK\V?D)$P=rrME9qgSUqpAY0J!<)p)XAa1]
+:k70O>;9diCB1d@ru:g&<I'C$8[mW5>&SV%@fZPG9kSZo@fZQ/!8IMQ'r"iTG?'e*q,;'SB32&-
+VI+@_?`<o%rrMDcr-naIl1Y,XgAq6Q#5r%7G?]"ar;R/Z!<<)b>@D_u=GY`2rrVS)J,]Hh`c#C1
+B:8)cg4O'dA;oUBUK_/NF]c0Rs/].?F&9+<rrLjSJcC<$jo5=4o<n_dRSA;~>
+oD]U(p[RV5in`;;d*0SL_7mOk[Bm-BYHIi+)Qp9JZEq!L]=u,#aNW#]g"tcQmIL&Ps3!9fpAY-D
+r;Qr.;L`mcajU2=qbh0UB3+p0s%Wj$s8VsoC3sSoqmfICF^f1+qjLK0LK$gRs*ntTIrFcNrt`q/
+>'G0gOT5=\hZ*W4!<<'BCYJdghYmHU:'drkrrVV,J,]H\g4O*d@Z0=I`J[K8F'@;t\H$.<C]FDq
+Mb\J;>2'#A>$cDo>)D&7eph.M@Y*23`GB"+At&)deph.M@Y*23g4N:QG>?9[s'f/U>&XH@\H$.<
+C]+25h>mQT("RkDF(0^Qs1;rWF(044s0,gDBk4^PrrSKoao)/JG?T'/;O%4]X\s4];R,ur#.nP]
+F(044rr3&fDh%cd"gD<IBk4^Hrs%al??^Ho\YoH/ltq7Ms""&F??:*mW;Zbr:'ds$s8,]/HY6CV
+\P@3i:5f/H4_oh/+`ID\IrFb)DsmK%$LVh^i.kKSGAT'arVlo`f)'psf(T+Eh>mNS$E[3IF&ISA
+gfuRHrbDMArVmi6RT+Qf<(OLVLK\V?D.<SG_+nTdG@LXQrrCpTrtV21GBZrHs8,]/HY6BXqkd\@
+EF,UBrr3#aWr.>IWp9<X!T!hTrrce7G?Sq^rsRZ`s8V@f??^HoM;8+1!q'uVrr4%YCgqO!RdC(.
+K5#[AMraN)>$cDo>.O\5X\s4];R--!!T!g-s+143rr@-3XTI[M8q6~>
+_Z'`8ImMo`rrCpRrri5(K7g_]rrgT)Iur7\rrRfmmf*5*c&7(5f)PcXLP(]/pAa!BKr22>_>h9Z
+p:n*1q>V6-dB%tQV"=WdJ+!@:mXP9:TRY\qJ+!:8!eVK\nc&[a\%hqB&H11KK:^lus7YlNIuDSO
+s3:Fjs8N5iS:?IArr4:uP^eJ%hZ*WSe!PcXf_tjD`JoSQk5YJ[e!PcXf_tjKf!0j[\c2U6g5pfK
+irB&'qg\PD!UbI:rtYL]R"Lp]rVuN/OF`_Bq>]fhLP`Y4rr3&9Y3c)d%I0U9K;eDAs8/mMK=1UN
+rs&,7OF`_Bq>UBqp:%g9rrqbsLP`Y4p&>0KP^eJ%VZ-_cDh%Za"m2n?LU6:FrrRfmmf*5*c&7(5
+f)PcXLOYubs8TcbLW,p=s8TjCp:n*1qYpor\%ht$VM0r9W5%Ts!UbI9rs8M'K7gSarT:!TIfR7]
+ru0aeKr22>_>iGjKo<@eJ,fPbMgq,BJ,fOumf*5#pT0""V"=Wdc&7(5f'<:tXG)G9lKS<LmXP38
+"PSrePiDT?!UbI:rrq,@Itt_orVlrm\%hqB(&#V+KrjG:s8CN;K:^lus6SI(Itt`:rrr;$K7gT/
+qu6]R!.k0$s5j7\K_)kYn!m.'~>
+o`#a*p[RV5iS<&6cH=,B^:Le[Z*(1.W2HNkV&?/.W2cr%Z*_!O^;@n4cdUP&iof\!om]9`p&>$H
+r;QosY_@eBd/O6oMgpl=rr3%P*q0+.)pX@kOjsF0[YKNuaS5_kTSBDPPJ[@7[e@JEpA+_(qpDL!
+K;S8?s*sG9s6Y=9s.Fqqs*sG7rrRfon+$DZp9qa8rt,.ZRY@Bhs8Vi^SUldEs8U=?J,fNOn"##h
+bl7VgfTgrC]\NMdr6gpbSCd`>pVr8LXl]T_r6gpbSCd`>rRJ-+Kt@9`#MP5gQ/hoEbklnfrrMM:
+rr3r8d[,WWfDYaB`fYn>c2%D+[>0XPnc/Xg^om#$rse:gJVC&os8VnrK8$]0p\tHj`fYn>c2%A=
+!qs(;rr3/g[>0XPnb)ncfTgrC]`"c.!psiSqu6i^XbDS;l2L\aK-'L\ru97AJ!&7\rO.K4U@8-^
+^4V9^U4rXI^UEjN[eBRt$MLpCs50]-Mm]P!l2LeOJ,TBQq5f4&[+G9<VYkoD^\n*MhOoV%[$/B,
+hkl*c[F0R)s1jPBQdUB`s*sG8rtP4/KnH8os8UB&J!&7Fs5pG;LpQ@1rrMM:rVm#SO+3GTqu6]a
+J,]HPfTgrC]\NMcrrVo&^]+6SpVr8LXl]T_rRI?jTA9JHle%JPM7ifes7raKKs^aSrrLjSJcC<$
+jo5=4o<n_dRSA;~>
+o`#a*p[RV5iS<&6cH=,B^:Le[Z*(1.W2HNkV&?/.W2cr%Z*_!O^;@n4cdUP&iof\!om]9`p&>$C
+r;QosZ%I\>d/O6nMgpi>rr3%P*:Eh+)pO:jOOjI3[>0Bra7fPiTS98LP/715\+[SGpA+_(qpDKt
+K;A,=s*sJ:s6bC:s.Fkqs*sJ8rrRfmmd^;Yp:%g9rt,.[RY.3es8Vf\S:?IAs8U@@J,fNOm[Scb
+c2R_hg6@)B^#&ehrR7-dSCmf?p;N#FXQKQ_rR7-dSCmf?rRS6+K=V!]#MP8hPiD`Cc23"grrMP;
+rr3`3e!PcXf_tjB`K5Y:c2%D+[>0UNnG`Fh_63/&rse7dItO]ks8VttK7gT/p\tHi`K5Y:c2%A=
+!qs+<rr3/g[>0UNnFceag6@)B]r(f2mVdUPrrqPdKnm#"rr3%P*:Eh+)pO:jOOjI3[>07)mf3=#
+K87F=KE(td\+[SGpA4drp:%g:i223d[A^k)rrMP;rVm0#XFl/5f_ss0r-n^]r;R\lTS98LP/71V
+VM0r9dXV;s_2Ef1dXV;sJ+!=9'_e\]K;A,=s36IOOOi^sk,a8lZg-fT!UbI9rrh&;J!AsirrMP;
+rr3/UP^eJ%hYmHUp:%g9rtY7HNJ4Irs8W&KRY.3es8VH>P^eJ%rr30!XFl/5qtpBoh>i-,JcFj3
+!-@b6!p>e?J,~>
+_uBhh3f<n.rrCojrrVdmDnl;Ro2]d\s+13prr_b1H27+4!qTH2JcCQ+!r&c)JcC<$jo5=6o=Y4o
+S5+S~>
+p&?oJq"!e7iS<&4c,df;]=5,NXJr+oU7n3NSt2FDStD^OV5L>qYd:gN^Vn4<db!:6kJfK;rUg*i
+gVEgkrUX01_#FN8o3$!_s+13prr_b0H2716"TJAk=`8lkM#RPNX:Bg]JcFj3!.sgN!pc:LJ,~>
+p&?oJq"!e7iS<&4c,df;]=5,NXJr+oU7n3NSt2FDStD^OV5L>qYd:gN^Vn4<db!:6kJfK;rUg*i
+f"_4do2]eErrVdmDh7q>s3:QGn8WaLo`#!a<c<QhM#RPNX:0[[JcFj3!-@b6!p>e?J,~>
+`W$&=N&oJZrrCokrr_8%3RZsf!UQobIfY,:kl1bEF#h["s+13prri.Z:pp2prrhiNF#h\/rrMJf
+qgSWt_1DWjrrV>,F+O@Bs5j7\K_)kYn!m.'~>
+pA[&Mq=F":iS<#3bf@T6\[8TBWMQ>^SXZ%7Q^3o%QC!u,S"64IVQ$]%[CO#ga3;r_g3bcsoDJ7\
+!8G<h"5e/\cK"p*l`Bu5!J82Prr_/"3mN<VJcF!p"Sn*T[JT^u"Rk5h3mQdc!UHiaIfY/<JcDtS
+!p=cMJcC<$jo5=4o<n_dRSA;~>
+pA[&Mq=F":iS<#3bf@T6\[8TBWMQ>^SXZ%7Q^3o%QC!u,S"64IVQ$]%[CO#ga3;r_g3bcsoDJ7\
+!7nsc"6+A^dc:?.m&^)6!J/)Nrr_8%3RWKYJcF!p"Sn-U[JT^u"RtDl3RZsf!UQobIfY,:JcDtS
+!p4]JJcC<$jo5=%o;r)WPY-H~>
+`r?.t6@Se$rrCokrrV20W8dgXm&^)6!J/)NrrV20W.Fu"s3(EEeX!iEp\t?bid[odrrMJfqgSWt
+_1DWjrrVW!k(3P`s5j7\K_)kYn!m.'~>
+pAZ$,o^:r&gt'lr`kf<sZEC4)U7RjAQBRGmO8Y(VO-#NhQC488U8FrnZa[T`a3:tOD;XUHp&=Xa
+!8G<h"6"a.rT!nYl`Bu5!J82Prr_50W;V;IJcEso"4`[KqtL*nnDSkqrT!nYl`Bu5!J81>s02M)
+n$qP3s+143rr@ZB[K>c`9n3~>
+pAZ$,o^:r&gt'lr`kf<sZEC4)U7RjAQBRGmO8Y(VO-#NhQC488U8FrnZa[T`a3:tOD;XUHp&=Xa
+!7nsc!oe^.ir9&GXS[JJJ\gRM!oe^.JcC<$bPq[pQFm%grr_cMJ#MB,!UQobIfY,:JcDtS!q*V]
+JcC<$jo5=%o;r)WPY-H~>
+a8Z4/1s5:e!8`;,JcC<$JcC<$JcC<$Qi@&=o=Y4oS5+S~>
+p\u00p@.>,h:L&u`kf9qZ)jjuT:;13OcGBXLkkq`)2F$*N/s*cR%0hFW3*>6]YShBVV'bdlL=Q@
+rrCf)s+13$s+13$s+13$s-N`cK(HDPl^COu~>
+p\u00p@.>,h:L&u`kf9qZ)jjuT:;13OcGBXLkkq`)2F$*N/s*cR%0hFW3*>6]YShBVV'bdlL=Q@
+rrCW$s+13$s+13$s+13$s-N`cF7ZL8kEJSh~>
+ao;J*9Q9aorrCo,s+13$s+13$s+13$s-N`cK_)kYn!m.'~>
+q#;<4q"!b4hq?H%a2,BrYcFXqSXG_)NJ`LEJq8FMIN!]eK8#)<NKKKoSYE$`Z(s?Z_9LH^hra:r
+r:^-jgO]BUs+13$s+13$s+13:rr@ZB[K>c`9n3~>
+q#;<4q"!b4hq?H%a2,BrYcFXqSXG_)NJ`LEJq8FMIN!]eK8#)<NKKKoSYE$`Z(s?Z_9LH^hra:r
+r:^-jeq*jPs+13$s+13$s+13:rr@-3XTI[M8q6~>
+b5VO`1;E2U!8`;,JcC<$JcC<$JcC<$Qi@&=o=Y4oS5+S~>
+q#<DPo^:o$g=4Eh_S!=]X/;S\Q]dAdL4b#)H[0j[G'8(SH$asiK85>EPF%f5VM6=P]Y_b9e_B'H
+me6AS!8E))JcC<$JcC<$JcC<$Qi@&;o<n_dRSA;~>
+q#<DPo^:o$g=4Eh_S!=]X/;S\Q]dAdL4b#)H[0j[G'8(SH$asiK85>EPF%f5VM6=P]Y_b9e_B'H
+me6AS!7l`$JcC<$JcC<$JcC<$Qi@&,o;r)WPY-H~>
+b5VM6o'?;UhLY]Xs+13$s+13$s+13:rr@`D]`RYm:4N~>
+q>WSVp[RP/h:Brq_nEOaX/;PZQB@,]K7A8oG&qYBDf0H2E,fuCH$k-qLl@I^S"ZFKZFIWeb0ehs
+jQl@5p\t6JJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+q>WSVp[RP/h:Brq_nEOaX/;PZQB@,]K7A8oG&qYBDf0H2E,fuCH$k-qLl@I^S"ZFKZFIWeb0ehs
+jQl@5p\t6EJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+q>VH3o^1f!g!\*`^U^YOVkKTFOGejEI<fsTDJX'$rF[*`C2@g/Fa8CeL5V1[S=uj_ZamlkbgY;(
+kO/$Bq#:?KJUN)tJUN)tJUN)tJUNl5!.sgN!pc:LJ,~>
+q>VH3o^1f!g!\*`^U^YOVkKTFOGejEI<fsTDJX'$rF[*`C2@g/Fa8CeL5V1[S=uj_ZamlkbgY;(
+kO/$Bq#:?FJTHB`JTHB`JTHB`JTI,uo;r)WPY-H~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qYqT8q!mY0gss`l_7R(WW1ofJOGegCHZjFIC1h'd@/XFP@:Ee\CMn0:I"@$1OdDT5W3<VA_TC-T
+h;mnlr:p9lgOXd(I=ZftI=ZftI=Zg5I/nlj[K>c`9n3~>
+qYqT8q!mY0gss`l_7R(WW1ofJOGegCHZjFIC1h'd@/XFP@:Ee\CMn0:I"@$1OdDT5W3<VA_TC-T
+h;mnlr:p9leq%mnF+JC`F+JC`F+JCuF7ZL8kEJSh~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qYrbWp$V#$g!\'^^:1>HUn*j7MhQ\-F`;/0A7/\I=]ea,=BSj6?t<qeEHZ\ZL5_:_StrEl\A#r+
+e(WdDmeHSW!8E'QJUN)tJUN)tJUN)tQ[Jjco<n_dRSA;~>
+qYrbWp$V#$g!\'^^:1>HUn*j7MhQ\-F`;/0A7/\I=]ea,=BSj6?t<qeEHZ\ZL5_:_StrEl\A#r+
+e(WdDmeHSW!7l^BJTHB`JTHB`JTHB`Q?2Z"!p>e?J,~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qYreUo'>Amf$DFR]!JN9TUD"'L4FVnDe`il?!2]mhW*(Z>Z+O%=^>HJCN+ECJVT5LR\6R\[(F2s
+d+@.9m.:5PrrCf)I=ZftI=ZftI=ZftI@#?^K(HDPl^COu~>
+qYreUo'>Amf$DFR]!JN9TUD"'L4FVnDe`il?!2]mhW*(Z>Z+O%=^>HJCN+ECJVT5LR\6R\[(F2s
+d+@.9m.:5PrrCW$F+JC`F+JC`F+JC`F-^n=XTI[M8q6~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qu7W7p[IG+g=+9b^:1>GUR[U1Lk:"tE,&rk>?JQ8ruUQG9M\Sg>@;#XE-?V]M3!snUT1T/^W+OJ
+gZ%Jer;$?mgOXd(I=ZftI=ZftI=Zg5I/nlj[K>c`9n3~>
+qu7W7p[IG+g=+9b^:1>GUR[U1Lk:"tE,&rk>?JQ8ruUQG9M\Sg>@;#XE-?V]M3!snUT1T/^W+OJ
+gZ%Jer;$?meq%mnF+JC`F+JC`F+JCuF7ZL8kEJSh~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qu8qZp$Uu"f[7gX]<n];TUCt$KRS,bCLpjV<NZ<$[q/EXh#HhD85)l\>$trYEd3(fN0B[&VlmG?
+_ogB[i90P'q>UHLJUN)tJUN)tJUN)tJUNl5!.sgN!pc:LJ,~>
+qu8qZp$Uu"f[7gX]<n];TUCt$KRS,bCLpjV<NZ<$[q/EXh#HhD85)l\>$trYEd3(fN0B[&VlmG?
+_ogB[i90P'q>UHGJTHB`JTHB`JTHB`JTI,uo;r)WPY-H~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qu8qXoBbPof$;=O\[&62SX,=mJU2BSB4+nB@f$,05!(ba5Nr-P6:OUE<EimEDKL5WLl[jmUoUf3
+_8ssRhW=+rq>UHLJUN)tJUN)tJUN)tJUNl5!.sgN!pc:LJ,~>
+qu8qXoBbPof$;=O\[&62SX,=mJU2BSB4+nB@f$,05!(ba5Nr-P6:OUE<EimEDKL5WLl[jmUoUf3
+_8ssRhW=+rq>UHGJTHB`JTHB`JTHB`JTI,uo;r)WPY-H~>
+ZMsp]\:an_Pja8,N6/p3KEB!3N.HY5KWTn0XldHU\:amIs+,jhKEI=XhPGdVJV:ajo=Y4oS5+S~>
+qu8tXn`o,geBGnG\$)a(RZi\aIWoaF@pE&2PQ1YW2`!0B0Soc&5sRk2:f^k3C2nHHKoD7cU8bB+
+^W+OKguI_krqcWpgUMY4s,QPr!enY.q0`=Y`eAtlJUOYK"01OuJ[g+/NrOZYl[8knaPEM?I=Zg]
+I/nlj[K>c`9n3~>
+qu8tXn`o,geBGnG\$)a(RZi\aIWoaF@pE&2PQ1YW2`!0B0Soc&5sRk2:f^k3C2nHHKoD7cU8bB+
+^W+OKguI_krqcWpf!oc%s+Ki^!dhboq/ZVJ_0^`SJTIr7"/P(iGIV\pK`?UElZ3/\`S-]1F+JDH
+F7ZL8kEJSh~>
+ZMsp]r.G33f)PKa_LqsiPja8,N6/p3KEB!3N6m7X^&EZoLp?7BhPGmYLlBpbpWibk%%QM\s43-^
+KT+L^pWibk!65!;&E9O>KVdQ&lEQ.uLp?7Bii2p1%&MhXlEQ.uLp>P2pW!2c"JtSen"p#:"e=cU
+s43/,KE7qLrIc/ehYZTCLkL_tmf2R[N.ck\hYZTCLkM#8p\4-Qqh,!Hs8IZO`r5o;`qY2f[G(QY
+!Qg<"K`AabKE[1:lMKG7nq7#;rIb?EkPtS5N3@m:N60%pl\#<5Pj<u,N4JBVlEuTLK`AabKE[U_
+p\2gpqh,!/`oMdRSD*o@!Qg<"K`AabKE[1:lMKG7l@]34Pjj>-]u>s*KEAj+N8TBh^&!B`ONkUm
+KRnfjK_)kYn!m.'~>
+qu8tVnEAibd`]P@[B6<uR#m/VHZX+:?W^3!XT.`G0J"\%-sQ`OCcXgN9N##$B5Vj>K8PeYTVns#
+]u8.Dg>_AerVHNog\cI&K$X>g_npg&s,QPr!enY.q0`=Y`eDfg!e7kord>6*W9*j2TRD6>L=?%o
+a8UJqP2H06f8>!)L=?%oa8UJe_u9THiLkUIS_Eo(Y(;"PXQTE:UAfQLS_Eo(Y(;"NW6bA8_u>&e
+Rd:">T)O-AP2H06f8BKS!M9>iI2ng3q<>&5I>>8sqrt>;I=7[?q<>&5I>bu8p$84HI0#r>rd=da
+rVll8pjE1Gf)5OP`eAhhJ%WAlI0G,!jn[`*o6gXkp\fLDP2H06f8?b[",4b3Ja7^bpQ"Qf#)BYQ
+qrt>;rd=it]Xn)j"cL7jou)jeI0#)?jF%&of)5OP`eAhhJ%WAlI0G,!jn[`*l?r^-NpqGu]#'0r
+I0.!sL#IF]K"S\kI0,8J^4C]`ID:11K(HDPl^COu~>
+qu8tVnEAibd`]P@[B6<uR#m/VHZX+:?W^3!XT.`G0J"\%-sQ`OCcXgN9N##$B5Vj>K8PeYTVns#
+]u8.Dg>_AerVHNof)0RlHd;Zc]u"gks+Ki^!dhboq/ZVJ_0aOMs0_iI%<nW1qq@EYF*Du^s7aP4
+Et"#as8UYsF)u]Zs7aP4Er`oPrt+%SF*!`&qs(,(F*FSJqqdkBEt"Giqs(,(F*FG*s7a5+Es.`j
+s6lKWEs7NZs8UYsr,Vn's8@!YR+hH&W-<<4[I4([Xa>,1R+hH&W-<<8^%;!eSGR@.PlL`(!58@2
+!58/K!NjrNrrKr_rcA+Irc86eUuqR.R.>:up\f.:N8FU7epFTA"+.ktGO';NpOqjR#(O&Ks6?_5
+rH&"Hrc86q^%;!;L\l,nHbJK]!Kbn1rrKr_rcA+Irc86eUuqR.R-J_npOr$W!k#^gpi?ME]mJ[Y
+s0_]E!e82"JTHB`^2rnJ!p>e?J,~>
+ZMsp]r.G7!kEMM2[DRXus-2u*!fY7;q1Jgcac+]%"GiSem_SmU,,s;0R*!pLKX'CbPappMKS9*N
+Pa(%]KS845PappMKS7q%rfegmLkMGL_3hpiWJ%P1[@"eYTS/ud_3hpiWJ%8)kEMM2[=j5-`f.V*
+re(ILes)EUhYi*/PkY4WKH6`6_3hpiWJ%tAXd$6M[=k4$_3hpiWJ%tAWMI6%r.G-9p](5G!S5Qq
+PQ6[;KE7$nrfd\jd]nI]SAjp4re(KTg:`lqesuGe",sA=s8@TSpXYRnhVPGh!fY7;l@]3<Pj<u2
+^##lU[GJ<ELn)HP_>])k^##`ag:c9p!Jlj:PR+D>Z%Rq'`U:SAKEeF0]pQpmSEkh/s-3#+!l<!;
+pk/^bac,85"H9J>m_SaQ!fY7;JV8T-^4c*k!q2XSJ,~>
+r;T+_p@%2&f[7gX]<eT8SX,=lJ9c-L@pE#/8$DsT0.J7l+X'JXs,Alt6:amQ?"@_kH%Cd4Q_(%T
+[(F5udb3RBn,)t]!8IF""ioY`QLD,sI0'A.msP7k`kM7s!ku[.dsV@MQGDn%rd>ube[UdZd$K0^
+gXh=GkIQ(in'd/SgY7.)gXh=GkIQ(if>mlR0ogm7REiI,[aUt!XP'h<][3-rREiI,[aUt!U=J:a
+QLD,-IIk1-[eGB%IIGXBNn`=eI0,;ts8IEfREiI,[aUt![bIa>Yh?1-REiI,[aUt!\CdOI[eGCP
+I0,;ts8IEIf>mlR!/gQ"!JZR4OpJ)8Y'kke_!Sl8I0QFr\<=_UQhGh0L8N`*rI"k<du'1?gTQ#,
+KuUjlI0'A.l[92MgSg(8frfaSQGDn%rd>!\fV4tg]RSac!J-4/OpJ)8Y'kke_!Sl8I0QFr\<=_U
+Qg9&#s,QSs!ku[.pjE4X`eEH$"GWf.mCrFF!enY.JUN)t^O6*6o<n_dRSA;~>
+r;T+_p@%2&f[7gX]<eT8SX,=lJ9c-L@pE#/8$DsT0.J7l+X'JXs,Alt6:amQ?"@_kH%Cd4Q_(%T
+[(F5udb3RBn,)t]!7q'h"if_YN:3mdErl;omrJPW_7BA_!kH-odrPY9OM0qirc99Rf!U=IcB*+G
+hU[@=kI#APn'6T>f%+n`hU[@=kI#APf#I]J."c_bPg6gqZ-o.`W7nA0\^$F\Pg6gqZ-o.`SCZkV
+N:3liF76M`[J0ZA"n0`iK\"`QErq$hs8I'[Pg6gqZ-o.`Z.>S$WRe"hPg6gqZ-o.`Z-o#,[J0T?
+!eg=Jrc8+k`r:nsHh_X_H\;<V#c,_DF*E_ZlFHn8#+X8PLqV)qp2^=_V:P\FEs;$XKS7q-YB'bl
+_7AiP!WRi=Et#>)TS0;qW,m0E^$<0-Es8hsR$cI4giEL?KDpf8Us5iZGEBN'\c-XSSCY*(^!;`*
+Erl;on8eZA_0bru!kH-oj)Y?MV:OqBqJu^b_7>,<JTJPHo;r)WPY-H~>
+ZMsp]r.G7JV1aN0kL"rDXmc;a[=j4Qp]'*7KS9B5n,N-aKS5;diqr#GLkMGTqtJ[u_1\ZAqsM"R
+KYcBjp\WC+KS6c%s7a5+KGOTikPt:YKS7&5s6$fiKS5<0p]'N`M"lW+OL<O%_>]*3^!;jqSBeNu
+`W(mMKVe-jSH"P$KUi'qN;niiKVe-jK^Z&?KJ's`P_>!_OGLlpLkM#8\V.ZAP_>!_OG(<mV1aN0
+kCf*"N.claP_>S,N.ckSs8@TPkKa,,KH@hPP_>!_OGq<#LkLl7_1]MIP_>!_OGq<#LkLH]Pl67:
+kKa,,KE:PDn:V+,_7bYXOL<O%_>])l^!;jqSBeP9KEIaif)P`&#+Y^PKS5lqYClt9ahdk-$&GkO
+qr4`6KTuN9KEd\@K_PN@XmLcXN60%pKTOHpKTNUilG8.,N60%pKYbchr.GB@s+H(*Xlo`YXltEE
+N5<2`KTNUilG<IQ#//<HKUg>qqh,66f)PKiN.dGqre(K?s+L.HpT=4D*LP.Hqpq:Nqtng/SC70/
+g7X,4qtng/Lontss43.pKERgjf':*JKE@+S_1@8jKYE-2]`RYm:4N~>
+r;T+^p$Uu"f?hUT\[&61S<T"fIWo^D@9QT&7%=5S/0l;V)&[#cs/.S15"/.D>%22bG^kI.Q(=_O
+Zb"#qdFd@>meZe[!8IF""o"U:IBqn\I6+Css7<OEIDbgZhi<,5s0Ctfn#CeaJuI`*kH'5_S(@E.
+d+Z3^T\]M6[Y9.DfZs*]b`dI'Y4)D^])I*ns/+uZn#Cea[dX7ZWrIKqK$X2gkH'70I0>D2cfr1C
+I3Z>GNI@/9Y^s[kMLBoEl[>*!L4+K9s*]Y%MLBoEl[=3IVLn_o0"/cZI=m]@J\o?XI>u1PIC@.T
+I=m]@ICdRmI=8E]I>\&VI=hKZI?snfI=7F]rI"b)a8c-e*k'(JI=m]@KuUoXI>Q+\IC@.TI=m]@
+K>bQTItI]\rI"b)a8c-e!pc_8nU1^t^:])HM6P=j^A`Nb]#p"\QccQ+I05eYe,TDq#+#:DI=7F]
+YC-J+`kM=u$%]8Dq;J3#I?+@,I0P`3IImL5VX8dJKuUoXI>Q+\I>P2Sl+VRoK>bQTJ&''Xr-\m3
+s*]=qVW\!JWp"j;Ktb3PI>P2Sl+[.F#.hs:I@&*\qgAa)fDG<cJpi[Zrd>!2s*aM=pSR_6*L"_A
+q9kV>q>8I"Q-T."esh)tq>8I"J#L]fqpU;cI0>kZe*4UCI0,,B^4C]`ID:11K(HDPl^COu~>
+r;T+^p$Uu"f?hUT\[&61S<T"fIWo^D@9QT&7%=5S/0l;V)&[#cs/.S15"/.D>%22bG^kI.Q(=_O
+Zb"#qdFd@>meZe[!7q'h"o"7&F04WQF#p/ds7`X:F1q>JhLorks/kJan"k)HH_fZuk+m3BPg]<t
+b1=+ER+hH*Z$UQ&f#mUYb)CC_V=4HY[Jk4_s.&9Pn"k)H[I=.YV>kUXHd;Bck+m4rEs-ulb3$86
+F!A$2K6*-sX`qJYHZO7mkAuU^HZO7es)WPeHZO7mkAt_-V>G<WZ,)'6H]3T$]tJW2K>"C.Z,)'6
+H]3Su[DeAOF04VHK`D$m$3,["N;n6GF,^.tErt4<s8I'WZ,)'6H]3T(_7b&6J&Ss>Z,)'6H]3T(
+_7BPd!WRiOErt4<s8I'?kG@Zh$%'4jGB885b3$86EsB%kK6*-sXnHf<N5j0Crc8:&s*Jg.N;p)&
+!dhboqf<'fW9X9:S9&b)s8I'DK`?,^s7`&NEu02>]m"OI`OU&>WQOA6F)u]E\T;i&_0c*$$&&>"
+F8qcns6lfJEs[3([<H\AWQOA6rc8:O`Ii5nb,tP^#^b/&pVq8qK`D$m#)*"tn,N-Ppi@I7b4ke]
+OKnQWabPhtp\WO+F0YK:abP)9cM.@aHg>_UN5j0*\b^@KHbm7DF+JDHF7ZL8kEJSh~>
+ZMsp]rIbB>s,;VaSH%#j<K-s[N33,=`p]FVf&q^>s6#W"^%[25f%.6n\_aTag<Q(QcMPGSg;T;]
+hR/$Qo=^*Ug:`/us2L"os,;Vas6#W"`qP/"pSEhFn,J&of%-(M\_aUbKGTTh_1[K#ai0'hONkV#
+ao@<QKUi'qN0O<p1:?S(PlH\qKUi'qK`C68s44H2LrJ6)qs(GBN60%pKTOHpLrJ6)qs(GBN60%t
+KS5lqr.G6]pOn3YPl?=:[I=*J*QHZps+H&]`ST>GlEQ.u^##`IZ/2mE`ST>GlEQ0DKE@[Op\faI
+`n$CSre(ITkPtS5N:_c)[E=m8KFEg]_1[K#ai0'hONkW6KE7>;re(<2Pl?=:[I:;P!g([Cqh,9\
+hRSleg80Ies8IZTPlHDis-2i&#//lmN3V6Ire(?3ahdk-!h@iTqh,9?s+H(*kELY>pZR83[E=m8
+KFEg]_1[K#ai0'hONkW=K`Bp/PQ^HpKTuN9KE[V?KS9Aipk0]E`R^QLf#<H]ac)%pii/<n`JB2`
+ac(nTf%-(MhVRLM!gLgCqLes0ai0'eKRnfkK_)kYn!m.'~>
+r;T+^p$Lktf$DCP\?W$-S!/eaI<BF??W^/s6>6E!G97\:&J;YTs04.44$uV;=C>c[G(,.)PanMK
+ZFRfmd+@1;meHYY!8II##)`G8I=7R]dX>,Ms/(OFs+\8RP)@`KI=;.UMLE)1I=9GhY)KaBXIIe`
+P`j,`^7EcfNiq-@ID56[K:CN)I>7d>L8+^*I=;.QNe5">ICAa=L7[l6I=9GjMN5'uXS.&YKuUiT
+I=oJTJUNI!]S"0&L4+K=qgF'Vrd?Q-kC&6fL4+K=qgEnij8]/.XFYr>gt;GcXFZ#B_L[,nb.N;B
+gt;GcXFZ#B_M3JeRf!&3#(ilHJpi62rd=gQkPflM_q1(OI=6[`gt;GcXFYl2et@\rf<0\Agt;Gc
+XF^A!"Fl`;o7Hsi"2i`Rs8IEMqr@_Vdt[LC!jK\.rI#*.`kHkLK>bWXI>c7\oR-b#s8IEIJr]hY
+!OCmlI0,2F^AE<bWnFb@][`['NrT*,"ciV2IK,>oI0Y83et@\rf<5+$!enY.r-\]tQHm'kr-\m3
+s*]=qhi<<&pZR#,Yf;n*I11hL^3tE^`57(RMor^0I0eHZNfrSCI?+@,I0GZ2I=;-UpjF37_U=a7
+d)(@J`eAu\iM;^b`.NKP`eAi<dF3u5gY:t@!fk:7qL&I"`k[(TI=Zg^I/nlj[K>c`9n3~>
+r;T+^p$Lktf$DCP\?W$-S!/eaI<BF??W^/s6>6E!G97\:&J;YTs04.44$uV;=C>c[G(,.)PanMK
+ZFRfmd+@1;meHYY!7q*i#)*#'F*!TGdW8E8s."G+s*M0:N-ik5F*%BEKQFQqF*#XTXb<h-Um0HP
+Mi5RK\WkCMK;@5'F1LnMH^**hF*mr#H^t+hF*%B<KQFj$F04nqH^+"!F*#XXKS6JYV"SjGHbm76
+F*ka:GB8DY\U20mHZO7ms)WO?rc9iskAu=VHZO7ms)W8]kPtS-Uj%$rg=H/`Uj%1%]m"OMaglW/
+g=H/`Uj%1%]mFgAPlLZ&"f:s7F*iT>EriE+rc9*neqF'EF*G=Of)+U*GB:%?S9q'_W->r/f)+U*
+GPuRaN2?:IEs',,K`D$m"omccs3>u`Err;VN;[f+Hbm76F*ka:GB8DY\b'qDK`D$m!IKM!EriE+
+YB'bp`OYke$)H.SLq1s$F+jSmEs76sF*%A7lZ398esq)_eu8Rh!dhboqf;gtcF*Oj$&&>"F8t*M
+F1q>3Err;VN;[f+Hbm76F*ka:GB8DY\bgIJecpedkIkqis8I'CK`?+7s+L/g*d><BMi5inGIbP:
+GJ2k'Mp9(bF1K,6F.gt4KS7q-l#QoZ_7BD`"+.ktGCagdF2)efXTI[M8q6~>
+ZMsp]rIb39s8IZPPlK0b7u[JUN.d.CpT9+%PdQ0ts.tC%PlHDqs2BeIN60&Td[5]@R+B*ed[5]H
+Un!+SdZfEDah`X`P`19cs-/1is.tC%PlHF*Xo<t]XoF'5s,;VaN60%ppOj6>ah`X`N6/nhKT+$h
+KXL!oPapq:rIch_`qQ!VK]gpNSEKp*N9@U%Pipo*N61@mPe#MMKXK[ER)/C1N61@mPe#MMN6/p8
+KE7>;rIk4N!3Q0P(Q?B.S:lQtmu3M2KS5<+lEukeg9$$mdf07Qac)2#lEukeg9(@-"2Y$;Xo<t_
+Xm_45s+H&akI#u-kLT<Z!h@QDr.GK;ah`X`N6/nhKT+$hoRm70s8.HON5kU^YCltRf!YF/$Ac[C
+N.dSH]nDXMre(H>s+H(*Pl-17Xo&+uXn[PMPg]R2!Qg<"KE@+S_>Jrg_>i)Rqh,9?s+H(*V1aMd
+s87NMXo&+uXnIDLSBeP?KFEg]_1[K#ah`X`N6/p6KF*V;P_=^lpOne2re(H>s+H(*Pk]n6LrJ)@
+reMDE_9%XhN0&jWc,kot_9%Xl`PmdhKTuLqrIb0Qqu6Yup4NL3ahde+!kI$]JV8T-^P)3l!q2XS
+J,~>
+r;Ru=o^1bsf$DCO\?Ms,RZiY_I!':<?<9on5WRHrlr+W/$\86V*47:P3^H>6='oQWFa\q%PFJ;H
+Z+7Zkce%%9mJ$JW!8II#!KR3ZI0#N2dX=W?s/ps%Jpm*^I=7!YI=;-eI=7:YI=hL;K7/Hn_S"0X
+I=7=/^:)+DI=n,XID4!dI>>nXI=dW6I?snnI=;-eI=7:YIIF'4I1)qPI=hKVI=6gh_L_H0'SXQ@
+I=6gh^3tEbaM*).kKf$Kj8](+08@C9RXKVIc\dnGs*]X^We-8kgSfhGl`uPZfr0>)gT6FHn\0^s
+l`uPZfr0VE^A`N]P5kK/s8N)!r-]iF_t0=FIA61bNrONUKuWGaNjdW>I?2bTs8BrmKuWGaNjdW>
+rd=m_s8T+uI1;q>L5u:^I>6d^Jr\m?omHn,aKYSj%#)^8I=6gh^3tEbaM.:p!KR3WI055Ao9uk2
+!hIcFr-\p%^rV:ZO34t\NrT*,"ciV2IK,?*I/p/ArrB(oI0PbZs8W&;L]2]'KuUk)I074`e<BcX
+$',%6IK,meI?OX.I/p/ArrB(mI0,\TYl&nXKuUiTI>,\TI=6ml^ANBcK)_!^IA6=]NrT*,"ciV2
+IK,?&I05&;esQGd(k'-<Kn"u;Iu2=fKmg\TKn$nVMLBo5s+^K#!2fYn!35a@!fk:7q0`=Md[br;
+JUP=^!.sgN!pc:LJ,~>
+r;Ru=o^1bsf$DCO\?Ms,RZiY_I!':<?<9on5WRHrlr+W/$\86V*47:P3^H>6='oQWFa\q%PFJ;H
+Z+7Zkce%%9mJ$JW!7q*i!JLLPErh7"dW7p*s.t'`HZSYGF*!#:F*%AGF*!$7F*mr#GB8,I]sZ"A
+F*!;g\Zs,/F*j:9F1KDFF*ka6F*!:eF,^-PF*%AOF*!<?F75t)EsniEF*mq6F)u]E]m'3l'RR[,
+F)u]E\T;hA`OU&lkK\a>hZ*Oq071D,P]Lp/c@h/5s)WPMV/q=Het@B+lE,`Eet@)dg8Tn9m^[\\
+lE,`Eet@B+\c-XNN;rits8N(qr,W[$^%[b4F.D]GK`?+7Hbo!LKX'+$F,/$>rs?YoHbo!LKX'+$
+rc81Ps8SqpEt+Z.H\DE?F*m)HF+iDqolC1n_5R9Q%"#h$F)u]E\T;hA`OYV^!JLLMEs$d&pQVk&
+!gqE<r,W3h]u>JBLWQrFK`D$m"bcnsF8ppkEr_a-rrAnjErh'@rr3#<J,XKjHbm8jEs&uQdZ"'E
+$&&>"F8qbOF,^.sEr_a-rrAnhErq<:W;L]FHbm76F*ka6F)uiM\bpLTHiK%GF.DuGK`D$m"bcns
+F8ppgEs$X"dZFHP(j!7(HZO[hGCRTJHZQa6H[!0:HZO7]s*O]c!1`rd!2]C1!eeD#q/ZV>d[5T,
+JTJSIo;r)WPY-H~>
+ZMsp]rIbB6s,;VaSH$ui#Gp;OkH0F;Pl$+=s-/1iPlHE$qu?Z?#`s^mONkVXac-.N)8XFRKT+$h
+KS6Jjn(.N'KS9AiKS5TiK`@SAKEIbEKTuB6!R6`#KG9Be_1[Jt`PmXdONkUpN0N3!pVut,KEJp^
+cA_aU"dImDpVut)KHd8@_2QLTLkLl7_1[cXmebkt]o:(PLkLl7_2-(LN.ckSs87NOXoF@ZKI+>+
+cA[F0PkV#5SH"P$N60%pKTOHpKY?6AN3V6IN60%pKTOHprIbQGXoF?5PkV#5SH"QFKE7qLon3C[
+cBS6[%#i<EKS50#`JB2/c,'%*!L3W^KEJp^cA\r["-CdUPl-1AN6/nhKTOHpKTuN9KE[V?KS9Ai
+l\#JUhPlI=hR3?9!fY7;qh,'=f#<ICKF*nCKS9AiKS5Til%B,OcBS6[%#i<EKS50#`JB2/c,'=2
+!L3W`KERhFKTuN9KE[V?KS9AipOj?I_<UL3R"W;tN.dS@lf.3ON.f$hN/YmUrrASSKE@C[_>/`d
+SCYN4JV8T-^kD<m!q2XSJ,~>
+r;T+\o^(\qf$;=N\?Ms+RZ`S]Hus4:?<0il5WDX/s8CHWir@`bs/7D&3C-24='fKVFa\q%PFJ;G
+Z+7Zkce%%9mJ$JW!8II##)`G8I=7FYd<u7kg\9a*IK,K-I0]e8I=7.UI?+4)rl>A#I=6ml^:q[D
+r-]HsaG51t`kHkLWorQss,MMUs,qeYNrOP-P5]k3P5frjqu6]<L\H32KuUiTI=oJTJUNBr]R>Ko
+huE;^p\oRC[e%Osrd=s1huE;^p\T@_R``9q`57(RMor\\KspIGf\3oh`57(RMor\b`577WI?sd.
+I0-GCK)U0E[e%OsI=7"ESq<:.JqA`q_L[,nb.N58fV42'fs$+I_L[,nb.R\$%$R^cJpiOJSq<:.
+JqEoK!LioYI0-juO8OD7KuUiTI=oJTJUNBr]_$UQNrT$*"1IgAMQ_F1M9=,'r-\p+`kHkLLWI2X
+NrT*,"d8n6IK,>oI0Y85fV42'fs(I(!enY.qgAR1d(Fl+I0kr6I=;-YI=7.Ul$WWAaH-7I%#)^8
+I=6ad_L[,laLqG!!KR3ZI0>`5I?+@,I0Gf6I=;-UpO*j;]]nh%OaXs`Kmf0+kMPUFKmg\TKn[PD
+rrA5II0,GK^A30ZQdiZtJUN)t_0l<8o<n_dRSA;~>
+r;T+\o^(\qf$;=N\?Ms+RZ`S]Hus4:?<0il5WDX/s8CHWir@`bs/7D&3C-24='fKVFa\q%PFJ;G
+Z+7Zkce%%9mJ$JW!7q*i#(-AsF*!<?d;oPWf(\$kF8q3rEsM_uF*!$7F+jGjrl#.mF)uiM\[f\/
+r,Wad_0^6M_7=W.V<@$ms+GH7s+GH7K`?,nN;dl#N;msPqu6]9J+n!uHbm76F*G=2GB88Q\T<+N
+hZ*&Xp\o49XnThgrc86rhZ*&Xp\T"UPf^I__7b&6K?:ZFHa3#5f%RNY_7b&6K?:ZJ]tJc6F,^.s
+Err34HiA(4XnThgF*!$/P^AAhHZOPM]m"OMaglK#g73Mceu3r3]m"OMagq@k$]LqVHZOl7P^AAh
+Hi%jbPlLDt!jT_"r,W9n_7=W.GJ1\6F+;0>oQ(%ds86p?XnThgYB'eq`Q<c1Esd91\T;hA`OU&C
+s8I'CK`?+7s+K]Z#.<0TH_f5krc8-f_7BGa",tO9GPlLgK`?+7s+GH7K`C:X!jT_"r,W9n_7=W.
+GJ1\6F+;0>r,Vmls8I'BN;msPs8I'CK`?+7s+L,f(PB-XlFhso\\WW6N5k&;lG7gg\\WW>_>F64
+N9YHcKYb4pEs%NP\T`UGJTJVJo;r)WPY-H~>
+ZMsp]r.G7JV1aN0kL,#RN2;2\XoF@SV1aMdc@glNP_=^Ss+H@2`JB2'P`WT,R"U-[f"o&FP_>"#
+WJ&+0N.d/3_1[dIS:lRqP_=_iP_=^Ss+L-Kre(W\s+H@2N.ck?P`YTl!fY7;re(rucBO!PcF&=a
+P`19K[GHRicKCGiKF!g$KS6biKUfILKI*/1]nF5DN.dG@]nD?+LkM;?Z%Ts8N.dG@]nF)EV1aN0
+kCefNre(LUP_=_8kEPpu!2]Sm)nho\ac(n;cFo1Y`JB2/c,#(Lac(n;cFo%AZ2TCYs-/25qu6`2
+S@/?L!M&oXKE@Oh^&*HaN6/p8KEf-8P_>RP[If+QPlL]8!m]tnXFpYFcF*S'$Ac[CN.dSH]nDXM
+re(HOs+H(*PjF&.N60%pKTOHpre(]=ah`X`LpaL@KYbchr.GB@s+H(*P_=^Ss6>7=R*r\FKE@+S
+_>])l^!;jqSBeP?KF*V;P_=^lpOne2re(HOs+H(*Pk]nQLmXE[R+B64_9%Xl`QaKt_9%Xh_9%Xl
+`PmdhKT)GcKE@C[_>8feLrIW#JV8T-^P)3l!q2XSJ,~>
+r;T+]o^1brf$;=N\?Ms,RZiY^Hus4:?<0im5WLPf[.jV#qP5:ps-5)i3C-24='oQWFa\q%PFJ;H
+Z+7Zkce%%9mJ-PX!8IF""o"U:IBMVYI7JmXI=8!mL@_-fI>Z'nIK,=UI?+>UK)`]=I=I34[`jq`
+I?W0p\B9k\K;bMm^;bkTKuUiTLB!]jIK,=UIK,=UI?+>Uo;;M8$E!iOK)^RRI=I34p3d!r`kMG#
+'=u>GI?hmXI>*]5I=89QI=9;rNr4;2Ne2\-Y1nAjY5Wi&R`N'g]Y];LMo`JXKnt5,Q,KbP]Y];L
+Mo`JX]#pUmIBMUYMVE`2K)^jZIEUN.rI"[;qu7kKRCpChI>c1XKuUoXI>Q+\ID!FLI>c1XK<hY0
+ItI]\I@g?9!k+Dtrd=g9p\'":Oik-0I0,,B^A`Nb]#p"\Q,p3%I0#B.rI"ajhi=dd!gh-:r-\p%
+^rV:ZO34t\NrT*,"ePaBIK,>oI0YJG^jgchb.dk'%#)^8I=6aRY((r:`eF>=$',%6IK,=UI?+?m
+I0,PR[ekISKuUk+I0R:*NI@)5Yl&nUK)_!^IA6=]NrT*,"ePaBIK,?&I3*luMg^`9_L]G@Kn7+b
+Mg`=ZKmg\TKn$nTL4+K%QK`f!NlJg0I04u7aG5=pJUP=^!.sgN!pc:LJ,~>
+r;T+]o^1brf$;=N\?Ms,RZiY^Hus4:?<0im5WLPf[.jV#qP5:ps-5)i3C-24='oQWFa\q%PFJ;H
+Z+7Zkce%%9mJ-PX!7q'h"o"7&F04WRF%:SAF*!lOHhX%OF+hPSF8po7F+jR7HiLd'F*E7dZ-&#H
+F,\PX[E42FH_m6R\\WW6Hbm76HiK=OF8po7F8po7F+jR7pSIk1$Cq-;HiJG6F*E7dp2^:^_7BPd
+$+7a)F-+PHF*iT>EsAc'F*#@XK`#lkK`6#qXkn,XXo<AfPf:%O\\WW6K>k6>H[BgTON"/>\\WW6
+K>k6>[DeAOF04VHHe/1;#60?tF2m'irGqt'qu7VCPe"VWF+_H>HbmC>F+;0>F1K,6F+_H>GGq>:
+Es)GqF-QS%!k!uhrc8+)p\&Y0N68F&Erp^)\c-XS[Ddc>ONO]tErgsorGr%[hLqtO!g(R,r,W3h
+]to&:LWQrFK`D$m"e>U6F8pp[EsI'.]m"OI`OYth%"#h$F)uQ(UiUUf_0c*$$&&>"F8po7F+jSY
+Erq<CZ28SDHbm8lEsB%kK6*-sXo*5HHiJb?F.DuGK`D$m"e>U6F8ppgEuoO\K6)gm]m%$'H[!0F
+K6+T>HZQa6H[!0:HZO7TN9PBbKYb4qEs$X"`IEG[JTJSIo;r)WPY-H~>
+ZMsp]r.G6nhMd]f[F0_.N;o`5XoF@"kELqVkCeNgP_=^Ss+H'Vf!UaMhR0$1cBt!ApVE]W]o]MU
+[=lB<N.d/3_1[dIS:nTUS:lRqP_=^Ss+J)[V2V8>s+H'Ves)E,hR3'1!fY7;re(o\d^>1Qd[Yuu
+kK]$VpT9+=s.'%Ps+EGrcA\:fXb<5E[>^X=etn&!f"%$Yg8Tb5g9$U]d[5]ef"%$Yg8Tb%db]qI
+n$Rh%pUuO!pOn3is.'%Pr.G*8s8IZlWReVE^"TH=^#H;][GJ<EWReVE^"TH=^"T9X^%_DW$C(RD
+KUi(MN1B(Np4NLPeuAP"!fY7;re(KPd^>1Qd[]r_!L3W`KE@\DSGe\UKE@7[_>AluZ/3$U_:k`=
+N;p;=Pir("K`@S?KE/.OrrB1rKEf-LZ';ZQ[Jkg\N6/p8KE]'CUnl_Xqh,9?s+H(*P_=^Ss87NM
+Xo&+uXnRJMZ.>oOKE@+S_>])lV:)c5_:"kNK`Bp/PR[*$KT,r=KTt["KS9Aqpk0]E`R:-Df#<H]
+c&db#c&eUTc&dUpc&dU\f%-(Mf&usa!3Q.u!3PsJ!gLgCqLep/ah`O]JV:ajo=Y4oS5+S~>
+r;T+^o^1bsf$DCP\?W$-S!/eaI<BF>?WU&q696nR,pkc=*"XFrs(X,B4$lP:=C>cZG(#('PaeGJ
+ZFRfmd+@1;meQ_Z!8IF""ioMTMX.RrI8u%!Sq=!BL;W2;MUUU6IK,=UI?+>UIFm#PMQYX8S(>`H
+P/d71T[g]8Y1p1/^;bkTKuUiTMZ8uo])RqAIK,=UI?+>U]'l5FRd:!%IFlr*MQYX8p3d!r`kMG#
+&u*j\Lq:luIBMJNMOO.6I?so%rK@2/3oA,<Re*D)P5hhBP2k)eIAG?!OLj&>IBM,#P/b_.IAG?!
+OLj&>IA53JL5P<&I=h4%L:Zu)I?so%rK@),!KR3ZI3#-4[#hlNUj]]+W/Rt6Y'm+p[#hlNUjp&.
+StN[dqgAg3s*]<Ys0@BBj2^kA!ijS@qgAO"`kMG##,9SPLq:luoR-b#s8IEJQN*EPP-998LWI4,
+I1iR5ZAuTLU4%q!Y'l>js*]=qQMc.2VYgAnWq^uH[bIa>Yh?2YI1(bK^3tEZ][i[If!tU*$',%6
+IK,=UI?+@*I/p/ArrB(nI0-FpUAK??KuUk+I0QFpZA?*;Qhu1Cf@u1GkJr".s/pd1j8XOUs-EG.
+*eD,NOI"D5J\K9`K>bokT%qDBID3j\IB(iHMMfm?r-\RBqu6Yrp3d"&`kM:t!enY.JUN)t^O6*6
+o<n_dRSA;~>
+r;T+^o^1bsf$DCP\?W$-S!/eaI<BF>?WU&q696nR,pkc=*"XFrs(X,B4$lP:=C>cZG(#('PaeGJ
+ZFRfmd+@1;meQ_Z!7q'h"hic>K^Z%kF&dSeP^B8,HbJU$Hd:JhF8po7F+jR7F4Sd=KW3P$Ph*s7
+LV`_qR*rNtUt2Jc\\WW6Hbm76HiK%G[Ju2,F8po7F+jR7[I9?,PjeWnF4SWiKW3P$p2^:^_7BPd
+&t$qFJ%<jdF/[s8H^*uhF,^-`rJ^bt3o7l'Pjb,`N;p#,N8DgHF.COXLq2*,F/[N[LV^rbF.COX
+Lq2*,F-t5/H\CjiF*%)XHaWThF,^-`rJ^Yq!JLLPEugdrXbaO=S9(shV1bu)W,nKSXbaO=S9)*d
+PaJlQqf<*ts)W7?s/gX,hS&W(!i4,3qf;gc_7BPd#+3Z:J%<jdoQ(%ds8I'@N;o.@N3@:(J&Stq
+EtY;"XbaO9QudWSV/q=Hs)W8]N;R_sSGW<dV>,*9Z.c%-XkK`QErp^)\c-XR[F1;,f!YBr$&&>"
+F8po7F+jSkEr_a-rrAniErr/_SGR@/Hbm8lEsA#VXFIe+OSa,!edmFmkIkq`s.sdihZ%Y<s,?_o
+*d><>LQKrtGIb\BGJ1tFPhO*+F1K8>F/770KS7Y-r,Vk.qu6Ymp2^:g_7BD`!dhboJTHB`^2rnJ
+!p>e?J,~>
+ZMsp]r.G33f)Pcid"GB+p]']aKS7YFs5&unK`@9iKTuLiKT*2$s6dFVKVdQ&pX7d3KW3u.m^\:0
+_9%XhN6/nhKZ=&d^#&dBK`@9iKTuLiKY@-[kH4c;KT+L^s6dFVp4NL+ahdt0&;[UVs5Kl.KT)/Y
+s7`pSKXL^Ws+CN>kPt:are)T"n,N.%V1aMXZ0MAOXb_Xh^%;-PS:lQOZ0MAOXb_XdZ.AsT`r:Vr
+V=4HQS:lR'qu?SI!L3W`KH5lRlMp"KLkLl'mf2R[N.d"llMp"KLkM#8p\4-Hqh,!7s8IZSXmc;a
+`q=ud_:G"NKE@+S_>])kLp?7Fihc7"!L3W`KE/FWs0%(WN6/p5KG00HlMp"KLkLGpp]'EYs+H'^
+s/kX@#*?Ods6@"Nre(?3ahdt0"dI1(pVi6kKF*nCKS9AiKS5Til@]5TesQ>f!fY7;re(H2Z0MAK
+V>>iXN7S%/cA[F0^%_QiXoF'-hZ'_QKH6T6qtJC'KX'srR&/g>g<K'%KX'srR#&#us8Ur?l%B,&
+ahdh,!fY7;JV8T-^4c*k!q2XSJ,~>
+r;T+^p$Lo!f?hUT\[&61S<T"eIWfXC?s-B#6p3F].3fiN(Dh)kpbslb4[_tB>%))`GCP@,Q(4YN
+ZF[lod+I7=meck\!8IF""G4tspW(X/<3Gimn#Cefa7oVkNdZ?UNdZ>9s*]<MXQTKFY_.@pf_P-[
+e@pF.htulNKmg\TKmeZp^3tFDqtIPVpO.JiNdZ>9s*]=,oDe!Rs*]<Me,0%,Y_2Xt!enY.rd>?-
+W9*j4U4%HDNoU02Z@./,qu?\E"HMOBo<S@D-)Tl*o>@;PI=\K_qr=Q'I>,3$q9kUXI=\K_qr=Q'
+I=J3AqtJ/1I0ZM8s6#i!IBrbMr-\U+s8IEeJZS&3j/.<SLUcaKl*,egJZS&3j/.<SO3%(ekF29r
+!KR3ZI0HM2s7=-[pO*-n^<i#>I0,,B^A`NaJ#MK)hkK^j!KR3ZI/pSMs0$hPKuUk(I1q17l1s;8
+IslaRp]'9Rs*]=Qs/,.2#)B_Uqrt>;rd=j%`kMG#"cpb!o>$:]I0kr6I=;-UI=7.Ul[8kb^<i#>
+I0,,B^A`NaJ#MK)hkKsq&r,$8pWJ/:ICAnMj/W--IGb(%pjF0Jd/!F[PC9V&dZL*Uq:<^S\p^aM
+dZK*^e,0$oMWoNjNlJg0I0,,B^4C]`ID:11K(HDPl^COu~>
+r;T+^p$Lo!f?hUT\[&61S<T"eIWfXC?s-B#6p3F].3fiN(Dh)kpbslb4[_tB>%))`GCP@,Q(4YN
+ZF[lod+I7=meck\!7q'h"FJGopV"pp<3>opn"k)H`qTMiKQD57KQD3fs)W7.Uuq^BXa>,VgACK]
+d^aFhhYZ`GHZQa6HZOPM\T;i*s7`qXpN(EUKQD3fs)W7hn,MRIs)W7.cN!q0XaBb_!dhborc8Wp
+UuqR.Qud=qK\latX`JQcqu?\;"GGY3n#cS1-(O/upUur8F*FGBqqduiF*k1[pWekAF*FGBqqdui
+F*FG*s7a5+EsJ6(s6#VfF05?>r,Vmls8I'[GGOBuhOo(6J$n_ElE,DSGGOBuhOo(6LW0#ZkEPjb
+!JLLPEs/#rs7a5"ErrnsL\l,oHbm8lEs6c`k53l"o5aqcs8I'>Xo&.%Erp^)\bgFOGGsg(hOORd
+$FTX.kGA3"F5HqeluNA\[I4([XaC%g!dhborc86u`V8u;KDT]rK`?+7s+GH7K`C=Y!kHR2qf;gc
+_7BPd"a?d)qq@G6Es-j@s7aP4Esf>Ls6$6YF*$4<SG7.GOOF%#b)CD?m`gNShYYmGlEt]3m`gN2
+UsB#?eqE:/!eeD#qJu^b_7>,<JTJPHo;r)WPY-H~>
+ZMsp]JV4'+SGn0BV>#OoJV;1!!fY7;JV9SI!fY7;JV8T-^4c*k!q2XSJ,~>
+r;T+_p?q,$f[7gX]!JH5SX#4jIs>sJ@Tuf,7mK*k/LVkf+!f\BYV%an5t=[M>[qMhH%:^3QCaqS
+[(F2tdFmIAn,3%^!8E'Q!N)1^I0$)2JUN)tb'a>F`kI"PSUCQpaM*4RJUP:]!.sgN!pc:LJ,~>
+r;T+_p?q,$f[7gX]!JH5SX#4jIs>sJ@Tuf,7mK*k/LVkf+!f\BYV%an5t=[M>[qMhH%:^3QCaqS
+[(F2tdFmIAn,3%^!7l^B!M#,JErhg"JTHB`b&[W2_7>,<ST=jZ_7>,<JTJPHo;r)WPY-H~>
+ZMsp]JV46In!o'$kK\X3JV;1!",t@DN.HYSKEI%0hS"JnJV:ajo=Y4oS5+S~>
+qu8tVn*&``d`TJ?[&p3tQ]R&UH?3n6?<9ur6rH3)/h8>+\c;:k1c[ch92\l!Ao2X:Jr,VWT;Sj"
+]Yr"Bg>V;crVHNogOXbW_rm22QKQ;>I=ZghI05,?`.NVhT7$fmUt`D1I=Zg]I/nlj[K>c`9n3~>
+qu8tVn*&``d`TJ?[&p3tQ]R&UH?3n6?<9ur6rH3)/h8>+\c;:k1c[ch92\l!Ao2X:Jr,VWT;Sj"
+]Yr"Bg>V;crVHNoeq%lH^#t>qN9A33F+JDTEs$d*_0^`ST5t*YSCXrrF+JDHF7ZL8kEJSh~>
+ZMsp]JV45\cM.A5cA[=-JV;-u"0Lk-Lk16DKE/.MrrBmPKEI1<[?,rmJV:ajo=Y4oS5+S~>
+qu8tWn`f&fe',eE[]cX'R?EJ]I<KOB@Tui.8XK(]Srp,As8$Uj3^,r':K:Y/BlJ9FKoD4aTr>3)
+^;\@HgZ.SirqcWpgOXbWK#dK_o>cH6I=ZggI06G4_L[8dl$WQ/qYpTn]#&jtKrV;4JUN)t^O6*6
+o<n_dRSA;~>
+qu8tWn`f&fe',eE[]cX'R?EJ]I<KOB@Tui.8XK(]Srp,As8$Uj3^,r':K:Y/BlJ9FKoD4aTr>3)
+^;\@HgZ.SirqcWpeq%lGF2mtSpVqc*JTJnR"/+eiGCai"Er_a,rrN#)_K,g+V5\rqF+JDHF7ZL8
+kEJSh~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qu7T2o'>Ame]u4M\?W'/S<]+iJ9c3PAm\\?:6k_V+5UNg4?u;+:K1M*Ao2U8JV]AQSYW<l\\Q83
+f%oHSp%eUfgOXd(I=ZftI=ZftI=Zg5I/nlj[K>c`9n3~>
+qu7T2o'>Ame]u4M\?W'/S<]+iJ9c3PAm\\?:6k_V+5UNg4?u;+:K1M*Ao2U8JV]AQSYW<l\\Q83
+f%oHSp%eUfeq%mnF+JC`F+JC`F+JCuF7ZL8kEJSh~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qu8qZo^1euf?hXV]<n];T9tauKRJ&`C1LXR<)6t^UT9l%5X.P%7nZWW=^P`UEHckbMisL$VQI5;
+_ogBZhrjG(q>UHLJUN)tJUN)tJUN)tJUNl5!.sgN!pc:LJ,~>
+qu8qZo^1euf?hXV]<n];T9tauKRJ&`C1LXR<)6t^UT9l%5X.P%7nZWW=^P`UEHckbMisL$VQI5;
+_ogBZhrjG(q>UHGJTHB`JTHB`JTHB`JTI,uo;r)WPY-H~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qu8q\p@%5(g=+6`]sb,DU77F.LOjepDeW]f=]J<n8k;HA7Rp!B:/P"p?Y!niFaJ^rO-Q61WN`kG
+`QZfbip#t2q>UHLJUN)tJUN)tJUN)tJUNl5!.sgN!pc:LJ,~>
+qu8q\p@%5(g=+6`]sb,DU77F.LOjepDeW]f=]J<n8k;HA7Rp!B:/P"p?Y!niFaJ^rO-Q61WN`kG
+`QZfbip#t2q>UHGJTHB`JTHB`JTHB`JTI,uo;r)WPY-H~>
+ZMsp]JV8T-JV8T-JV8T-JV9>Bo=Y4oS5+S~>
+qYqT3o'58je]u4N]!JK8T9te#Kn"AiDJ<Wg>?=d%;#O-/:f::q>[V,XDfg;UL5_=aTVeit]"uJ6
+f%oEQoD&=cgOXd(I=ZftI=ZftI=Zg5I/nlj[K>c`9n3~>
+qYqT3o'58je]u4N]!JK8T9te#Kn"AiDJ<Wg>?=d%;#O-/:f::q>[V,XDfg;UL5_=aTVeit]"uJ6
+f%oEQoD&=ceq%mnF+JC`F+JC`F+JCuF7ZL8kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+qYrbWo^1euf[7j[]sb/EUR[X3MM-J)FDko+@U<8A=&r=$<``F/?XdV_Dfg;TKo;([SYN3h\%]f(
+db3RAmeQYX!8E))JcC<$JcC<$JcC<$Qi@&;o<n_dRSA;~>
+qYrbWo^1euf[7j[]sb/EUR[X3MM-J)FDko+@U<8A=&r=$<``F/?XdV_Dfg;TKo;([SYN3h\%]f(
+db3RAmeQYX!7l`$JcC<$JcC<$JcC<$Qi@&,o;r)WPY-H~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+q>WVPnEJree]u4O]!ST;Tpq=.M1gA)F`D84An,4U?<piC?X[GVBl.j4H@LU*OHl</VlmD=_8ssQ
+guI\irV6BmgO]BUs+13$s+13$s+13:rr@ZB[K>c`9n3~>
+q>WVPnEJree]u4O]!ST;Tpq=.M1gA)F`D84An,4U?<piC?X[GVBl.j4H@LU*OHl</VlmD=_8ssQ
+guI\irV6Bmeq*jPs+13$s+13$s+13:rr@-3XTI[M8q6~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+q>VH3oBbVsf[@s]^::GKVP'BBO,AXAHZsOMD/*`rrFHp\BPMC'FEi1`Ko1qVR\6OZZFIZgbgP2&
+k3_p;rrCf)s+13$s+13$s+13$s-N`cK(HDPl^COu~>
+q>VH3oBbVsf[@s]^::GKVP'BBO,AXAHZsOMD/*`rrFHp\BPMC'FEi1`Ko1qVR\6OZZFIZgbgP2&
+k3_p;rrCW$s+13$s+13$s+13$s-N`cF7ZL8kEJSh~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+q#;<-nEJrfe^)@S]XG&EV4X3@O,JaEIX63[Ec>ppD&[A3EccMPIY*<4OHl9-V5pl1]u.t=f%oBO
+nG`1^!8E))JcC<$JcC<$JcC<$Qi@&;o<n_dRSA;~>
+q#;<-nEJrfe^)@S]XG&EV4X3@O,JaEIX63[Ec>ppD&[A3EccMPIY*<4OHl9-V5pl1]u.t=f%oBO
+nG`1^!7l`$JcC<$JcC<$JcC<$Qi@&,o;r)WPY-H~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+q#<DQoBk\ug!e3d_7R+YWhc8UQ'%#]Kn4]"H$=FSFEDYKGBnRbJq]&@Od;K0V5gc-]>;P5eCrmE
+meQSV!8E))JcC<$JcC<$JcC<$Qi@&;o<n_dRSA;~>
+q#<DQoBk\ug!e3d_7R+YWhc8UQ'%#]Kn4]"H$=FSFEDYKGBnRbJq]&@Od;K0V5gc-]>;P5eCrmE
+meQSV!7l`$JcC<$JcC<$JcC<$Qi@&,o;r)WPY-H~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+p]!8Jn`o2lf[7m^^q-nVWhlAYQ]mJhLkUJ4IsufnI!pHnJV/]6N/s0iS=ug[YdM*Y`lul`hW=(o
+rq??lgO]BUs+13$s+13$s+13:rr@ZB[K>c`9n3~>
+p]!8Jn`o2lf[7m^^q-nVWhlAYQ]mJhLkUJ4IsufnI!pHnJV/]6N/s0iS=ug[YdM*Y`lul`hW=(o
+rq??leq*jPs+13$s+13$s+13:rr@-3XTI[M8q6~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+p\u01p$_,(gt'iq`P9!lYcFXqSskt/O,]$QLP>_\s+M;FLl.1RPEqZ/U8P&r[CX/mbL+qtj6?%0
+p&>$HJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+p\u01p$_,(gt'iq`P9!lYcFXqSskt/O,]$QLP>_\s+M;FLl.1RPEqZ/U8P&r[CX/mbL+qtj6?%0
+p&>$CJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]`r?=TKA,aCs8RT:JcC<$LAqA)R)/a=rrVo'^[qI+mXP-6!UbI(rrM,RqgS[Km(`LK"+cc_
+oDS[jc$uhmrrqhhLOYE%rr;kF!1<N\!5JG]"H1IaW5JT6!n4*sq#C5@#ds^4J+!@:J+!46qgSX)
+bP;)FrRdcsK:LHggn;FZrr3E(Mm<<Z[>TNiZ1n:;qL8P"s8.9LMp).8LWBAn"4<:@pA"XorRdcs
+K:K4@s8VtG"IT5hJ+!46qgSU5rr3;ubF!p;W8R^8UAKE@XR+43!qs+<PQ(^X\%gu'!/0sW!q2XS
+J,~>
+pAZ$,oBk`"gXXZn`PB'nZ)jn"TUhO<P`h,gNW"eQNK0*`Pa@i0Tr"]iZ*q9[`QQWZgu7G`p[nIc
+gW'7!\qAZ&J,fOum=G:gs+^OUe!IlJ_uBf3[_MG6!UYC6rrMM:m/I+GU\fNBXmEh$Ifk:hcL_#7
+!mZ:ur;QrhWeZ(b_Z'T4IfPi0rrBh3Ig(bRjJg#qrr3&KW71PAqgSmYs8RT9s8RT9qu?PC!K5.r
+rsSbVTS8&hde_al^A@j/%/Z$is7s*]Iu1E&s2Onb!S[SNIg(bRs1aB2rVluIOgauYrsAVTTS8&h
+YkA%rqgSa8s8RT9qu?PC!13]b$2;Z2K86Gas5KgNIfZ\<c2Rk=[_J%+!qs(;j8T+2o<n_dRSA;~>
+pAZ$,oBk`"gXXZn`PB'nZ)jn"TUhO<P`h,gNW"eQNK0*`Pa@i0Tr"]iZ*q9[`QQWZgu7G`p[nIc
+f#I^q\V&W(J,fOumXbChs+^OUe!RuM_uBf3\%hP7!UbI7rrMP;m/I+GUAKEAXR*_#Ifk7fc1Co6
+!mQ4rr;QrgW/#ka_>aK3IfPl1rrBh3Ift\QjJ]uprrUZJe+it?IgEI^s*sJ:s*sJ6s8.9HMp(nq
+$iS_NKnGoFqqRjZqu6U(qhq`ZqmD?3LU$UR`VP&bgAh&""cLS(^PBl.rr^Z3\+]Us$2rMLKnGo#
+p](9jIfu/=s*sJ6s8.9GR/[*lp</hULT'/2ihH="!NbY4rrVo'^Q\[!p:%fsrr@-3XTI[M8q6~>
+ZMsp]r;QosZ%IhBd/OA3BA2K.s8N)Ug]%>m]Cs\Qs24j9%K4kHKqR6$s82PhK87#:rs\1cItO]o
+s8VhlK87#:rrBb2Ih8.*s8V#QKpL-bs81-.KqR6#rs[h]KpL-bs8CNRK87#:rrh>GJ!Aghrrq\\
+ItO]or;QfWJ,TBUi1u'mdJa+Bc^'9Xh#.0Zn?Kb.s7!XWM3Qlrrrh>GJ!Aghrri(pK87#3rrLBA
+r-naVpAY*l_uBZ>rRREkT\T,<!/LOQ"T,HVLUjSf"Sn'Y^]!!g!Jg+-rrVV,J+N[@juN>=!T!hC
+rt=7YF)*KjF*"5FIkb_[F)P0!R/R$eD[\Atrr3AtG?T'+@nOH7rr?R-Er_<rrrR[)C]8A_J]H\Z
+EU<`*rKL?tq#:?pA,UHSZ2ah(hZ*TUhY[<S!+TgDErgj4q#:`NIq3\C?usHDAmj-frt)jXWW/nt
+F*DP#PlJR@F(54LEs(.r!+YtK%=uS"IgCDls8VtX'Q<F7rsR;*A9Ds$;O%4]!+YtK"H`Z`!8dVQ
+!<?X.Etsf:s7s'9AoVNcKAPOTF)*KjF*"5Fh>[M2mdpG[mVdUMrrU*Mp@S@bLZ\X:_qP+kL[Od6
+!q'uVq#:E5]Cu"!#jS(4K;ePEs+L!W!q2XSJ,~>
+p&>m)o'GMsgXXZn`PB-qZ`gF-UnOBLR?s5)rKJ+`QC+)1StVsXX08k>]YVV2d+6t1k3Va3rrCgO
+rri5'K87%brs1_uf],$mrrCg.rrU*MpXB-Drkl\Rruq?kR>%<hs8VrgWe6):rVuo`TRh`qp&G'b
+We6):rVuo1rI5r[h#IE3V1t;`r;ZW>QA(sbrr<#UV1t;`r;Z`GY_._Brr3,]PC\qSrr3/fTRh`q
+p&+gjiICh+%H"":QI5X1qTkI]TA';CrsJ8"^]4?(]8DK0hZ!NXj-,%XhZ!NYor<Y"\Gc4&!R@V@
+Ig3@Ts8W)9`;]c?rRI<iT\T/=!W@lRrri5'K87%@rri+U<PA=drrIoDl2LhPD1D0W!TQ6<rrLjS
+m/I^VRr`@"3HK8=l[LX)F)u;)E1$V(")eZ+qu6U'o6FV]DdcASs8N(/rGqsup\t;E0l-c0$\67S
+AT6r7s88$\^\Ig0!+YtK#d44-!8IPR!8IDN!WZ_Grc8*j`q]QAdXGbMFCK=5g1OgBrr3PB(omV5
+=*&S*;j76uF)tgkrc81orr?R-Et*Z>s*kB(oDejfNtcHuq#:`MIV!YD@T/Kjrr?R-Es.L&rrCgN
+rrE+0rGr^5s8Vo'CM.U"=,#MhRr`@"3HK8=leVRAL[Xj7!psiSq#:E5]D)!u!W@l<rrW2;`7k4l
+L[Xj7!psiSq#:E5]D)("#j\.7K<"VEs+9jN!pc:LJ,~>
+p&>m)o'GMsgXXZn`PB-qZ`gF-UnOBLR?s5)rKJ+`QC+)1StVsXX08k>]YVV2d+6t1k3Va3rrCXJ
+rri5(K87"ars1Vtg?(EqrrCp1rrU*Mp<s!@_uBZFrRREkT\TSIqtI%ALUmEa%-jL8K;ePEs7`IE
+LUmEa!58>\&=hPUs59],QI5[2qp1R^T\TPH%,dq8QI5[2rRS6+LUmEa"QGYqPhuE>"mVb1K;ePB
+rrM,/rVm;aUkP,^rVuc@QA)!er;R,nZ+p>=n@OO6PhuE>"QGYqPhuE>"S\jILUm0Z!R7M>If[%P
+rr<#9rr30#es_;ch"(IFL].5Uqltd/\ZYr8q2SLjrS@JSL[OF,!q'uVoD\jR3W&gWh>lpB'&]4"
+CG@hjF/J;R0l(iODcgqFrVlt<$o.YYrsSFB>'"Ul9"k9)!+YtK!0HsT!e2q?rc8Hua5CKJm/R+a
+PZGQorrE+0rGr7Ls8N)Us8N)Uqu6]t@r)'b!J/;drsR;*A9Ds$F33-J@+>2U&A8dWs/8t>GAgBD
+s1rbt@fZLL"5<bTA,UHXJ]Ie?#^c.Bs8.llDsmE#$e'T9F`UqgPlLa`A,UHOOT5=\hY[<R!+YtK
+'p/Iqq6amJEG8I+hVaiDCG@hjF/J<[rrIoCoD\m[Dh%Q^!lMYDo`"oHk5YJ!gA_2/mdpG[mVdUM
+rrU*Mp@nRmlC`WZW;$>lF7ZL8kEJSh~>
+ZMsp]r;Qr*8onoCajL+o!7LoA\c;[0hV8&3K6-J2rri5]]iKdbs!$*D??'5,jT!Dj;Km1[`W,s^
+:31JOSH&VV;Km1[`W,sM3W<eBNnFBkOCiWCIG"SCF_#W(MrOcrOCiWCIG"SPI7eR!9$.,5DcV'c
+B)_f6G><4#:7V:_!qU=1rr3JfOCiWCIG"SCF_#W(MrOa9$i.%dJ,fPX@V9CYB)_f5DcV'cB)_f6
+Qr8-L;T8G2!Qgf0CC!lmL\CW-]iKdbrs%,(??'5,jS&TUpXZ,GrVm&+8onoCafk^Hn8WmTh#@B\
+hWb%AmVdUHrrMl)qu6]R!:9^urV,pCBmK=Aq>YqYiq)d.[8\IOrrhp:C';uarsPY\Z0Lc*>!`2g
+!7Li;!;H6f!e4qDrppNjqtlCS_uKc#D/JM3rrE,JrUU<ls8N)Us8N)Uqu6]tdc18t!VQ?bru[V7
+\aJn#>)E'_:lOuFo0upXs"TJppZ@h_p\XRRdK':<s8N*"df&bHp&"c=&nKDis5\G>DsmE#$^b82
+md@iW*;BI5df&b?p](6nhY[<R!7Li;'_hY-dVX'Mm,41)T`+WVib<]0oD.2A!=7QRrrVV,J,'$F
+K6-JTrr`#HU^65b"T.>p<eK-+!=7QRrrVV,J,'$FK6-JTrs3gDF)t*Hs8RcD]`RYm:4N~>
+p&?lJp@7J1i7c`.bJqE4\[A]FX/MkiTq@pIS=?%=SXuIIUSaujY-PLI^;@q7dFR(1k3MU;oD\gF
+r;Qr+8o\cAb0g4p!mgo>])Vd1gY;`0K6$D1rri5]]N0^bs!$*E?>s2-jT!Dj<HiL^_Z0R[:N^_S
+RfEDT<HiL^_Z0XK3<!\JNS"3iO(WTCIFnMBG%Pl,MW"NoO(WTCIFnMOIS+Tu9$726EE.9gC&S)1
+Gu&R(:R_7^!qU7/rr3JfO(WTCIFnMBG%Pl,MW"L6*;QfsJ,fPY@qTO\C&S)3EE.9gC&S)3QrS?O
+;Sr5/!Q^`/CC!lmL\CW-]N0^brs%,)?>s2-jS&TUpXZ&GrVm&,8o\cAb-1gImr*UOh#@B\h<Fq@
+m;7@ErrMf(qu6]O!:9^urV,pCBR04@q#5bViq)d/[8eRQrrhp9CC&;drsPV^ZK^i)>=AGi!7Cc:
+!;6*d!e4nCrppNiqYH4R_Z0YuCi8J3rrE,IrUU<js8N)Rs8N)Rqu6]tdGk/s!VH6`ru[S5\F8n$
+>`/<`:Q4oFo0lsZs"K>npZIndp&"@Pd/a1;"9&6"dJ`YGo_ST;'4oSks5S><D=.,u$^Y//n*e#Y
++SGa7dJ`Y>p&G$lg\_!O!7Cc:(%qV,d;F*Om,+((T`"QUib3W/oD&=@rrED]oD\mZD1D?\!eYO]
+p\t?ietNN9rri5]]N0^>rrED]oD\mZD1D?\!eYO]q#:[!Gu&R(:R_=`K(HDPl^COu~>
+p&?lJp@7J1i7c`.bJqE4\[A]FX/MkiTq@pIS=?%=SXuIIUSaujY-PLI^;@q7dFR(1k3MU;oD\gA
+r;Qr*8onoCajL+o!7LoA\c;[0hV8&3K6-J2rri5]]iKdbs!$*D??'5,jT!Dj;Km1[`W,s^:31JO
+SH&VV;Km1[`W,sM3W<eBNnFBkOCiWCIG"SCF_#W(MrOcrOCiWCIG"SPI7eR!9$.,5DcV'cB)_f6
+G><4#:7V:_!qU=1rr3JfOCiWCIG"SCF_#W(MrOa9$i.%dJ,fPX@V9CYB)_f5DcV'cB)_f6Qr8-L
+;T8G2!Qgf0CC!lmL\CW-]iKdbrs%,(??'5,jS&TUpXZ,GrVm&+8onoCafk^Hn8WmTh#@B\hWb%A
+mVdUHrrMl)qu6]R!:9^urV,pCBmK=Aq>YqYiq)d.[8\IOrrhp:C';uarsPY\Z0Lc*>!`2g!7Li;
+!;H6f!e4qDrppNjqtlCS_uKc#D/JM3rrE,JrUU<ls8N)Us8N)Uqu6]tdc18t!VQ?bru[V7\aJn#
+>)E'_:lOuFo0upXs"TJppZ@h_p\XRRdK':<s8N*"df&bHp&"c=&nKDis5\G>DsmE#$^b82md@iW
+*;BI5df&b?p](6nhY[<R!7Li;'_hY-dVX'Mm,41)T`+WVib<]0oD.2A!=7QRrrVV,J,'$FK6-JT
+rr`#HU^65b"T.>p<eK-+!=7QRrrVV,J,'$FK6-JTrs3gDF)t*Hs8R03XTI[M8q6~>
+ZMsp]r;Qp`GOFTs@ab8fO8sLYmXP9:!8dbQZ%mt1p\4\;kconsXQJ<Be,THgY3+rQLP;hl`C2ke
+m/?gdLP)Q"s8RSjMgr:ZLP*/$rrhi!D(0u6s!"%<ZKe)hYksA&T_%Gq>6!jrV"=#5-3*]_T_%Gq
+>6"UcOT+N"nGE6cBs[6FQHT/a@*.iCCTRQ9Bs[6FQHT<">'KDs>%7O'%))DS#kS)]%&EL_N$\H&
+!gGtNrr3J.Bs[6FQHT/a@*.iCCTRO8*6Dt=J,f=oAD5nZ#kS)f%))DS#kS)j+e\GlHWp4E%K#_]
+lJe%LbQ%(>D(0u6rs#&uZKe)hYkJ)!ieUJ4rVm$aGOFTs@^#e5mVdUPrsAYTS;!9Tqu<V&rr3_#
+_>jD;LP)Q"s8RT"R"(4Ks,-l$gA([_kconsXQK5c^]4?-\%h?LAu^QNchmM;$1<<Cs1sVCPdpeY
+rrVV,J,TBKIrFcSrrV=s"TJE(\IdUDJ,]HK23e(>"k%JlrrCpHrrR[gmed"i]iLHts1_[%rV6Bn
+!8dSP"T[EZrrCpQrrN2WmdpGsLK`%&s80F?qsK/?_>g/Sdf9=YV#12lpODr:rrLsVr;QcthYR6Z
+IlUo6s8T]R3H+?\rsOTcci*n@pODr;!8dSP!<D!RrrE,VqYpVcABFiN!pHAhrr3&fDh%T_$2rGF
+KpJ\3s/<@)rt_!<s80'VK;ePEs*rUeIur7]MZ@tTm.pZ!i223bVHeWNkconsW8dir76@I7s3d!Y
+MoG\q"6,,7!9sLdn?m*^J,90OrRRKmQI#HWY-n9/'pui;qltp/W;$>lJ(C!:OOjGi!-d/ls!?U#
+Ko)[3J,e`;LP;\ds2@DgW9i`QLP:Z*s8V?mV"=#5-3+!uo=Y4oS5+S~>
+o`$]Gp@.D0i7li1c,di=]XYATYH4b&Vkp2bUSFW\V5L8lXfo%<\\,_raj&8cgu7D]nbr%Y!8IGO
+"[75!k?DNGrt(4kFkH)2s8N)Rs80*WK<"\?s!m6<Lk`%ngTf9.s2_G,kd$#!Xl[Pl3iD<Bqm)!0
+WqZPnJ&mV#]#ok^\ENqqn?m*]J,]ILSm/PdTjY2'N$=qdl[)k9k74<Zmu/UnpEH:%l[)k9s$2Y0
+lg+':s/Th=m_Y=7qi"t*n$?f3s/Th=m_Y=7s.3G?mH7\bs76`5pV[F-s5slfoC%Vbrr3*!PX5BL
+s":?cZL5Srbkm?-amZQOXoJG#aD2rKs7q1Vg"jRRn,Mth]_B>On,N,+T_%Jr>PS4-q=<k;if\?*
+s7!F5."D6r#+f&*lChUkpAY6RM,=9OrrkT3mH7\bYQ"[kD1DH_$2rGFKpL*_s/<=(rtUm;s80*W
+K<"\Gs*rUfJWJ=\N<"+Rq#;)mZA=7;jn?-ts8Vf$^[5lMX+lnbqY:'sm=509_Ms&/[K,Rl!psiS
+rVlqKD=.?&!p45'rr3,2&DS[^rr3!WPl:Ucc?9$a!8I)E!e5(Squ6r8<gEX`^KR!&q#:?pg\UpR
+!8IPR!8IDN!W_!BoD]_a=jI!GqRaB9m=\TXs.Udes8NY)qu?]hJbB$B!S[VPrrE,SqYpnP3FSfb
+s1<D6D=.,u$\qm1rVu`eJbB$Cg\UpN!8IDN!<CmNrrSX#ao;;Gk+]Bas8VJ'J,0*NrRRKmQE']Z
+W3lR((72o<qm)!0WqZPnJ(C$=O4=2h!-Qr[q>V>jW.p/*>CZ\9Y_Rq2iW$ne3iD<Dd#W[7`;]c=
+iJCD3l2LnU[;@=AqYpm#esqG[d/2:p[/U(?Qbre"ZA4(4p](8CesV)MeGkL.FkHKh-/b_VM5=F+
+s6$VAKrEu1`^W"elfYL-Ko<nLs5slfoC%Vbs8R]B[K>c`9n3~>
+o`$]Gp@.D0i7li1c,di=]XYATYH4b&Vkp2bUSFW\V5L8lXfo%<\\,_raj&8cgu7D]nbr%Y!7q)J
+"[.(tk#u6Brt(7lGM;J7s8N)Us80'VK;eP=s!m6;LP;hlgp#9-s2V;)kconsXQIJj4/hNEqltp/
+W;$>lJ'!Uu\]KVZ\`j%rn?m*^J,]HlSm&GbTO+l"N$4kcl?c_7l3sK[mYiIlpE?4$l?c_7s#lJC
+l7qf*s/Ke>m_b@6qi"q)m^$]1s/Ke>m_b@6s.3D<mcI\^s76Z4pVdF0s6:#goBqP`rVlq`5lgoa%
+]X6Lm_b@6qi"q)m^$]1rr3t[CES-,q0ur/hSfcls76Z4pVdF0s7[\0oBL[+q#:g#o'5N"P]P%Jn
+?m*^J,]HPSm&GbTO+krrr_8:;?6[q"[.(tk#u5trrVV,J,B6PrRRKmQI#I.W3uX)'pui;qltp/W
+;$>lJ(C!:OOjGi!-d/lrtXb&LP;hlp:%g:s7Wq:mVc^;KpL'^q#:ZgJ,fPbMgpu%!9sLbmVdURr
+rR[gmf*4fk%OttrrfkDhBd[NrrG!ArVm&LF8u7?hX^[JIrFcPrs6;=QMpiu=I/p\rrE,VqYp^!h
+Z*TUhY[<S!8d/8ru-Yrci*n@]=[t.Kil1kTI&%drt)"'s8VhCp\t0nh>mKR!<D!QrsF69@&Eu(]
+6-,PmeHeiLK`%&s82P?p\t6MqYpQrhY[<R!8dSP!h*ZArr3&`U:L:'!q'uVq>Ud"esqG[W;$=j[
+Jp1AR)/h"Z%mt1p](8CesLrKf)LX.GM;EZru'alKo)[3J,e`;LP;\ds2@DgW9jQ4OFN2-rr3)[L
+f+6;rrhi!D(0u2rsAYTS;!9TqpV^Urr3_#_>jD;LP)Q"s8RT"R"(4Ks,-l$gA([oi223bVHeWNk
+consW8dir76@I7kconsMoG_rl3sK[mYiIls)[e6!p>e?J,~>
+ZMsp]rVm)n#ho=YYoM3l&<Hm9g>2i0rrCpUW*4Oh:7V+Z/Gl5JEH,0Vb@[";n9]*3Ug.nZ>,&i%
+4/hMpW*4Oh:7V@a!-a3%3Hp*^3V2M8?hDU?:4N<Dq0d8Ls4CqColU9's8U(Qs5n7os8TJ@s6B[R
+s8U(Qs8NpSIt+ECqtl"NR"^X6m.GLFp]'5iM>Mp1R"^X6m.l'LgAh2X*<5V[qu>(QoDdrkp](9$
+'`S+i]h5(#s8VtK>aU5,]Bo35GPD-sD2J;mhLg#MJ,f>T^&@0C%.jMjJ,B8o%.jMb!:Tsf`YA(F
+'?,7#qu?<5VG;X@s7q(_m/P^MNV<ASlEQiZrr32o#ho=YYoKtI!pjcRqu7khJSTI;Fj9r94obQI
+(q'CB>'k<cSH&ThGDCZC?N5o`GM;lm(Ajn4EH,0Vl>M1Ps6afTmVb%*F'<S.q#:ZW!<9l1Ap8;s
+!9sLbmVdURrs4*klMLJN]jN_srs<",s*#phs76BQr;Qofs8N)Qr;66g!e5(PrVHp"s6+<:kl$`L
+_tX03!8@DKrr3-%hZ*TUhY[<S!8?`:qZ-Tirs#i4@Z[qKo`"jod:@($0p)D7"_pJUTZ-3orrLsV
+r;QctgALgVrVq@RCk;0UP':ARmeHedZrge!Ze4RBrrE,Rr;6No!<D!RrrE,Rr;-Wso6YQJrVuok
+rr3&fDh%T_,L_3ZG@419s*m33s6:H/s/9+JF&&8*rr@7uInj>MMZ@tTm/$`*i.kKSF_!"PqkQtr
+F',%2`C2kekk@tIHYQ%Es8VAhS,hgR"SBs9:4N-?,1D*YG@5R<^Ks)'s6:H/s/9+JF&&8*rr@7u
+Inj>MMZ@tTq>Vf"LK\V=A1N0,UeYB?=J#E/76@I3UeYB?C.@stk&:"os0WR@s+L!W!q2XSJ,~>
+oD]U)p@.D1iS<&6ccX;G^V%+c['Hp=XfVK%'s+O?Yd1XF\\,_qa32fXf\PNKlgaoCrrCgPrs&'#
+f`1uU+O^9$NrX=TgAq9R!8IOR?$UKeSG<+8qkd_?EEf0[AsE8aHuIo>?ZC'iU;BA\VsDj4?$UKe
+SH&ThGDTTdGD0B`oBH9^oZa7-J,fQEI;nNPf4^6<FTCh/s2>iTj_a\js0NXClN$>Ps2>iTru,m*
+JZ@)oqh&+?L60(8olYHOs5IpSqh&+?L60(8q0d57s8T;Gs7:a;rQkuAs5e+js8TGCrr4je8Yc@d
+s8.FQR"g^8mIbUFpAa,iMuWh4JTaq@s7s4=r8u?7n,N!/qu+kMn,M\RmJm4*)"dhA`H\N]s7FR5
+9n33Cq0d5Js4:qFpAY6ZZC1dmrs&'#f`1uU+KteHlth1Ks!#sFCNa-/c2W8WrVu1#[f<@5H#lcO
+s8N(CM189+s,@#$f_PO_qkd_?EEf1%D1DTcm;7@?D)QHW>&_a]rs@E[s2%QGGB6gcl2LhPD1DNa
+#_-XRq>'Wp@Q=Ae$!g=+G:NFgnHRtNrrrAirVllLrV6Hjp\t;ECZtcn$Ms`$kA>)!rKLR*p\t6o
+fDYOErriDWs8N)Rqu6]tfBE50!W)cirs#i3A!"%Kp&=spcspq$162A6"_gGUU;ZBqrrLjSr;Qct
+fDYLSqYgGD?>Y;cr/l56D=.,u#..HAOL*R)rr3!!fDYLJqu?Zrg\_!O!8%2F"oJ>iHZS]Urs8Vt
+pAY*lm;7@Ks!-$GCNa,^SH"(&rVu1#[f<@5H#lcOs8N(CM189+s,@#$f^&D6+lJ/]E-5_BJ,?$9
+@W>J?qSkucVs!eO8pP,>p&G'VZC1dXrrhu=VG2R:s!#sFCNa-/c+dULrVu1#[f<@5H#lcOs8N(C
+M189+s,@#$f_POoi.tWWF_*(QqkQqqEEA_-`^W"ekG1g]EG7l7s5e+js8TGCs8R]B[K>c`9n3~>
+oD]U)p@.D1iS<&6ccX;G^V%+c['Hp=XfVK%'s+O?Yd1XF\\,_qa32fXf\PNKlgaoCrrCXKrs&'#
+gAh2X*7FiuO8sLYh>mTU!8daS>'k<cSG<+8qkRJ:EE]*[AsE8`HZ.i<>]FaeU;98[W9i!3>'k<c
+SH&ThGDB?^GCs3^oBH9^oZa7.J,fQEI<"WRfOg-9FTCn1s2GcQk&:"os0WR@lN$DRs2GcQrto[(
+J#L]jqh&.@Koiq5olYKQs5ImPqh&.@Koiq5q0d8:s8T>Ds7:a;s3_>Is5n7os8TJ@rr4jh8u)Ie
+s8.FRR"^X6m.GLFp]'5iM?!V4K6L4Cs7s4=rTMZ<oDeE3qu>(QoDe+Vn,NF-'_MD=`HeZas7FR5
+:4N<Dq0d8Ls4CqCpAY6[Z((gnrs&'#gAh2X*3]ADltq7Ls!#pCCNj0/c2W8Vs8V@$[K!1/HZMrP
+s8N(CLOW'*s,-l$gA1aaqkRJ:EE]+%Dh%femVdUCD`;`Y>&hg^rs@N^s1qHBGB6dbl2LhQDh%`c
+#_-^Vqtp$!?o@r`$!pC,G:EFho*"(NrrhcirrCdNqtL*lIr4KLq[*6$k\Y2#rKLL'p\t6ogAUpJ
+rriDZs8N)Uqu6]tg?SY6!<)]m#..KAOL*U3rr3/LA8JY.OT,7`C.3WF`TmC$!T!hSrrE,Rr;-p$
+s*n?kJb&c&G@GLYq#:Q*=CRAuf]rJ9!<CjOqu?Zs!8dVQ!<CjOqZQrjHZS]Ts8VflrrVV,J,0*h
+dt):Y?r!6lIm*i3l56r/W*4Oh:7V@a!-a3J:1!sY!-d/`qYq_sLK\V=A1N0,UeYB?=J#E/76@I3
+pJOV1C.@sts6?kZ!9sLdoZa7.J,90hdt):Y@!0`/?9S>gl56r/W*4Oh:7V@a!-a3J:1!sY!-d/m
+s!HZZ>&SOo.t@Gl:1A9HT)6Jq4/hA=:1A9Z7ecrFDtj;3[1rZ@F7ZL8kEJSh~>
+ZMsp]rVm)]!;lfrecaD#&-1Seh>mTU!8dT)T_%T9-2768/GF?fd-.L?mX90?b@Hq3G>urQWk&"V
+DsmRg/YM_'PU6)(!1<Z;!1<Z;!932A:$uqLs8VS.IJs32D1VM:(o6cgIfTNGmf3$p>'p;@(o6cg
+IfTNC*,C%B7<?fGF#S/_??afmKjMsj[6K03F#S/_??afdEII`as4.>Os!rRs@fQK*mf3$p>'p;L
+g.nI#!<<)iF#S/_??afmKjMsj[6K0@m$)e3Dh%`c"2APJ@f666Io9bUs77)'oBLf*p&>-XKnnsl
+rs\=6J,fQ<EIIfcl>;+ErrLsVrr32^!;lfrec`2V!n1P8r;Ru>P\/&,_-E#pdL>"4W%%?8/YM_'
+PU6)(!.XG:X9ek+!8dMN(\`,Qd-.L?l>M1Ps6afTmVbS.m($/Yqt^6uh>mRN?J>/1@K??+!7q$s
+!NPGZrrVV,J,TB^Il2:oHZ`"kSH&WS(p*b_!6P9(!;H<h!<?p6HN:2BrrR[-F8gLnPh,m5Qrq&c
+Dfb:>rrE+8rd+Wtrr3-%hZ*TUhY[<S!,HZTHNBA^q#:lm[!c_&BpR]Ws8/`c2+I$5rs%><DeE]u
+_>XB7h>mKR!<?p6HOZ4js*nsJF4',qNdG^4q#:`i[!c_&BktQbrr?j5HN^JNrrCpQrrE+8rHe^M
+s6"HMqtU0mmVdUOs!%E+B$'PYPU6(P%,V#_.J*EgT_%T9-27E>J+!?<#ljo)hY@*iVH05NlC]k]
+qlu78iad-$s*ntTqtFm6qoJj#rVloT!;c]qf)'psf(T+FmVdUPs!%E+B$'PY>`Rl`%,V#_.J*Eg
+T_%T9-27E>J+!?<#ljo)hY@*tVH05NlC]k]qlu78iad-$s*ntTqlu78ilM2_s826apUsaWs8RcD
+]`RYm:4N~>
+o)BI(p@7M4iniA=dEThR_na!u\[T#T[/I<F['d?O\\#Sl_oKpFdam./j6,e"rUBgeg\q-VirJoT
+s3h2"rt#1bs4[PRrrCgN0VIt)PU-#!s"*ni<mKm.\F+`ckf[P&oQaK_kGl&hIr4TOPq\m$n!#*l
+rrAG`g&RH9g&U*ps%VltJ,fQ=EI@]al"ktIKc$]Yl[K!9qsFFX]NKU]o,+@rl[K!9oc@suECb6!
+o5cj4G$fI@q1W2"n$PE2o5cj4G$fI@nSrsPs8UOPrr4PJI8aSQs823`pUjXUs8UeJU>#\Js7::j
+FEV#8dJ8K'bjVr)JH+u#GeS$Err30$]kC>QrVlg*rI%UQrVuI+VXs,'!qlQqkCn]UrVm;nD1DTc
+nSrsSs64?Oo`"sH!<3!&irJoTs3h1Vrr`8L@Z:6b,5md?aRI#NNVCj4gAe*"oD:57naD\fp\t5C
+n,9<ns8N)Rq#;0)Gui5RWjq;1J,fQ9D1Cqi7_S3!<fd(Prs@E[s&!.WpYKB[r;QcJqgSXHl1b2Z
+m;7@OrtU#?EHuhN94FFks6CN's2kJcs5O+Rq>UHqC&N;WY4qqtIl)0EGm]bds8A<f^$'BTlhCD[
+!,;FX!.k.L"T[<WrrCgNrrN17EW14aPLfO/&+-cQCM7FKi;`iRVaiX6mJd+igl6/bB5>B_rrLjS
+r;QctC&N;dPLfb`D2iS`j`ul5D=.,u$gk?MCM7Et_Z0W9C&N;[Y5eM%g\_!O!,;CW"g7mcEI7TX
+rrVS)J,90hrKV';nA1>7pX0W,s/7@;q_4]5n!#*lrr@Q;rN$;)rrCgKru7n=SET720n9&(OOrB"
+EUj'YD=.2mCUX&Y!9=%X!S[VNrrCXIIfS!lrrVS)J,B6irKV';nA/@hjDbabs/7@;q_4]5n!#*l
+rr@Q;rN$;)rrCgKs!F[HSET720n9&(OOrB"EUj'YD=.2(OOrC0!9=+VmJlpn=aU2KK(HDPl^COu~>
+o)BI(p@7M4iniA=dEThR_na!u\[T#T[/I<F['d?O\\#Sl_oKpFdam./j6,e"rUBgef)>UQiW/lU
+s4.>#rt#1es5!bUrrCpQ/YM_'PU6)"s"*ng<7'j/\aFlekf[M&oljB^kc22jIrFcRPV&R"mZ]$l
+rrAG`g&RN;g&U-qs%Vp"J,fQ<EIIfcl>;+JKc$WWl@/g6qsOLY]iod_o,+:pl@/g6pDdsuDae`n
+noHa2F^B:>q1W.um^59/noHa2F^B:>n8WmRs8UXQrVnBt;I]\+qsOLY]iod_s4U5Dh>mTUnoHa2
+F^B:>q1W.um^59/s6Ptq_/Fi%rr^#M;I]S($\)&`s8V[-V"<l$!;6?ok_4fWrVm;oDh%fen8WmT
+s6=HPo`"sK!<3!&iW/lUs4.=VrrUYWMu<T!rKLp9nA/@ipX0K,s/7C<q^nK4mZ]$lrr@Q:s/ZM+
+rrCpNrtkER<7'j/\a"*_s8VM*J*q5E^$N:1OSekR$/P[^:0uZKhI6K_rrCXIIfZS7p\t<_Dh%`c
+'n8)^H[Bm/@\!Jul56W&c2budk5b8PrrE+8rHeOHp\t;E208bD$C'-ArKp^#k\kP/p\t6oC]8Y\
+KDtlS!8dbU!8dVQ!W["Wrd+[1f(f7Um^.CXB5*[is8Vtp82Wm)rr32ZMf36@CVfuL!T!hSrrE+8
+rHf!<f)L5<O)r_2H&d5imeHeim^.CXB5).ts8N(7rHe[Ls8N)Uqu6ZsC]/S`XoIR*Hi*U<!q'uV
+qYqc<P\/&,_3?8?dL>"4W%%?8/YM_'PU6)(!.XG:X9ek+!8dMN)l?Z+kj"fqJ,?L4f]$F_o)F2X
+mec`o[JS&Gk5G;\h>mEP!7q$s!7plD!q'uVqu7l=P\/&,_-E#]D[bM&W%%?8/YM_'PU6)(!.XG:
+X9ek+!8dMN-Djh6kj"fqJ,?L4f]$F_o)F2Xmea8Nf](!Qk5Y>Hs7a31HiO+eo;r)WPY-H~>
+ZMsp]rVm)a!;lfrecaD#&-1Seh>mTU!8cu@GCP*\!93hS/GlG_I?1r(s.j2?Sn,h;Wb[$D\a'3E
+Dsm7?!-`pBDZJes!8@JQ!8@JQ!8co='^fmhs8VY2IJs32D1V`)LJDo7?3pQ129CJlKBE46LJDo7
+?3pT*R*u$&Io_m)EDX^D]3La'_eNS%C,:M3EDX^D]3L`oF+*rcs4.>Orr[aK>5S=!--:d\KBE4*
+@WV:t!;lfcEDX^D]3La'_eNS%C,:M<Wb]$+D12B^rrg)N;HitrrsO<S>5S@"LJDo7?3p6(!jQ[W
+r;R2nDh%fenoK6Xs6=HPo`"sK!<3!&joG;Ys4.=Wrr_hT>eU(8,4p">H[g5uET6jQOT.n)s69T.
+It)A:ir9#'s8UpUs8N)Uq#;0-Wb[$D\a&U$J,fQ:Dh%1nFnG_+F`m!Frrh0YrsZU?rrKq9r;QcJ
+qgSXHlM(;[mVdURrtU#BGCP*h=Bp@Us/5p9IsV06s76BQrVm&uR,\,GDuG.cZ1n8"IlDTNIgMLp
+s8U,CNkJhlpAY-nDuP4dL]7;W!8dbU!8dVQ!W[._rdOs9f_POXrT<>9fX$'(SGW?dk\1%%rr39$
+df8UOTO'tZrr3#U!;uit!,qgc%@GfJIrDr?VS.,]IrFcNrs\kgkk*N6IpPJ9rr@!9Ig!%VrrCpQ
+rrE+<rI5!Us7:SYnG`FnrQ2bBs8VM*J,90hoQ<6BIs5f2iqkTps%.kCl2Z$XIr>>HrrC=Ds5!bU
+rrCpNru6Z&hZ*W6@"847Wg8rCDsmXTDsmZ*_3C=O!8d\S!T!hQrrCXIIfS'nrrVV,J,B6ioQ<6B
+Is3hkm[,kns%.kCl2Z$XIr>>HrrC=Ds5!bUrrCpNru6Z&hZ*W6@"847Wg8rCDsmXTDsmY`Wg8s8
+!8d_T#K_U>KBE46K_)kYn!m.'~>
+nc':%q"!h9jP\hGeBuO`aMl'5^V.;W]+Vcj^VRh,aNMlVe_&[8jQZ((rpTjeg\q-VjT,,Vs4%>$
+rt#1bs4[PRrrCg>!d0!BDZJhns"+&KCjhARkl7Gj^RSlTqlFU^O14?QIr4TGFolf9Ir>>IrrC[N
+rrC[NrrCg:rtOj;J,fQ>Ed[fbl>;.Q_hV*3H!L^Ts#%rOF+NHQs+aHoH!L^UopO8,mt"T,n8M7G
+n%)_is2/Y_GAAsdn8M7Gn%)_inoB-Rs8UURrr3-"IoBSKrr4RmK6)V*s79fCo@F!<rU4]&aR?]E
+QiFs>@s;]DKDDTbZfPtMqu6Wp^1gMMqu6U(rI7aMqu?\O;0@.i#kn9#ri^1Or;R2mD1DTcnoB-U
+s6=HQo`"sH!<3!&jT,,Vs4%=Xrr_hT?G6::,5$+@H@L,tET?pUO8hh)s6B`/It)A:j8T,'s8UgR
+s8N)Rq#;0-XDE<G\*33rJ,fQ9D1CqiFS,V)F*-[Brrh'VrsldBrrKn8r;QcJqgSXHl1b2Zm;7@O
+rtU#AG(5!g=Bg4Rs/5p7IsD*8s6g*LrVm&sQf7rED>eqaZM4A#Il;KLIgVRqs8U,EO1eqkrqHEn
+!,_^b!/LRR"T[<WrrCgNrrN1;G5cslR+V67&,bPQo[gI":n@L`s6"%qY5\G,q9o<-`hHa+p\t0n
+gAq0O!<@!8Igqdts*nmqEi-Nm[sr8^q>Um$jll?g[!u@Kp\t51rI4sUs8N)Rqu6ZsD>eqfZN'B=
+Eq').#lMcVnGiOUD1DE^,5$+@H@L-W!9<r9O8hh)s6B`/It)A:j8T,'s8UgRs8N)Rq#;:fB&<Rf
+hdCs5hQ)s-8o<tqIr4TPrP4\bPQ9J:rrLjSqYpQHqgSUqpAY3]D1DH_,5$+@H@L,tEUT;TO8hh)
+s6B`/It)A:j8T,'s8UgRs8N)Rq#;:fB&<RfhdCs5hQ)s-8o<tqIr4TPhQ)s-PQ9J;rs-]!F+NHQ
+s+9jN!pc:LJ,~>
+nc':%q"!h9jP\hGeBuO`aMl'5^V.;W]+Vcj^VRh,aNMlVe_&[8jQZ((rpTjef)>UQjoG;Ys4.>#
+rt#1es5!bUrrCp@!-`pBDZJems"+&ICOM8SlMmYj^ReuTql4F[O1FQUIrFcIFT?W8Ir>>HrrCdQ
+rrCdQrrCp=rtOm>J,fQ>F++#el>;+P_hV!.G?tRSs#%oNF+`WTs+a?jG?tRTpR'D/mXJ9'n8V:F
+m^l_ks2/SZF_W^bn8V:Fm^l_knoK6Vs8UXQrVltL;Hitss!>d>F+`WTo3ue8g&V$Mn8V:Fm^l_k
+s2/SZF_W^bq5S5<k\YbHrr3,9Bi8.3rVm7T;Hitts+a?jG?tRJrrTHD^&7m=mVdUTs715ZrVu/"
+Jb8sCh>mQT#3Gp_s8UXQYl=grP$G]us!%)X4*uI$2f[jS23@i0KE(3:GCP*\!94"Yc2[h#!<<'!
+hY@*eql4F[O1FQDDh%femVdUCDft^PoQ><Aq>UTS!<3J@rr3#8!;uisf)'ptWp9?Y!q'uVrVmU^
+2g9b$HWXO&s8T"tDh!*6Du]D3ir/l\qj?CC!,qgc!3u:u!e3.QrdP6Af`1ul>)p:(T(`0b!,qjd
+!/LRR"T[EZrrCpQrrN1=GQ*'mR+V67&,kYSo[pL":n7F_s6+.sZ2Xb/qpPN0`LpO(p\t0nh>mKR
+!<@':Igqdts*nt!F/HWn[sr>aq>Um%k32HiZ[Z:Jp\t53rI4sTs8N)Uqu6ZsDuG.hZ2aEBF7B2/
+#lVlYnGiOVDh%W`,4p">H[g6X!93l5OT.n)s69T.It)A:ir9#'s8UpUs8N)Uq#;:eAD[@di*_'7
+i2W*/8oO.tIrFcTs1sqePQ9S=rrLsVqYpQHqgSUspAY3^Dh%Za,4p">H[g5uEUK2OOT.n)s69T.
+It)A:ir9#'s8UpUs8N)Uq#;:eAD[@di*_'7i2W*/8oO.tIrFcTi2W*/PQ9S>rs-YuF+`WTs)[e6
+!p>e?J,~>
+ZMsp]rVm)r#i>U][2dTo&-1Seh>mTU!8cu@H[gNlBBo<m/H+G3Q@ESHqp/l*GC/cVhQrMtBW1fX
+Dsm7?!.03FHY;XD!8dbU!8dbU!8co=)t%Wos8VtGF70(^BT<&[hOK(RO=C50Z"AKnp\t0uhOK(R
+O=C4lc2R`Y`bC/&H[#/_jD0JLm_+X7NEh_DH[#/_jD0JHIrjKHs0WjHpS@ihdKK%=s060c[J0_$
+dKj?0CB/_#gj=8<s5[sLs6dR\KoK?%k\W1qF#?+RhTaIJkgBV&s7`>hs3_&=s8UrGIuBC;pAY6[
+H[kJ]rs\=6J,fQGIrk&Xg1ZK<rrLsVrr32s#i>U][2cFN"7hgg^&7mSoQ<<FIsl=8lMm)/hAFuH
+l2Z0\IsYhnrrCpUs5!bUrrCpNrtkXjZ^-)SW9S;Ns8V4nJ*q5to`+Q+FmAf&"Ps.Y%)MrC!Pnd#
+rrVV,J,TBUIrFcTs80uC'`\2)6N2<8;Bbf70pMY:"jRt=rrCpHrrR[gmeZqemWE,eABX]H!<D!Q
+rriDZs8N)Uqu6]thX:%9$2L<eo`+sVCNoOPrrRZMhZ!NVo2=lQrrUaOn,E=fh>mKR!<D!QrsF6o
+i-g$/H/a<lmeQkkq4aJQs8VB8!:TpfhYR6Q!8dVQ!<D!QrrSQsao;;Gk&Yh7s8VM*J,90hoQ<<F
+IslZVlMm)/hAFuHl2Z0\IsYhnrrCpUs5!bUrrCpNru6Z(i;`i8@"8'NCQ"ibDsmXTDsmMs<e$L8
+!8d\S!T!h>rrVV,J,B6ioQ<<FIsl=8oZ<=XhAFuHl2Z0\IsYhnrrCpUs5!bUrrCpNs!!//i;`i8
+@"8'NCQ"ibDsmXTDsmM"CQ"ja!8dbUZ"AKnp\t0mK_)kYn!m.'~>
+n,Fg4oC(u,inrMCe^Ddfb/hWB`5BL0_Sa:0`Q-'Bc-Ohgf\><DkNhU3mJd1@rVm)p$JYU\[NNut
+&-1JbgAq9R!8H`<H%1<jBC#Bn/H+G4Q@<JFqp9#,FaNQThR&StB;k]WD=-t;!-s'DHY;[E!8IPR
+!8IPR!8H]:)sqKls8VqFEp`n\CQJMahk#CYO=L;1Z>"`qp&=sshk#CYO=L:ncMmiZa(gA(H[,5`
+jD'DKn%Oj<Na7nEH[,5`jD'DFIra<Ds0a'Moq_Qdcj&n;s0??e[e9\#dL'E.B`NFsg3\);s5[pK
+s6m[_LQ5Z)k\`7pEATeMgs".EkKjG#s7N2ds3Lu;s8UuJJW5a@pAY6ZH@G8Zrs\:3J,fQFIrarV
+g1ucArrLjSrr32q$JYU\[NMgS"7qsk]_qdRoQ33CIsl=9li321hAk8Lkl?!YIsYhorrCgRs4[PR
+rrCgKrtkXj[$H/RW9J/Ks8V1mJ*h)po`+N)G3eu("PWqV%`&)D!Pe^"rrVS)J,TBUIr4TQs80uC
+'`\2*62l-5;'P]30TuD7"j@h8rrCgErrR[emJ?hdmWN8iABOWG!<CmNrriDWs8N)Rqu6]tg[4Y5
+$2C6ep&G'VC3K=MrrRZMg]%3SnPecQrrU[MmJd+dgAq0O!<CmNrsF6mhL9p.GMmsfmJ6bjpnFDR
+s8V?5!:Bddg\UpN!8IDN!<CmOrr`4c@EAHJ#j$)Nli7"PD1DE^,4ot>I"-QkBC#S^3o1k1s60N/
+It)fXli-t>s8UgRs8N)Rq#;:fBA`ahhdCs2Ve_3`<Gh.'Ir4TMpK)j2WW:fPrrLjSkPkVND1DH_
+,4ot>I"-QaWV+At3o1k1s60N/It)fXli-t>s8UgRs8N)Rq#;OmBA`ahhdCs2Ve_3`<Gh.'Ir4TM
+Ve_3`WW:fRs0??e[e9Y"!.sgN!pc:LJ,~>
+n,Fg4oC(u,inrMCe^Ddfb/hWB`5BL0_Sa:0`Q-'Bc-Ohgf\><DkNhU3mJd1;rVm)r#i>U][2dTo
+&-1Seh>mTU!8cu@H[gNlBBo<m/H+G3Q@ESHqp/l*GC/cVhQrMtBW1fXDsm7?!.03FHY;XD!8dbU
+!8dbU!8co=)t%Wos8VtGF70(^BT<&[hOK(RO=C50Z"AKnp\t0uhOK(RO=C4lc2R`Y`bC/&H[#/_
+jD0JLm_+X7NEh_DH[#/_jD0JHIrjKHs0WjHpS@ihdKK%=s060c[J0_$dKj?0CB/_#gj=8<s5[sL
+s6dR\KoK?%k\W1qF#?+RhTaIJkgBV&s7`>hs3_&=s8UrGIuBC;pAY6[H[kJ]rs\=6J,fQGIrk&X
+g1ZK<rrLsVrr32s#i>U][2cFN"7hgg^&7mSoQ<<FIsl=8lMm)/hAFuHl2Z0\IsYhnrrCpUs5!bU
+rrCpNrtkXjZ^-)SW9S;Ns8V4nJ*q5to`+Q+FmAf&"Ps.Y%)MrC!Pnd#rrVV,J,TBUIrFcTs80uC
+'`\2)6N2<8;Bbf70pMY:"jRt=rrCpHrrR[gmeZqemWE,eABX]H!<D!QrriDZs8N)Uqu6]thX:%9
+$2L<eo`+sVCNoOPrrRZMhZ!NVo2=lQrrUaOn,E=fh>mKR!<D!QrsF6oi-g$/H/a<lmeQkkq4aJQ
+s8VB8!:TpfhYR6Q!8dVQ!<D!QrrSQsao;;Gk&Yh7s8VM*J,90hoQ<<FIslZVlMm)/hAFuHl2Z0\
+IsYhnrrCpUs5!bUrrCpNru6Z(i;`i8@"8'NCQ"ibDsmXTDsmMs<e$L8!8d\S!T!h>rrVV,J,B6i
+oQ<<FIsl=8oZ<=XhAFuHl2Z0\IsYhnrrCpUs5!bUrrCpNs!!//i;`i8@"8'NCQ"ibDsmXTDsmM"
+CQ"ja!8dbUZ"AKnp\t0mF7ZL8kEJSh~>
+ZMsp]r;QpdK_t@M@aY2d!8db4!<<'!hYSb#oCJo5q#;oBYG1C7=F'`5I5t?*s80!om+,9aq1!8J
+rK8V.oCJo5s8N)Us8N)Us8N)UkPkVODh%cd';/gLpSq],s2BnupZ>Y+s6;=ghYug?s#Z.@pZ>Y+
+s3aZapZd69T`:Hn_sY!?T)Zd"ddEcC^&OO6_sY!?T)YHmK_t@M@fQ0SanNa_oDe)1J):1i!WV$U
+Iku!CJ&UE9B>a/H?Cq29SC6huC;'&<It)Z$5GI"tHf3c"%.jMn/]mb+%.jN!Mlla9>'ouC!l&9A
+qu6`cDh%cd#,#G?pSq],o`"sK!<)p$6%o.,@UcP@!nq7Er;Ru>P%`,3c'H3Gs5F`28cShf.B)k0
+W.Y-M!8dbUh>mTU!8@5J(]1D1m+,9aluQn)p9Zu4mVbS.m^lYeqt^6uh>mRN@bUS5B)ql0!7q$s
+!NPGZrrVV,J,TBKIrFcSrs%h,!<;$eZ2XV2c31u`TJ`h5o?pf"p\t6Ar:B[_!e4qDrUU$brr3+q
+9/1_]pAY-nhYR6U!8dbU!7Li;s8N-#dc15s!;ZHj$2]f`Y3>;m@#Y!^rrRZMhZ!N\pF1UKoBMtl
+p\t0nh>mKR!<CRGo*kHpIrFbH>#(+TIrFcNrs\dd<3GHQ`LnCKrrCLFoDegk!7Li;s8N*"der_:
+rsm@iE67J+Q:R>=s8VM*J,90hrK:j=o?F4ds8V'mDb:!/q^JK8o;I<ArrCpUs5!bUrrCdJru7h;
+T'5I61Oo.CBBJ,[D=%:PD=%#c!7(V\!8@DO!T!hQrrCXIIfS'nrrVV,J,B6irK:j=o?ET;s7#"^
+Db:!/q^JK8o;I<ArrCpUs5!bUrrCdJrue1@T'5I61Oo.CBBJ,[D=%:PD=%"@BBJ-g!8@J<0n8'Z
+lMpkaK_)kYn!m.'~>
+mf*msp$qG6jl51Qg"+[$d*Bn[bPfQpbKS5Vd*gFpg"bKEk3D@(qs==_g\h'T7"Y7+@qF'f%fkAa
+gAq9R!8I<!VXa8XL%t[!qQ?UZdo^njo6r`$VZ6LqU[-B2H2)l)lhlkpVXa8XL&_/Qg].9Rg].9R
+gZSS<m;7@PrtD)9^%SL;ZN%q(Y4^m^HiN=cJ_g=ks8P0?Y4^m^HiMPlb4k4O@\NgkBuKGJ?Ch,9
+S^HhuCq]k<BuKGJ?Ch+i@tOOJ@qG]3/B7G$%.F5\14e9\lN.%BrdQ_@!.W#JRq]h/[U,O)`gtNE
+TkqF1YCD%F2F!tlO*TU;_@5o5o.7oU_@5o5s,F2Sj^!6,rrTrGU\k&mm;7@Prs#0,^%SL;ZLn.t
+gAq3P"[mt<o4)@8rrUneMu<T!r/k[9o$3T=s8V$nED6E4q'r93o;[NErrCgRs4[PRrrC[GrtkO7
+U[-B2H0TB_kP)AIJ*h)C^@&O8Pl(:V$/5I[;.82QhIQ]brrCXIIfZS6p\t<^D1DNa!e5(Srr32h
+C]OLo%^>s.&'P0js.2-OkOHo'2YI(MdJWV1rrR[`ir/HKq>UBsU.d@hnFlk_!8IAM"T[<WrrCIF
+oDegl!7Bg)o)SU^rsAR`<Nt]T`*eK!rr3%L!8IMQ#ko`uhXg!)+SGa6!S[VPrrE,Ir::?ms*nnQ
+Sm"jIqL<ALq>Um#O&`FJm_kb@p&>$>r:Bsg!<COGoDegk!7C`9s8NSSC3%J`i0?iuqZ$T_D1DE^
+,5dR:bOWrYL&_23(3*%Js7n.Anaic7s8N)Rs8UgRs8N)Nq#;;3=e4dATe_,kGA$$p@;G3/Ir"BD
+m/kQ2_>r3drrLjSqYpQHqgSUqpAY3]D1DH_,5dR:bOWrF_Z0,a(3*%Js7n.Anaic7s8N)Rs8UgR
+s8N)Nq#;J8=e4dATe_,kGA$$p@;G3/Ir"BDGA$$p_>r3fkq[hGrp0Ua!.sgN!pc:LJ,~>
+mf*msp$qG6jl51Qg"+[$d*Bn[bPfQpbKS5Vd*gFpg"bKEk3D@(qs==_f)5OO6%o.,@Udab%fkJd
+h>mTU!8dT%W:TVZKD>Htqlca\el[4nnpNN!VZ6OsU?pH5H22r,m/<(rW:TVZKE(rOhZ*TUhZ*TU
+hWOn?mVdUSrtD&7^\=a;YlD\#XnUs]HiN@cJ):1is8P0=XnUs]HiMMhanP(M@%dOgB>a/H?Cq29
+SC6huC;'Y9B>a/H?Cq1i@YFXM@UfB3/]mb+%.jMa0n8'Zl2gqArdQ_B!.VuIRV0P+[pG[+`LPBE
+TPD1.Y((qF2a=%nP'c-D`=2A<pFXM]`=2A<s,4#Rk$!-*rrTrGV#1/nmVdUSrs#-*^\=a;Yk7qr
+h>mNS"[Rh=o3u14rrUndMu<T!rK:j=o?ET;s8V'mDb:!/q^JK8o;I<ArrCpUs5!bUrrCdJrtkR9
+U?pH5H0fTdkk;AHJ*q5E^$`L9Pl(:V$/P[^:1DrOhIcidrrCXIIfZS7p\t<_Dh%`c!e5.Vrr32h
+D#jUq%'fg/&'b<os.D6Nk4@#)2>@+Nder_2rrR[air/HKq>UBsU.[4dnFlk_!8dSP"T[EZrrCLG
+oDegl!7Km*o)SU^rsARa<3GHQ`F+Z%rr3%L!8d_T#kocthXg$*+nu!9!T!hSrrE,Jr::?ms*ntT
+Sm"mLqgWPPq>Um#OArCHm_thBp\t6Ar:Bsg!<CRHoDegk!7Lf:s8NSTC2h;]ig*-$qu?]aDh%W`
+,5m[<c1B2YKE(u2'Q6SCs8+7DoCJo5s8N)Us8UpUs8N)Qq#;;1=J"aAU,.;nGA$'r?u>91Ir4QH
+mf:Z5_#W3frrLsVqYpQHqgSUspAY3^Dh%Za,5m[<c1B2G_>j#a'Q6SCs8+7DoCJo5s8N)Us8UpU
+s8N)Qq#;J6=J"aAU,.;nGA$'r?u>91Ir4QHGA$'r_#W3hl7meFrp'O`!-@b6!p>e?J,~>
+ZMsp]r;Qr.;L`mcajL,!!8db4!<<'!hZ'6PGBZrHq#;oDVI"=`?E!i&VCPj#s8Ag$F)bNbrK'LC
+m*D>.GBZrHs8N)Us8N)Us8N)UkPkVODh%cd'&%tPHX_oos2BmkGB6sAs1&,>rG2H53f?aWF'@;t
+l<7M<F'=FUs42[/F(0^Qs2Ae`F_7*/s42[/F(0^Qs4W*'Is4Z0s8QP3G?Sqbs1&,>rG2?2!T!hU
+rsmV0@WQ"0f`/p,@Wc:Om/?qkmVdUTs0,gDBj,HSrrce7G?Sqarrn<UGB6sApAY2[@*/<G!q'uV
+rr32VK5#[AMraO1!T!hTrrof.Is4Z0YQ"[jD1DH_#1%^2G@Y^6rr3$k&@)67&tiEPG>aP&rrCpU
+s5!bUrul13q>V6/VI"=`?E![k:i1i53IgI82fj+HFj^!a$/P[^_+nTdG@LXNrrCXIIfZS7p\t<_
+Dh%`c!e5.Vrr32nErc6-*:Eh+&,S(ns7:G8CNEuX[K$7,A,LBKqu-?j!e2q?rGr4QrVuoF<[OR6
+rrE,VqYp^!hZ*TUA,UHOp\t5'C]/;T\,H.&#LRa!Df]N9bPhGBIfS@(rs#8kC3+H"R/R$ch>mKR
+!<?X-Et#PVIrFbu<^4"lIrFcMrsR4u>&SIo>+#?i!+YqJ"8i)uA,UHNp\t5'r,W5Bs7s'7?uKg]
+J(jo%!q'uVq>UZFI;!h8;NUnX!_Es.rr3Y)>'G0gOT5=\hZ*W4!<<'BCYJ.Oru9mO>&SV%0n9(h
+<-a6u8@SV\7\],@4_oh/+`I>Z!T!hQrrCXIIfS'nrrVV,J,90Lc[BJNA9#ZhrrPb'Z2Xb9TNZP`
+;NUqY!8dbUh>mTU+`#g-ru^0S>&SV%0n9(h<-a6u8@SV\7\]+8<-a7T+`ICk!+YtCs8N(Po=Y4o
+S5+S~>
+mJdasqt0CEl/q$ahV6`8f%&:!rR)5*eCE.&g"bHBj6#UnnG3(LrrCgOrroi.IsFf3dJj^Wg]-".
+s8N)Rs.WY?G?'e#s"+)F?ZL*mW;Q[m/6pd+r2*hAE*oRAO%,l0d%XZeG?'e*rrCgRrrCgRrrCg:
+rrVS)J,]H\g4O'dA;oUL`f3f=F'I;s[K'h9C]FDqNDOh?>M/uA>@D_u=GY`3eUM(M@Y!)1`c#C1
+B:8)ceUM(M@Y!)1g4N7PGtuN^rF8uS>AsK?[K'h9C]+25gAq6Q%b6&=F(0[Os2JtfF_@-.rVmi(
+D1DTbY[2!W>AsK?rF8uS>AsK?s,Bj!F'I;krr`7b?c`-E!psiSrr32VK4oXCN9'X2!S[VQrroi.
+IsFf3YQ"[jCk)?^#1.d3G@kp;rr3$l'!VB8&u&NQG?'e*rrCgRs4[PRruc+0q>V6.VI+@_?`<^j
+;/V)93.L=43-B@KFj^!a$/5I[_G+ZeG@LXNrrCXIIfZS6p\t<^D1DNa!e5(Srr32nEWH-**:Nn,
+&,S%ls7(;7D/iuU[/^.+A,LBKq>C'g!e2q?rGr4Pr;ZfE<[XX7rrE,SqYp^!g].9RA,UHOp&>#%
+C]/;T[f#t$#LI[!Df]N7b5M>AIfS7%rs#2kCNFQ"QMpgagAq0O!<?X-Et#MTIr4Sq<BmnkIr4TJ
+rsR1t>AnRp=dK*f!+YqJ"8VrsA,UHNp&>#%r,W5@s7is6@W,s\IbF`#!psiSq>UZGI;!h:<K[:\
+!_O*0rr3Y+=a,'iOoPF]g].<.!<<'ACY7tLru9mO>&SV%0n9%f<I'C$8[n_\7\]&<5&5q2,&dG[
+!S[VNrrCXIIfS!lrrVS)J,90Ld!]SOAol&mrrPe*Yl=Y8U02\a<K[=]!8IPRgAq9R+D]X*ru^0S
+>&SV%0n9%f<I'C$8[n_\7\]%5<I'CX,&dLi!+YtCs8N(No<n_dRSA;~>
+mJdasqt0CEl/q$ahV6`8f%&:!rR)5*eCE.&g"bHBj6#UnnG3(LrrCXJrrof.Is4Z0dJj^WhZ)F4
+s8N)Us.EP>G>aOts"+,G??:*mW;Zan.pCL'rMEnBEF,UBO@Gu2c_+HcG>aP&rrCpUrrCpUrrCp=
+rrVV,J,]H\g4O*d@Z0=I`J[K8F'@;t\H$.<C]FDqMb\J;>2'#A>$cDo>)D&7eph.M@Y*23`GB"+
+At&)deph.M@Y*23g4N:QG>?9[s'f/U>&XH@\H$.<C]+25h>mQT%b?,=F(0^Qs2Ae`F_7*/rVm5m
+Dh%feY[2$X>&XE?"CbPY>&XE?"cH-"F'@;krrSKoanu)>mVdUSrs%20BmX<IjRiHQh>mNS"gq6X
+G>?8`rrVP(J,B6Mc[BJNA9#ZhrrPb'Z2Xb9TNZP`;NUqY!8dbUh>mTU+`#g-rtbR1??:*mW;3#]
+D1d6sJ*q56F*1`1dJ3_Jh>mSl:1e]o@fZH,!7q$s!NPGZrrVV,J,TBKIrFcSrs&%8!<8E+mf*4s
+q_;^_o645NF(7hMs8N(/r,Vo9rV?HpIkba;EsK2Qs8UJI-DL25!<D!QrriDZs8N(/rGr,9rr?PE
+rGr"KrV?Hud<Ac4F(T^@rVlqK!8d\S#,Fk+F)tNPrVloT!;uit!+YqJ%(H1bDskeL5ILN@DsmE#
+$dj0%Df]MoR/d0dA,LBMqu6Y+rGr)8rr?R,EshgEq6agBDeiC'gA_*RmVdUNrs$etBQmubOT,7]
+8J&0+rtD&/GBZrHs8N)Us8UpUs8O6Xg?e\9)rQKTDg-%QJ,>[6H&#?i\,VOZU?M>7CPR]hDuK\:
+h>mEP!7q$s!7plD!q'uVqYpcGI;!h8EQA(Y!_Es.rr3V(>'G0gOT5=\hZ*W4!<<'BCYJUa+5hoX
+Dg-%QJ,>[6H&#?i\,VOZU?J%FH&%2!Du[?JA,U3Crr@-3XTI[M8q6~>
+ZMsp]r;QosZ%I\>d/OW+mf2^)s8RT:s7`UIK;A,5s"!65Knm#"s8To3L%bQHk,a8lZg.S:OK@gG
+pT0""V"=WdJ+!@:J+!@:J*uM"!qs+<rr3Q.es_5_h#IEJm[Scbc2[ggqg\YG"R_e0Mp;8$-/+T5
+LV;REs8CE6K:LTms7XEkKrjG:s8CE6K:LTms8CNRK7g`6rs.8>J!Asms3:Fjr;QfcJ,]HWrR7-d
+SCmf?p;N#FXQKH\$MLsDs8VGnLP_8Trr3,TOFNMSrr3,hS:?IAp&>*0Y3c&c!qs+<rr30#es_5_
+h"1OHmXP38"T,HVK=S/b!q'uVqu6ltd?oQNbPD/;!kj*Trr3W*XFl/$oDei?mf3=TJ,fPAJ(j\t
+($;TOLU6:Gihh?d\#R4:\#-0ZQI#I'rsA+Cs8TonJ!eZ6l2LhY\%hnA!l)5<rr30!]79jgSG`Bn
+XIT=jm\kbfOMUqrqL8PCrV?Hn^\`Kc^&A!2oX14Ep&>&BmeZqcJ+!@:qgSY@s8%3G^&@d,#Q<;J
+KnGoFqu-Nr^OP\Mrs&A.MgpMep\k*mmXP07qL8perP,i8n?JeMs1c&:q#:[!fV!qNS?_hgs8%3G
+qu?PC!VcWjIgQ#Ps7XX%JVU2^rVlrm\%hb=#5cf8K9W2'rr3&5J+N[>'DJS\K;A,=s*sJ:s6bC:
+s.Fkqm.pZ"i223d[A^k?hOoS"Z]`0)c]G6ps1O&?`Lqk^rrMP;kPkVW\%he>#5cf8K9XRTrr3&5
+J+N[>')/J[K;A,=s*sJ:s6bC:s.Fkqq#;>lVM0r9W5&AhTS98LP/71EOK@g*TS98^TS*9hqg\YG
+!/0sW!q2XSJ,~>
+li.IoqXa4DlK@9hiSWMIgY;\\s4[q:hV[;Pjll!snG*"IrrCgOrri5'Kn[+brssVHs6Y=9s*sG9
+pT0($VXsQ^/*<sfLpQ@Gs1qNdp](9UXbDS;l2T(kXm>lYXG);(oDei?mJm39mJm39mH=KNp9qa8
+rt,.ZRY@Bhs8Vi^SUldEs8U=?J,fNOn"##hbl7VgfTgrC]\NMdr6gpbSCd`>pVr8LXl]T_r6gpb
+SCd`>rRJ-+Kt@9`#MP5gQ/hoEbklnfrrMM:rr3H*d[,WWfDYaD`fGnWjo#,cp9qa9s6R.KMO!6$
+rrh&:J!K'nrrhe]JW7nIrr`89Y3Yub!qs(;rr30#eXD2ah"1OHm=5*7"T,EWKt=Ge!psiSqu6lt
+d?oTObk_8<!ka$Qrr3W*XG);(oDei?mJm4RJ,fPAJ_9bt($;WPLpQ@Gii%Qj\#R4:[\p3]QI,O(
+rsA(Bs8TlmJ!\T5l2LhY[_Me@!l)2;rr30!]79jfS,E9pXIK7imAP_gO21_os8%3Gq>C'g!5JD\
+#JC!7s7E[fg\(RIJ*m+4"+T_<s8.9Hp&Fl<!PJ@+rs/JRTS8&hde`qB!l'6PrVm)t[YoWlYk@tp
+!UYC7s8%3R]_oOQp@,;_jT!!'pA"Xor7@TqKUf:>s8VqF!VucmIf]6BqL8kJs8Vf8Q@amjhZ!NS
+!qs(;q>UZrd?oTOVXsfe!ka$Qrr3Z+XG);(oDei?mJm4RJ,fPAJ_9;aru0dlKo<@<^]3/`L8_JC
+_Z.rDXm?#$K8IUBL&M#Pm=4=!!qs(;qYpcsd?oTObk_8<!ka$Qrr3W*XG);(oDei?mJm4RJ,fPA
+J_9bt*8dWIMm]P!s5'E'W3hc*s3He/le\:hW5bQcs31@is8N(No<n_dRSA;~>
+li.IoqXa4DlK@9hiSWMIgY;\\s4[q:hV[;Pjll!snG*"IrrCXJrri5(K7g_]rssVIs6bC:s*sJ:
+pT0""V"=?\/*<peLU6:Gs1qNcpAb0TXG)G9lMo1lXR,iYXFl/$oDei?mf3<:mf3<:mcXTOp:%g9
+rt,.[RY.3es8Vf\S:?IAs8U@@J,fNOm[Scbc2R_hg6@)B^#&ehrR7-dSCmf?p;N#FXQKQ_rR7-d
+SCmf?rRS6+K=V!]#MP8hPiD`Cc23"grrMP;rr3H+e!PcXf_tjD`JoSQk5>5dp:%g:s6R.KM3R$!
+rrh&;J!Aslrrhb[IuDSErrU$>m/-eap:%g9rrrAPRY.3eoD\jZJ,TBMqltd+\ZYr6mVdUPrs&AJ
+R"LXHq>UBq]moYQrt>(-K7fuks8RT:s8VM:s8SaAgA([_k,a8lZg.SMVLsf9Wk\8:VQ,?9chmM;
+$1<<Cs1sVCR*pKKrrVo'^]"06^UNq9rrr;3J,cpHr;R))SH&WWW.TS]_>aK2If]HFq>UH0qgSja
+rVuoi[@H%FrrIW;qYpYImf3=aIf]<DqL8OZrV?HurRdcsK:LHgrVlr6J+!:8#5bfdItt<'rVlod
+J,K?CIgj$h^UNq+Z)$I\^UNq3rsAYVTS8#gZ1n:uqL8PCs8.9Hp]()>$2ac&p</bQLT'/0rrVo'
+^\Rm6qpCd`PbdpMrrTl`oD\b'pT0""V"=WdJ+!@:mXP9:TRY\^q>VAkVM0r9W5&AhTS98LP/71E
+OK@gK]n;*ZTS*4C!UbI#rrVo'^\[s7qpCd`Pfrn%rrTl`oD\b&pT0""V"=WdJ+!@:mXP9:TRY\j
+ruBsoKo<@;^]3/`Kr22>_>hiCXR+f:Kr2h^KE'3nJ,fNKF7ZL8kEJSh~>
+ZMsp]V>gYnUggfas+13Frr_b1H23$kJcC<$JcFF'!/0sW!q2XSJ,~>
+l2M.jqXj=Hm-<ftjlGJ!iX4`,jlbmomI0ZBroa:]gSXuRrqN@$[t4R1s.fSrn8N[KJcC<$JcC<$
+g&D&(o<n_dRSA;~>
+l2M.jqXj=Hm-<ftjlGJ!iX4`,jlbmomI0ZBroa:]etrBKq4qK/JcC<$U]1GcEI%A2s+13$s+14'
+rr@-3XTI[M8q6~>
+ZMsp][f6?]qL8Ns_>F68n>fTDk^ibbs.fSsq2eF\qqM,NgA6:"J\g^Q!USP:IfP,-rrLiTqgSWt
+_=@O+m&^&5!/'A4!UQobIfY,:ao;D.XS[JJJ\e/^!SXXPIfY,:Rf<BAqL8Ns_;,%jK_)kYn!m.'~>
+k5Q4qqXsFKmd9B,lK[WulK[^%mI0Q:q>KCS!8Fs^!8.-t!J82crrhei=+o^es+13Frri.Y:pp2T
+rrC^JIfY/<m/I+Pf_U'tKsUd[fW=t"!J82YrrMGeqL8L!jSo8HXS[JJK#5Y0!UHiaIfY/<V#LJJ
+XS[JJK#3uV!8.-t!J82Drr@ZB[K>c`9n3~>
+k5Q4qqXsFKmd9B,lK[WulK[^%mI0Q:q>KCS!7nUY!8@:!!J/)arrhhl<e]ags+13Frri.Z:pp2T
+rrCdLIfY,:m/I+QgA6:!K<tRYg8t1$!J/)WrrMJfqL8KtjSo8IXS[JJJ\fJ.!UQobIfY,:V#LJL
+XS[JJJ\dfT!8@:!!J/)Brr@-3XTI[M8q6~>
+ZMsp][f6?]qL8Ns_>F67n?J5,JcC<$U&P5FQFm%KrrCdLIfY,:m/I+QgA6:!K<tRYg8t1$!J/)W
+rrMJfqL8KtjSo8IXS[JJJ\fJ.!UQobIfY,:V#LJLXS[JJJ\dfT!8@:!!J/)Brr@`D]`RYm:4N~>
+j8T>_r;$-]o^_tN"nVE]q>:0MrrCf^rrC^JIfY/<qu6fgY`mN7JcC<$UAk>GQ+QqJrrC^JIfY/<
+m/I+Pf_U'tKsUd[fW=t"!J82YrrMGeqL8L!jSo8HXS[JJK#5Y0!UHiaIfY/<V#LJJXS[JJK#3uV
+!8.-t!J82Drr@ZB[K>c`9n3~>
+j8T>_r;$-]o^_tN"nVE]q>:0MrrCWYrrCdLIfY,:qu6cfZ'<^gs+13Drr^f;]DL@_!8@:!!J/)R
+rrMK?qL8KtZi:'[XS[JJJ\gmV!UQoaIfP,^rrMJfqgSWt_9)]Xm&^)6!J/(_rrLiTqgSWt_4(B(
+gA6:"J\g.A!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+h#IBQgA_0-JcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+h#IBQgA_0(JcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]JcC<$JcC<$JcC<$JcD):!/0sW!q2XSJ,~>
+ZMspZJcC<$JcC<$JcC<$JcD):!.sgN!pc:LJ,~>
+ZMspUJcC<$JcC<$JcC<$JcD):!-@b6!p>e?J,~>
+ZMsp]`r?=TKA,aCs8RT:JcC<$LAqA)R)/a=rrVo'^[qI+mXP-6!UbI(rrM,RqgS[Km(`LK"+cc_
+oDS[jc$uhmrrqhhLOYE%rr;kF!1<N\!5JG]"H1IaW5JT6!n4*sq#C5@#ds^4J+!@:J+!46qgSX)
+bP;)FrRdcsK:LHggn;FZrr3E(Mm<<Z[>TNiZ1n:;qL8P"s8.9LMp).8LWBAn"4<:@pA"XorRdcs
+K:K4@s8VtG"IT5hJ+!46qgSU5rr3;ubF!p;W8R^8UAKE@XR+43!qs+<PQ(^X\%gu'!/0sW!q2XS
+J,~>
+ZMspZ`r?=UK@oR@s8RT9JcC<$LAqA)Qb`O:rrVo&^[qI+m=5$5!UYC'rrM,SqgS[Lm(`LK"+llb
+oDS[jc@<"prrqkkLOYB%rr;kF!13H[!5JG]"cLRbWP\Z6rrUZJe+it?IgEF]s*sG9s*sG5s8.9H
+Mp(nq$iJVLKnPuEqV7aXqYpL'qi.o]q6l32M6Q[Q`qk/cgAh&""cLS(^PKu0rr^Z2[eBLr$2iDJ
+KnPu#p&G'hIfu,<s*sG5s8.9GQi@!kpWT"WLT053ihQC#!Nk_5rrVo&^Q\[!p9q`rrr@ZB[K>c`
+9n3~>
+ZMspU`r?=TKA,aCs8RT:JcC<$LAqA)R)/a=rrVo'^[qI+mXP-6!UbI(rrM,RqgS[Km(`LK"+cc_
+oDS[jc$uhmrrqhhLOYE%rr;kF!1<N\!5JG]"H1IaW5JT6!n4*sq#C5@#ds^4J+!@:J+!46qgSX)
+bP;)FrRdcsK:LHggn;FZrr3E(Mm<<Z[>TNiZ1n:;qL8P"s8.9LMp).8LWBAn"4<:@pA"XorRdcs
+K:K4@s8VtG"IT5hJ+!46qgSU5rr3;ubF!p;W8R^8UAKE@XR+43!qs+<PQ(^X\%gu'!-@b6!p>e?
+J,~>
+ZMsp]`r?<c#drLhs8N)UJcC<$LAq@S0n]A@rrVV,J+N[@h>mHQ!T!hCrrL).qZ$\$g40&$!sC3G
+kPbD^S,cajrrq7W&-*l,rr;iq!&=6J!.XnH";mNJ;MY5N!iT"qq#C3k#]'J?!8dbU!8dVQqZ$X6
+R/$[hqlrEq#W\mY\Nt`>rr3E$(h<U?CD[$_A+0GVq>^Q(s8)d"(mt>Q&<Qkj"/I5]meHegqlrEq
+#WZD`s8Vrr">TrV!8dVQqZ$UNrr3;mQn\jX;SiCP7f*/d>2%7$!q'uVPQ(^PDh$gI!/0sW!q2XS
+J,~>
+ZMspZ`r?<e#dW1bs8N)RJcC<$LAq@S0S0&;rrVS)J+N[@gAq-N!S[V@rrL,0qZ$\%g40&$!sUHN
+kPbD^ScE'orrq:[&-*i-rr;iq!&40I!.XnH"W3TK;hb2LrrT,rW;-Di!!m<=rrCgRrrCgNs8)cs
+(mk$t$i."n$jo%mot!J<p&=t"pDdcEo5,<E'Og>-Nqr_V[f?4)"W3U+IhInBrr]&BD=.,u$2Lel
+$jo%(li7"^!!G"UrrCgNs8)cr0`M(Yn!Z!;&6$IG`^fn+!F+:&rrVS)J!9m6m;7@5rr@ZB[K>c`
+9n3~>
+ZMspU`r?<c#drLhs8N)UJcC<$LAq@S0n]A@rrVV,J+N[@h>mHQ!T!hCrrL).qZ$\$g40&$!sC3G
+kPbD^S,cajrrq7W&-*l,rr;iq!&=6J!.XnH";mNJ;MY5N!iT"qq#C3k#]'J?!8dbU!8dVQqZ$X6
+R/$[hqlrEq#W\mY\Nt`>rr3E$(h<U?CD[$_A+0GVq>^Q(s8)d"(mt>Q&<Qkj"/I5]meHegqlrEq
+#WZD`s8Vrr">TrV!8dVQqZ$UNrr3;mQn\jX;SiCP7f*/d>2%7$!q'uVPQ(^PDh$gI!-@b6!p>e?
+J,~>
+ZMsp]r;Qoo@gEWed/O@O`rGLKs8N)Ug]%>1GOEoZs+gUR%K!7b$phH(s7bt[#S;(Vrs[IF!!lKk
+s8VOc#S;(Vrr@EE!"_0$s8To-$n\:Ps7`0<$phH'rsZ_9$n\:Ps8/p.#S;(Vrrg=j!%GV\rrpt?
+!!lKkr;Qf;!<)p/_+G+fV#12dTIgR<\c;]C4oPEa3P#1'4oG?cF8u:7@gEWerr3,q@gEWep\t8a
+:Ab(mDsmW)s+gUR"oGDZ$phGprr<W/rri(+#S;'[rr_k6Hi)Uu!>+,PrrVV,J+N[@mrSC+!T!hC
+rt>4tkLO-akNDI:Iq.'mkLtPS9)\bl65U"&rr3Ah&7a;JV%A"RrrC(;k5auFrrR[[f)Fh?lhC-t
+>2'#VqgVf#q#:?p`r5'+p](6nhZ*TUhY[<S!63Uhk5joCq#:`':5Ic`Lcq:*N'afKrt'hpn,HQX
+cL9%F3WJj:kJdN$kPtP_!65!#%I<cgIfO-Ds8Vh?"E3`'rsPo'Lu.!E695)G!65!#"RlBj!8dVQ
+!<C.<k7mCbs7:RtSD(e_7D8TekLO-akNDHlrrE\foD\m[Dh%Q^!f)!fo`"n&k5PMB@t385!>+,Z
+rrVV,J,'$FLNi1\rs71B!!lKks8RcD]`RYm:4N~>
+ZMspZr;Qoo@0dEed/O@S_uK%Fs8N)Rg]%>1GOO#\!r[n2rr4/=X>C>P])Vg'lW"3%EVoe9f0KNF
+<U9\blW"3%EVoe9H2R^c3kG@k^e5.iV"t&`TIpX<[f-7+^e5.iV"t&fXC2AGFoMCDa!_'=^Ae-9
+f0KNF<U9S_!Q+p9rt)t=%PFRQs7N$;$p_9"s1CJn!!G?os1CJm!!dZHs7]q-&9\!P"SZ=1&9[aI
+!M3*b!![<-s8W%QM>mMYqlDU_6Fudg!W*T0rri()#S;-]rr_e2H267q!>+/QrrVS)J+N[@lZN+)
+!S[V@rt>4tkLX3bkNDC6Iq.*nkM(\W8cAYk5o^=-rr3Ah'P5bNU(i%UrrC+<k5aiBrrR[[fDaq@
+l1O^n>M/uUq0cJuq#:?pa8P0,oDegjg].9Rg\_!P!6<^jk5ji?q#:`'9o.]aMEma0MaF`Krt'br
+n,HNVcgT1K4TG0=kJmT%k6(V]!6>'$%I*QcIfa?Is8Vh?"E!Q$rsPo&Lu7*I76LVM!6>'$"RH*f
+!8IDN!<C1=k8!=_s7:Y$SCt\^8A=uikLX3bkNDC6h>[Keht-jLm;7@JrrRt"n+H\]q\82m!o[R;
+g]%9cht-jLm;7@JrrRt"n+Zhff0KNF<U9\bK(HDPl^COu~>
+ZMspUr;Qoo@gEWed/O@O`rGLKs8N)Ug]%>1GOEoZs+gUR%K!7b$phH(s7bt[#S;(Vrs[IF!!lKk
+s8VOc#S;(Vrr@EE!"_0$s8To-$n\:Ps7`0<$phH'rsZ_9$n\:Ps8/p.#S;(Vrrg=j!%GV\rrpt?
+!!lKkr;Qf;!<)p/_+G+fV#12dTIgR<\c;]C4oPEa3P#1'4oG?cF8u:7@gEWerr3,q@gEWep\t8a
+:Ab(mDsmW)s+gUR"oGDZ$phGprr<W/rri(+#S;'[rr_k6Hi)Uu!>+,PrrVV,J+N[@mrSC+!T!hC
+rt>4tkLO-akNDI:Iq.'mkLtPS9)\bl65U"&rr3Ah&7a;JV%A"RrrC(;k5auFrrR[[f)Fh?lhC-t
+>2'#VqgVf#q#:?p`r5'+p](6nhZ*TUhY[<S!63Uhk5joCq#:`':5Ic`Lcq:*N'afKrt'hpn,HQX
+cL9%F3WJj:kJdN$kPtP_!65!#%I<cgIfO-Ds8Vh?"E3`'rsPo'Lu.!E695)G!65!#"RlBj!8dVQ
+!<C.<k7mCbs7:RtSD(e_7D8TekLO-akNDHlrrE\foD\m[Dh%Q^!f)!fo`"n&k5PMB@t385!>+,Z
+rrVV,J,'$FLNi1\rs71B!!lKks8R03XTI[M8q6~>
+ZMsp]r;Qq91#C2!PgTL3!8dYR!<D!2rrR[gma_=?pWe+3J,]Hl[8)M.G?W,gTL)Q>ehN-`rtnr&
+hF^E?s$BWHehN-`s&*q;egTPPs2A;shNV'Ks.DuShLf.Rs2A;shNV'Ks0YTVhTd:/s8Nphmu.hW
+rrj6CkMAg'rVlr^(]aR8)T?$8hNV'Ks.DuShLf.Rs/9D&f%/jTs/9D&rmhYLs8QjhhTd:/s8Qjh
+hTd:/q#:Bhk5Np;W*Z.spWe+3J,]HP[8)M.G?W,^rr__l8c\hi"`#jLc68FUrrVV,J(su(!8cu?
+!q'uVli."B!9sLbmVdURrrR[gmf*4fk%=\nrrhKb]`>26rrHV5rVm%t#ljo)hX^[JIrFcPrs5Du
+XT/=O>(?GErrE,VqYp^!hZ*TUhY[<S!8d/8rtL*(lMpnYGB`f<?>&F#k6Rpars73TrrVWhn,E=f
+h>mKR!<D!QrsF6%@_MgAdW[!UmeHeiK5^&Ts7bs^n,ECEqYpQrhY[<R!8dSP!jQ(5rr3&J<eLDO
+!q'uVg&D'QhXgaKmVdUMrrR[gme?_`n#]1^kPkYUIggh]rrE,VoD\m[Dh%Q^!e5.Vp\tL9>3Fa7
+9)npEo=Y4oS5+S~>
+ZMspZr;Qq;1u$>!QI5^5!8IGO!<Cm/rrR[emFD4>pWe+2J,]Hl[SVb0G?`5iU.&)Ff//Bbq]&o)
+hapE>s$]rNf//Bbs&F(<f.l7Ws2JDuh3(jJs.W5Zhh>FUs2JDuh3(jJs0b`\gWq".s8O'jmuA+Z
+s8*dAkMJj&rVlr^(]aR8)TH-:h3(jJs.W5Zhh>FUs/KS)f@T!Ss/KS)rmq_Is8QpmgWq".s8Qpm
+gWq".q#:Bdjo3j;W*c;!pWe+2J,]HP[SVb0G?`5`rr__m8HA_h"`6*NcQJOWrrVS)J(su(!8Hc<
+!psiSli."?!9sLbm;7@OrrR[emJd+ej_"_qrrhKb\cf&4rrHP6rVm%q%/^&)g[b@GIr4TMrs5K#
+XT/=M>Cl\HrrE,SqYp^!g].9Rg\_!P!8Ho4rtL*&l2UeVGB``8?"`@#k6Rsbrs7*QrrVKhli-nb
+gAq0O!<CmNrsF6$@D)X?cugUNmJ-\hK5KlQs7P[\li-t>qYpQrg\_!O!8IAM!jH%7rr38N=+gJO
+s6XZQg&D'Qg[kFHm;7@JrrR[emJ$V_n#f4^kPkYUIggh]rrE,SoD\mZD1D?\!e5(Sq#:Zt**qab
+8P/s^K(HDPl^COu~>
+ZMspUr;Qq91#C2!PgTL3!8dYR!<D!2rrR[gma_=?pWe+3J,]Hl[8)M.G?W,gTL)Q>ehN-`rtnr&
+hF^E?s$BWHehN-`s&*q;egTPPs2A;shNV'Ks.DuShLf.Rs2A;shNV'Ks0YTVhTd:/s8Nphmu.hW
+rrj6CkMAg'rVlr^(]aR8)T?$8hNV'Ks.DuShLf.Rs/9D&f%/jTs/9D&rmhYLs8QjhhTd:/s8Qjh
+hTd:/q#:Bhk5Np;W*Z.spWe+3J,]HP[8)M.G?W,^rr__l8c\hi"`#jLc68FUrrVV,J(su(!8cu?
+!q'uVli."B!9sLbmVdURrrR[gmf*4fk%=\nrrhKb]`>26rrHV5rVm%t#ljo)hX^[JIrFcPrs5Du
+XT/=O>(?GErrE,VqYp^!hZ*TUhY[<S!8d/8rtL*(lMpnYGB`f<?>&F#k6Rpars73TrrVWhn,E=f
+h>mKR!<D!QrsF6%@_MgAdW[!UmeHeiK5^&Ts7bs^n,ECEqYpQrhY[<R!8dSP!jQ(5rr3&J<eLDO
+!q'uVg&D'QhXgaKmVdUMrrR[gme?_`n#]1^kPkYUIggh]rrE,VoD\m[Dh%Q^!e5.Vp\tL9>3Fa7
+9)np4o;r)WPY-H~>
+ZMsp]r;Qp3^&S+s1"-(5+TN(]h>mTU!8dbM@h8oDn+Zi3dUNgs>0XTeW;lmZ?Hpo.&.DaeM[Tl#
+gACVS&-u2&s8N(`(]\WA&.!@@rrhVW?7g[+s!!51hZ(],R.ke)n,NF-.K@s!n,NF5!<;Kfn,NF-
+.KBDsXo&,NOE9F]o@DpqGB`f]icgXeOE9F]o@Dq$LM"7"s-,8<k5b8VrrD6^ec>1=s3:WCrrPN&
+!<3!2OE9F]o@DpqGB`f]icgXeP\\kJrrSF#f),IV&AA,DPVN4<&AA,DPVMh1$1<;!p]'NK?7g[+
+rs"6jhZ(],R.gO^emhk`rVm$4^&S+s0sCTYmVdUPrsAS)3=IL4p]"-,rr3]fK`CdV&-u2&s8N)$
+0`WB!rtk_I[J9b:dUNgs>0ZJRJ,fQ:Dh%1n:0%cTT_J6]$/P[^s+D3h.?jhsrrVV,J,TBKIrFcS
+rrV=u#lai,N$83n;Z?[s#gWAJ"Q'1Y!8d;H!e5.Vqu6oP>(?GLW)g"orrE,VqYp^!hZ*TUhY[<S
+!8d/8rr\0J[JTk$"ft:cs&qbgrrO$Yp\Fgih>mKR!<D!QrsF6N?BG3eUiT:LmeHeaMab&Nqu6Zs
+hYR6Q!8dVQ!<D!QrrRggk5G>[mf*4fmVdUNrsAS)3=IK;n,H:$rr3`gK`CdV&-u2&s8N)$0`WB!
+rtk_I[G(HV)8T&V'OFC]s3bBg$rY(EM[Tl#gAdum!#U[orr^h^=odac"/&[PJ,B6PqlMje/YMj:
+?>KQ?'etCApL=a?;XaYc!3IsU+g(b]!"cR5s!>KV$l!#?J,dr,&.DIUs,.9k@bT7?&.BD7s8UXM
+n,NF5!<<(Po=Y4oS5+S~>
+ZMspZr;Qp3^An5!1t)C8+92tYgAq9R!8IPJAIo,In+Zi3dUa%$>KjTeWrN*]@F!;4&e8-iN=H5&
+f_bDS&-u;)s8N(^*!CDM'F8^BrrhSV?S$^+s!*;3hZ(`0RJ1n*li7"&/H=0!li7"2"TRojli7"&
+/H>`$Y5A.s/rt#2s7=k&pNLcQs5A0es,V0Ys7=k&s+b7$s8SBAs5sCVs8)fVs3gu6s8UCJrr3)t
+6#?W$rtCH5iW&N$j7db?p&EupQ2d+deG]@G"-m`QrVZ[)&AJ2EQ8JXA&AJ2EQ8J76$13.pp&F9H
+?S$^+rs"6khZ(`0RJ-X_dq)Y^rVm$4^An5!1p?o\m;7@MrsAS*3XdX8p]"*)rr3]eLB%!Z&-u;)
+s8N)%1^"r$ru;"MZM=G7dUa%$>KlJOJ,fQ9D1Cqi9ihfUT(VmY$/5I[s+VKn.$=SprrVS)J,TBK
+Ir4TPrrVA#%0$80MBMpn;?$Rr%*SVL"oI3SrrCgErrR[emJHnge6.:us/K5)p\t6og\UpR!8IPR
+!8IDN!W_!BoD\oN7'ujgrroJpS,Zb[rr3$:EVK;/!S[VPrrE,SqYpnP:LTCcs/'p7D=.,u",fRS
+qtpBo!8IAM!<CmOrrE,SqYpVNCZYQq#lX/XrVuobD1DB]$2^kd$nbQKs&!M0rt[;Cs7^(9#Z^?n
+rrB2Y"<a`E)upPUf_POb_GLdW>tKPGcs[Io;8iKo%L?Lqs.UV9(lJ=m"4Lga!9jFcrLR(KJ,B6P
+qlVsg/u&*=?"s<<'ekCBpLOmA<U]tf!3S-]+KGG]!"cI2s!>NZ%MW2?J,dl(&.DFSs,@Ko@G&q8
+&.BD5s8UOJli7"2"TSLRo<n_dRSA;~>
+ZMspUr;Qp3^&S+s1"-(5+TN(]h>mTU!8dbM@h8oDn+Zi3dUNgs>0XTeW;lmZ?Hpo.&.DaeM[Tl#
+gACVS&-u2&s8N(`(]\WA&.!@@rrhVW?7g[+s!!51hZ(],R.ke)n,NF-.K@s!n,NF5!<;Kfn,NF-
+.KBDsXo&,NOE9F]o@DpqGB`f]icgXeOE9F]o@Dq$LM"7"s-,8<k5b8VrrD6^ec>1=s3:WCrrPN&
+!<3!2OE9F]o@DpqGB`f]icgXeP\\kJrrSF#f),IV&AA,DPVN4<&AA,DPVMh1$1<;!p]'NK?7g[+
+rs"6jhZ(],R.gO^emhk`rVm$4^&S+s0sCTYmVdUPrsAS)3=IL4p]"-,rr3]fK`CdV&-u2&s8N)$
+0`WB!rtk_I[J9b:dUNgs>0ZJRJ,fQ:Dh%1n:0%cTT_J6]$/P[^s+D3h.?jhsrrVV,J,TBKIrFcS
+rrV=u#lai,N$83n;Z?[s#gWAJ"Q'1Y!8d;H!e5.Vqu6oP>(?GLW)g"orrE,VqYp^!hZ*TUhY[<S
+!8d/8rr\0J[JTk$"ft:cs&qbgrrO$Yp\Fgih>mKR!<D!QrsF6N?BG3eUiT:LmeHeaMab&Nqu6Zs
+hYR6Q!8dVQ!<D!QrrRggk5G>[mf*4fmVdUNrsAS)3=IK;n,H:$rr3`gK`CdV&-u2&s8N)$0`WB!
+rtk_I[G(HV)8T&V'OFC]s3bBg$rY(EM[Tl#gAdum!#U[orr^h^=odac"/&[PJ,B6PqlMje/YMj:
+?>KQ?'etCApL=a?;XaYc!3IsU+g(b]!"cR5s!>KV$l!#?J,dr,&.DIUs,.9k@bT7?&.BD7s8UXM
+n,NF5!<<(?o;r)WPY-H~>
+ZMsp]rVm)b!;HNnc3Vht%fkJdh>mTU!8d`Z;Wln/9)/E;pNKZdelm:SCOc6@B7KMs<moQ&GP?T*
+mf0@l;Wln/9)nnk>5,E)>5,E)kNDj]mVdUTs7:;Yqu>eoKCa-an,NF-!<;fMrr4aD.KAQ2n,NF-
+!<<')0`V2OT_J2)7SX@DT_J&!GPD-s@t45s7SX@DT_J&!Hh[R?c3X@J"f3(9s7bCLrrJW=rr4j&
+;VhERs7^_,:(/_Ip[`HMp]'5_J,b-@(]Z"Xp]#jc(]XP6n,MPNp](9=#lj&fp](9=#k\,uS9*9[
+rs\=6J,fQ?F*mfak%fVArrLsVrr32c!;HNnc3UWR!pXQNqu7h@<h/068u2Kh&HDd]!9aAc;Wln/
+9)nnk6Jh`h&HDb1hY@*dpNKZdelm:[Dh%femVdUCD]t4rLI%a2rs@N^s+D5sn%BP<l2LhQDh%`c
+#_-XPp\3s;<b)./#r-f,V#^8ik5b8PrrE,Nr:fsc!e5"JrV$Wqs8.:Lf)'r'g@tUJ!7q,Crr3-%
+hZ*TUhY[<S!7p<2pAk*crs%=p&1(tolMgeepO>>A#i>R\"hb`Y6B'LnrrLsVr;Qctf)57Nqu;.a
+HZS?HIsZBXmeHedhJ*TJB<g%errE,Nr:g6k!<D!RrrE,Nr:^?okAu"Iq#:E`Dh%T_+fn_7ifm&-
+s/ck4s4.25s&r=`hF^E?rr>CBs*G=WrrCpNru8dLB%#7F%"J"q3ORRIGPD,eDsmAg!-@nJ!:Tmd
+!T!h?rrg#IQu@KOrunIESDoc*Ut/i`s8UXMkPn^`kMAg's8N'chZ%p6s8N)Uq#;DO:1hr*C(,Ud
+G<*(b??c/DIrFcLG<*(b]`@O$pYPoL"Ipq@s+L!W!q2XSJ,~>
+ZMspZrVm)b!;$6jb7)eu%fkAagAq9R!8INZ<TDt.8bi<:pN]oge6@.QBn-$?B79;q=jYZ&GP?T(
+mJj=p<TDt.8cSej?2(c-=nf?)kNDj]m;7@Qs7:;Wq>]PlL%B?cn,NF."TS5Nrr4aB/H=l5n,NF.
+"TSK-1]RYYUA+D+78FCGUA+8#GPD-tAV'T"78FCGUA+8#H1V(9b7+@L#5b87qu?EFrr3"f/H5Z,
+Gu<;rs8Vh;78FCGUA+8#GPD-tAV'l6*Z>)2UA+\?*Z>(_<U]tN!;$6jb7+F6!;$6jb7+%C!hFD^
+rVm;nD1DTco5f3Qs5e$Mo`"sH!<3!&k5b,Rs2thSrrVM%J,B6hY$%:RPY%\NXq^d5f)Y"6>ufqB
+8P/s^!(#N>I1ZGY!8I;K(AE)Wd*u9Dj_]MIs6XZQm;3u-gP8+mq#:ZT!<7cj[dUpM!9sLbm;7@O
+rs4*gj7Dm*P#l5ors:B-s.TYfs5O+Rq>UHqe,Ak<p\4[hIqdsBo*Y0fs8.@OeGF`&g@tUJ!7Uo<
+rr3-%g].9Rg\_!P!7U!-o)\O]q#:QRCD%t,Yj;;g"nd:-D$\nqrrotR#XsX&r;QfP!;uit!7Uo<%
+JBVuIr0IPkP9OQGAZaBrs%7o&gh7qfDbdN!7Uo<"S_rr!8IDN!<CUIo*+mgj)KGCq#:E_D1DB]+
+g+t<iKQo*s/m(5s4786s'8XbhapE>rr>@BqgB%UrrCgKru8gNB@>@J%Y+4s3jdIDFnPcaD=.)d!
+-RnE!:0U`!S[V<rrfuGQ>M-KrunOJSDf](Ut/rgqu>7JkPngfj53F"s8N'bhtqg5s8N)Rq#;DP:
+M8,,D%;'iG<3+^?$5i?Ir4TIG<3+^\cD'rpY5]I"I^nAs+9jN!pc:LJ,~>
+ZMspUrVm)b!;HNnc3Vht%fkJdh>mTU!8d`Z;Wln/9)/E;pNKZdelm:SCOc6@B7KMs<moQ&GP?T*
+mf0@l;Wln/9)nnk>5,E)>5,E)kNDj]mVdUTs7:;Yqu>eoKCa-an,NF-!<;fMrr4aD.KAQ2n,NF-
+!<<')0`V2OT_J2)7SX@DT_J&!GPD-s@t45s7SX@DT_J&!Hh[R?c3X@J"f3(9s7bCLrrJW=rr4j&
+;VhERs7^_,:(/_Ip[`HMp]'5_J,b-@(]Z"Xp]#jc(]XP6n,MPNp](9=#lj&fp](9=#k\,uS9*9[
+rs\=6J,fQ?F*mfak%fVArrLsVrr32c!;HNnc3UWR!pXQNqu7h@<h/068u2Kh&HDd]!9aAc;Wln/
+9)nnk6Jh`h&HDb1hY@*dpNKZdelm:[Dh%femVdUCD]t4rLI%a2rs@N^s+D5sn%BP<l2LhQDh%`c
+#_-XPp\3s;<b)./#r-f,V#^8ik5b8PrrE,Nr:fsc!e5"JrV$Wqs8.:Lf)'r'g@tUJ!7q,Crr3-%
+hZ*TUhY[<S!7p<2pAk*crs%=p&1(tolMgeepO>>A#i>R\"hb`Y6B'LnrrLsVr;Qctf)57Nqu;.a
+HZS?HIsZBXmeHedhJ*TJB<g%errE,Nr:g6k!<D!RrrE,Nr:^?okAu"Iq#:E`Dh%T_+fn_7ifm&-
+s/ck4s4.25s&r=`hF^E?rr>CBs*G=WrrCpNru8dLB%#7F%"J"q3ORRIGPD,eDsmAg!-@nJ!:Tmd
+!T!h?rrg#IQu@KOrunIESDoc*Ut/i`s8UXMkPn^`kMAg's8N'chZ%p6s8N)Uq#;DO:1hr*C(,Ud
+G<*(b??c/DIrFcLG<*(b]`@O$pYPoL"Ipq@s)[e6!p>e?J,~>
+ZMsp]rVloT!<3!!h>kt'&-1Seh>mTU!8dGMn,NFE!:Ta`"8@";cMm\Js,^mE[:663G>c`cq\T9^
+DsmLL!:Tsfh>m$E!7q2M!7q2M!8co='^fmhs8VM*J,fQ:Dh%eS0j<bk3<9$X0CO6)cN!o!>3FHs
+!<;LBV>oC47B#Wm.@AtR:9=J_7A/Lm*.RBp.@AtR:9<l%J,]HKh>mNSrr<&$r;SG=HPk'.s0X$E
+h>mTUmVaPAhN1L6s-Q6JhM3)#pQ01=mYaN4pQ01=mbTs%s5!bTrrh0Ys5!bTrrLsVp&>*ADk-b*%
+.8%`s8VM*J,fQ:Dh%EZ!T!hUrrLsVrr3#U!3cD(]iLNus!%>eGPD.*Dg1[E#eg7b;ZHIkn,NFE!
+:Tpf^&S,h!<<'!hY@*QpNKN\rqd8pDh%femVdUCDenY<l>(b@q>UTS!<3n4rr3#$!;uisXnr)!<
+n@$F!q'uVrVlkIqu@61Dq=sgec=S,pAg``k5b8Ps8)crA,$!'J,B9Q0sUcYYu[[O?AJ7Squ?^.r
+r3-%hZ*TUhY[?M!!+gZpAY<]Z"G4H_>aH:dS^'uqu6fMN'[MtrVloT!;ulo!"CZfs*ns_F1p"CT
+RUnJpAYB_Z"G3[K`D)L!!Hg3rrCpQs8)d"A,k_5Hi*U<!q'uVqYqc:H[#5ambRs4pB\J4HW'n<!
+:Tsfh>m$E!58F4h>mTU!8dMN)iJ%Ns8UYNJ,efrqs%s8mf.cTmf3=<p]&eEhYmHTh>mEP!3Q+u!
+3Q%r"kmaNl>M1Ms!%>eGPD.*Dg1f&#eg7b;ZHIkn,NFE!:Tpf^&S,h!<<'!hY@*iMdFj3s415#s
+6AbDl>(>+s*ntTs6AbDlIGslrVm)jHPk'.s+L!W!q2XSJ,~>
+ZMspZrVloU!<3!!gAoY$&-1JbgAq9R!8I5Nli7"B!:Ta`/GFEgbkq53s,UgDZt$95GuMraq>(&?
+D=.4K"RH*fhZ3-F!7UuJ!7UuJ!8H]:'^]aes8VP+J,fQ9D1DSP0O<kn2urpW0CO0'bQ%Sr?0Bg!
+!<;@AVYf758?2,s.[o7V9s"A]7\\dq*.REq.[o7V9s!f%J,]HKgAq6Q"8`&uWr2lMms,bns8TMQ
+o@j9Fs6jkURbs3$XT+VVU>L_GJ+\k>d-Zf`WqDEid-]^Q<WCqVrr3,U!<:pVrr3#R!;6?ncu#9M
+rs\:3J,fQ;Dh%fem;7@FrrLjSrr3#V!<3!!gAnJX"9#l7RJd(/qgE\]s6jlMn+R7%s*7KApB9g^
+s5*hFrrBe5s4[PRrrCgKrtkET;p>.7q<`$Ks8VJ'J*h)gli63`H1Uk3"PWqV*2``8!NH.trrB5!
+!!-*Lp\t<^D1DNa!.XnH%g6aus8U[Ng]-jJT)[gNp\Fjd!!$U)rr@QH!"(Kes8T<)VUf+.rV-?i
+!!!T0rriDWs8N)Rqu?Nn!A^tSrrqYkBd,p]rr3)I;#l4Frrgf270&)@rrLjSr;ZWo%5P6hIr1p"
+][CqsIr4THrs.emBd*P3s8Vrr"D.W5!8IDNqZ$e2s5S*GqtU0mm;7@Ls!%>gGP2")hZ3->%(cIa
+;?-@nli7"B!:Tpf^An5f!<<'!g\CdfNFC98s3t%urTWMBl"P#%s*nnQrVP4@s3gu&rVloQ!;c]q
+Y582!WqcStg22c2D1DK`,5Ze4p&FK!GOp@o])R%Qs7ZZ^s8UsVn,EC%s8UgRs8N)Rq#;:m@FG2U
+e5_"sl0%s.Bl38;Ir4TOl0%s.dfA/$rs%q;(sDsZK(HDPl^COu~>
+ZMspUrVloT!<3!!h>kt'&-1Seh>mTU!8dGMn,NFE!:Ta`"8@";cMm\Js,^mE[:663G>c`cq\T9^
+DsmLL!:Tsfh>m$E!7q2M!7q2M!8co='^fmhs8VM*J,fQ:Dh%eS0j<bk3<9$X0CO6)cN!o!>3FHs
+!<;LBV>oC47B#Wm.@AtR:9=J_7A/Lm*.RBp.@AtR:9<l%J,]HKh>mNSrr<&$r;SG=HPk'.s0X$E
+h>mTUmVaPAhN1L6s-Q6JhM3)#pQ01=mYaN4pQ01=mbTs%s5!bTrrh0Ys5!bTrrLsVp&>*ADk-b*%
+.8%`s8VM*J,fQ:Dh%EZ!T!hUrrLsVrr3#U!3cD(]iLNus!%>eGPD.*Dg1[E#eg7b;ZHIkn,NFE!
+:Tpf^&S,h!<<'!hY@*QpNKN\rqd8pDh%femVdUCDenY<l>(b@q>UTS!<3n4rr3#$!;uisXnr)!<
+n@$F!q'uVrVlkIqu@61Dq=sgec=S,pAg``k5b8Ps8)crA,$!'J,B9Q0sUcYYu[[O?AJ7Squ?^.r
+r3-%hZ*TUhY[?M!!+gZpAY<]Z"G4H_>aH:dS^'uqu6fMN'[MtrVloT!;ulo!"CZfs*ns_F1p"CT
+RUnJpAYB_Z"G3[K`D)L!!Hg3rrCpQs8)d"A,k_5Hi*U<!q'uVqYqc:H[#5ambRs4pB\J4HW'n<!
+:Tsfh>m$E!58F4h>mTU!8dMN)iJ%Ns8UYNJ,efrqs%s8mf.cTmf3=<p]&eEhYmHTh>mEP!3Q+u!
+3Q%r"kmaNl>M1Ms!%>eGPD.*Dg1f&#eg7b;ZHIkn,NFE!:Tpf^&S,h!<<'!hY@*iMdFj3s415#s
+6AbDl>(>+s*ntTs6AbDlIGslrVm)jHPk'.s)[e6!p>e?J,~>
+ZMsp]rVm)j!;HNnc3Vht#lri^h>mTU!8cT0!!(UFru'[G/L5Pos1)U;LM#EChLdC*GM<(HDsm%3
+qZ%#TrrCpUrrCpUrrCp=rtOm>J,fQCGC05ek%fVLmbU81(k`J"rr\K&C[_9&"l;QG(k`Its!#Hq
+KCa/.p]'AkKE(A$+Uh+<L\#S2p]'AkKD0S:p](9=#lO](V$QhpruI=@C[_<'k7GZ-ec>IEo5f-M
+s5n*Ls6bsl$r0EMr;QiXB7p*]&]P+Vmf<+^s3:oMmf<+^s3:oCrrS:#hYdB^mVdUTs7^_aqu>eo
+KCo0Eh>mQT#4DQds8U@MYl=gfB4Ks!rrMP+qu@%=f)K5irtr0DhYR9\f)Ga,s8UpUs8N)Up\tf]
+K.S?mg?rm/s8VM*J*q6)rr3%LDr1<i"Ps.Y!7q/L!S.88rrVV,J,TBTIrFcTs7`Wf.KBEpqu?jd
+s8NAMrVm&q0uj4nhX^[JIrFcOrrq7cGGJ]UpAY-nhYR6U!8dbU!8dVQ!W_*Fo`#!icI2^l"5[@.
+p\t0oIfS@)rrMkjrVlr4!:Tpe!T!hSrrE,VqYpnPDpi]gW-?L9DsmH$!rL9krr32Z]`@O$!8dSP
+!<D!RrrE,VqYpVLCZbWr#lBj5irB&HDh%W`!Uan'!!q0U@q5NU[K#+\!"7BX!8dbUh>mTU!8dMN
+)h2Ygs8VA"J,e)<0gR7,mf.cTmf3<h0elQ+hYmHTh>lj@#P3:XhWAU#qu-NqmVi"'$#Ah2@q5NU
+[K#+\!"7BX!8dbUh>mTU!8dMN)h2Ygs8VA"J,e)<0gR7,mf.cTmf1jV0gS\;hZ!NWPSe3)rr2tO
+o=Y4oS5+S~>
+ZMspZrVm)f!;$6jcOA5$#lr`[gAq9R!8HE.!!(XGru'[I/gPSls12d?KkK9BhM!R-FkH_DD=-e1
+qZ%#UrrCgRrrCgRrrCg:rtOj;J,fQAFa<f_kA>qQn)$P:*.eb$rr\Q(D<q3$"lD`O*.eb!s!#Kr
+KCNr*p]'>hKE(D',S3aCL[fA.p]'>hKCsA4oDej:%/g,,V@<4uruICBD<q6%k7ki*dfB":mr<RG
+s5dsIs6l*r&5PlQr;QiYB7p*]&]Y1WlN$PVs3D,RlN$PVs3D,Irr`4ZD;>'h%..n]s8Vb7H27L'
+D2%W^!S[VRrs%choDej:%']a6k@nGbr;QfdDu9SACY/StAcEaYs53\R$ePCYg].<.!<<'!g\:^`
+hM!R-FkH(uJ,fQ9D1CqiIJs3EI;e$=rrh'VrrC[MrrL^Ol2LhPD1DNa$\*$\s8Vhp81=N<H2IXF
+7K<5jbPhGEo.\)^!8I)E!e5(SqYp`U@<nYW[.aM#!8IAM"T[<WrrCgNrrN2TmI^D[q97:drr_%^
+GPD+:!e14)rr3#jVZ$Mr\cD3urrLjSr;Qctg\UpWIr3MQOf3EHIr4TKrrW#?df07Ngq!LSrrCgM
+rrE,Squ6Zsg\_!QqgiJCrr39"Oa5pcs6XZQqYpTbDu0M?fDfDnruAKIhtmB]fDbj*s8UgRs8N)R
+q#;:_C[;$#lYD"Me8I*/.W+SQIr4TQs/In0<<1ePrrLjSlMh.]I;@TtBmKIOrr3#fDu9SAC[89;
+AcEaYs53\R$ePCYg].<.!<<'!g\CdfIr"BMs6FHMs3tsB67Qj>s*nnQs3tsB6<+$?rr3(d(iAU<
+rr@ZB[K>c`9n3~>
+ZMspUrVm)j!;HNnc3Vht#lri^h>mTU!8cT0!!(UFru'[G/L5Pos1)U;LM#EChLdC*GM<(HDsm%3
+qZ%#TrrCpUrrCpUrrCp=rtOm>J,fQCGC05ek%fVLmbU81(k`J"rr\K&C[_9&"l;QG(k`Its!#Hq
+KCa/.p]'AkKE(A$+Uh+<L\#S2p]'AkKD0S:p](9=#lO](V$QhpruI=@C[_<'k7GZ-ec>IEo5f-M
+s5n*Ls6bsl$r0EMr;QiXB7p*]&]P+Vmf<+^s3:oMmf<+^s3:oCrrS:#hYdB^mVdUTs7^_aqu>eo
+KCo0Eh>mQT#4DQds8U@MYl=gfB4Ks!rrMP+qu@%=f)K5irtr0DhYR9\f)Ga,s8UpUs8N)Up\tf]
+K.S?mg?rm/s8VM*J*q6)rr3%LDr1<i"Ps.Y!7q/L!S.88rrVV,J,TBTIrFcTs7`Wf.KBEpqu?jd
+s8NAMrVm&q0uj4nhX^[JIrFcOrrq7cGGJ]UpAY-nhYR6U!8dbU!8dVQ!W_*Fo`#!icI2^l"5[@.
+p\t0oIfS@)rrMkjrVlr4!:Tpe!T!hSrrE,VqYpnPDpi]gW-?L9DsmH$!rL9krr32Z]`@O$!8dSP
+!<D!RrrE,VqYpVLCZbWr#lBj5irB&HDh%W`!Uan'!!q0U@q5NU[K#+\!"7BX!8dbUh>mTU!8dMN
+)h2Ygs8VA"J,e)<0gR7,mf.cTmf3<h0elQ+hYmHTh>lj@#P3:XhWAU#qu-NqmVi"'$#Ah2@q5NU
+[K#+\!"7BX!8dbUh>mTU!8dMN)h2Ygs8VA"J,e)<0gR7,mf.cTmf1jV0gS\;hZ!NWPSe3)rr2t>
+o;r)WPY-H~>
+ZMsp]r;Qp3`rH(/1"$"3!8db4!<<'!hY.$Es8Vi=q#;oBhW"Rh>'K`'CKbA4s81[4s4UY#pO@,L
+qg/>;s8Vi=s8N)Us8N)Us8N)UkPkVODh%cd'8LA_s35/Cs6eb<s8STUs8QRhkPY>chY7'MS3m8$
+SGrO7`bUA0K6QqeibO>Lmcs]Lc#99TK6QqeibO>LLMOp0s-thDmn3TZ"p!ids'n(PrVll2qZ%Ro
+`IiC+s5IgLs6f1Ls35JTk-`J6s5IgLk-`J5rt36^s8NYMs8STDs8NYMs8STDpAY3FB9<#j!q'uV
+rr31XCZ>B=Asi5j!T!hTrritRs8STDYQ"[G@[R)n,5Z_6qu?QQk5YJ$&A8q\s7ZNfs8Vi=s8N)U
+s8UpUs8N)Uq#;0-hW"Rh>'K+IJ,fQ*?@VB]C[1rbCO>gOrrh0Yrtqm;rrK5%l2LhQDh%`c!e5.V
+rr32fCB4D7(khn_"f24fs&rV)rro5!n,ECEo)Ac@DsmH$"H-;UBB&Xb!<D!QrriDZs8N)Uqu6]t
+hX:%9$28XZlMpnYGB`f\rrRZMhZ!NVmf:r<rrVWhn,E=fh>mKR!<D!QrsF6omY>RjHhW#.meQkk
+pNLE<s8Vi^!:TpfhYR6Q!8dVQ!<D!QrrT9*XT&5*dSb;`s8VM*J,90hqg3\es82Q9s8U(M]bpeL
+pAjsfs7ah=rrCpUs5!bUrrCpNru6l*f)Pd$<e'jfBBK5DDsmXTDsmAg!7(WE!8d\S!T!hArrLt_
+qu?ae`W#l]qg3\es81g<s5M$0]bpeLpAjsfs7ah=rrCpUs5!bUrrCpNrud5/f)Pd$<e'jfBBK5D
+DsmXTDsm@DBBK6o!8dbU@l``Mrr@`D]`RYm:4N~>
+ZMspZr;Qp7_uKb.1su=6!8IP.!<<'!g[bF:s8Vi>q#;oBhrFah=a0W'CKY50s81^6s4CIupO@&I
+q0;u3s8Vi>s8N)Rs8N)Rs8N)RkPkVND1DQb'8^M`s3>>Hs6nk>s8SZZs8QXmj8Ao_htR0NSji\*
+T)SaCa)-\5KmE:ij(jGMn*BlNc>fTYKmE:ij(jGMM/1$/s.2(IlUh!RqZ,[Vs(+=QrVll3qZ%Rq
+`eA^0s5RmMs6o:Ns3>VYkI/\9s5RsQkI/\8rt39cs8NeNs8SZIs8NeNs8SZIpAY3FB92ri!psiS
+rr31ZCZ5<=BpnVn!S[VQrrj+Ss8SZIYQ"[HA!d,n,5HM0q>^?PkPtS"&AB.as766^s8Vi>s8N)R
+s8UgRs8N)Rq#;0-hrFah=a/tEJ,fQ*?[qH[C[;#bCOPsQrrh'VruA'<rrK,"l2LhPD1DNa!e5(S
+rr32gCB4D7*.n1]"el"_s&iM'rro8"li-t>o)Ac@D=.0!"H->YBArRa!<CmNrriDWs8N)Rqu6]t
+g[4Y5$28XZli7"ZGBNTXrrRZMg]%3Smf:u=rrVWhli-nbgAq0O!<CmNrsF6mm>5UiH1cZ(mJ6bj
+pNLE=s8Vi^!:0Xbg\UpN!8IDN!<CmNrrT9)XT&5*dSk;]s8VJ'J,90hq0@8]s82Q:s8TtJ^)[1Q
+o)SC^s7ak>rrCgRs4[PRrrCgKru6r-eGoQu<IaagBBB/CD=.@QD=.)d"O$iF!8IJP!S[V>rrLt`
+qu?af`r>u^q0@8]s81j>s5Cj,^)[1Qo)SC^s7ak>rrCgRs4[PRrrCgKrud;2eGoQu<IaagBBB/C
+D=.@QD=.(CBBB0n!8IPRAN]#Nrr@ZB[K>c`9n3~>
+ZMspUr;Qp3`rH(/1"$"3!8db4!<<'!hY.$Es8Vi=q#;oBhW"Rh>'K`'CKbA4s81[4s4UY#pO@,L
+qg/>;s8Vi=s8N)Us8N)Us8N)UkPkVODh%cd'8LA_s35/Cs6eb<s8STUs8QRhkPY>chY7'MS3m8$
+SGrO7`bUA0K6QqeibO>Lmcs]Lc#99TK6QqeibO>LLMOp0s-thDmn3TZ"p!ids'n(PrVll2qZ%Ro
+`IiC+s5IgLs6f1Ls35JTk-`J6s5IgLk-`J5rt36^s8NYMs8STDs8NYMs8STDpAY3FB9<#j!q'uV
+rr31XCZ>B=Asi5j!T!hTrritRs8STDYQ"[G@[R)n,5Z_6qu?QQk5YJ$&A8q\s7ZNfs8Vi=s8N)U
+s8UpUs8N)Uq#;0-hW"Rh>'K+IJ,fQ*?@VB]C[1rbCO>gOrrh0Yrtqm;rrK5%l2LhQDh%`c!e5.V
+rr32fCB4D7(khn_"f24fs&rV)rro5!n,ECEo)Ac@DsmH$"H-;UBB&Xb!<D!QrriDZs8N)Uqu6]t
+hX:%9$28XZlMpnYGB`f\rrRZMhZ!NVmf:r<rrVWhn,E=fh>mKR!<D!QrsF6omY>RjHhW#.meQkk
+pNLE<s8Vi^!:TpfhYR6Q!8dVQ!<D!QrrT9*XT&5*dSb;`s8VM*J,90hqg3\es82Q9s8U(M]bpeL
+pAjsfs7ah=rrCpUs5!bUrrCpNru6l*f)Pd$<e'jfBBK5DDsmXTDsmAg!7(WE!8d\S!T!hArrLt_
+qu?ae`W#l]qg3\es81g<s5M$0]bpeLpAjsfs7ah=rrCpUs5!bUrrCpNrud5/f)Pd$<e'jfBBK5D
+DsmXTDsm@DBBK6o!8dbU@l``Mrr@-3XTI[M8q6~>
+ZMsp]r;QqA6MKXlPgTLA!8db4!<<'!hZ$JWkN?#/q#;oBIq%-[<dX`DO;LF"s8.:Tg<s#KqgWDH
+s/8h!kN?#/s8N)Us8N)Us8N)UkPkVODh%cd'"M29mtb;ls-u)Zn'2cXs4.1irRV#K3]U^=c5<th
+ec:s'ei?dAs05UhhMY:>s-ui`hK*;_s05UhhMY:>s1)<"pZEuis8NXpmu/+`s4.1irRUoH!T!hU
+s":QWPhq<r[JualWSV].g?NHG_;^5N\a!s&_;a$+F8u8]6MKXlPlLc)6MKXlPkP+YW+*=7rrVV,
+J,]HP\QYNlLgJ3qrrLsVrVm%B6MKXlPct)gl>(nHrs#E&T]_t>SGrNi(a48*rt/.4kN?#/s8N)U
+s8UpUs8N)Mq#;-,Iq%-[<dXF^;UXuk*.RBp+ctQ=8Z_^e$/P[^KG_,c]cdCRrrB1u!!--Op\t<_
+Dh%`c!e5.Vrr32jDZKgW!8d_T&,-?os5sqscKD#8C]FD7`r,#orrR[[f)=b3oD\al\Nppfp&>$m
+hYR6U!8dbU!65!#s8N-#`n(+O!;$!c#H0e,db^3\T`+llIfS@(rru@M^$!sE6N-obh>mKR!<C.;
+k7$t^IrFb_8i<:AIrFcMrsPbgF4/p0;F:E`!64s"s8N*"`r5*#rrE,>r9++[#kNC#PhO,\4gk:h
+!q'uVq>UYt<hSWK=ulT^!Z3)-rr3R.>3G'P3WK*ZhZ*W4!<<'!f(f7a_+nUjeo)+LpNL94_*Vr&
+s*nhLp[8+-s+CC'rVloT!;c]qXnr(uXnD\qmVdUPrs#E&T]_t>SGrNi(a48*rt/.4kN?#/s8N)U
+s8UpUs8N)Mq#;GP:1hr*D\.EmGA$'S6>PldIr"?DGA$'SKE0U'ec<_gf)PaMK_)kYn!m.'~>
+ZMspZr;QqC61a7fQI5^C!8IP.!<<'!g](8Vj6']1q#;o@I:LpT=*scCOW6p+s7q(QfZmQFq1!,C
+s/K(%j6']1s8N)Rs8N)Rs8N)RkPkVND1DQb'"V;9m>#&ks.)8`lcU9Rs3gtgrR_)L3]q!>b8dhf
+f*%E.f/QgBs0>dnh2+t8s.)ubgN.#[s0>dnh2+t8s12E#oB.Nfs8*@jmtqtZs3gtgrR^uI!S[VR
+s":T[QJIBo[/Z[nW7uB+f^!BK_W-DP]'F3-_W06-FoVJa61a7fQN-u-61a7fQM1=[W+!45rrVS)
+J,]HP\m(WjLL83rrrLjSrVm%D61a7fQEU;ilYD"Irs#K)T&l\?Sc8Wj*$ft3rt/76j6']1s8N)R
+s8UgRs8N)Jq#;-*I:LpT=*sCY;:+ci*.R?m,*Lc=8?DUd$/5I[L)@Af^*!FRrrB5!!!-*Lp\t<^
+D1DNa!e5(Srr32iD#jUR!8meU&,-?ms5Of!cf:`2D?'V9a8G,prrR[[fDXk4oD\al\j@0lp&>$m
+g\UpR!8IPR!6>'$s8N-#a4L:Q!;$!c#H0h/dbU'XT`+llIfS7%rru=O^?<sB62gfagAq0O!<C1<
+k7$t^Ir4S[82R">Ir4TJrsPbhFjf*/;*k6^!6>$#s8N*"a8P3$rrE,?r9++[#k<7$QJ',X5.:Ij
+!psiSq>UZ!=.\NJ>s/,d!ZWJ6rr3R1=l\[N4TGE]g].<.!<<'!e+iq^_G=gmeo)+LolXp/^dDi#
+s*nbIp$2V(qh>+"rVloQ!;c]qY582!WqHAnm;7@Mrs#K)T&l\?Sc8Wj*$ft3rt/76j6']1s8N)R
+s8UgRs8N)Jq#;GQ:M8,,D\.EkF_BgO6YYfbIqe0?F_BgOL&f^&df@GefDkjNK(HDPl^COu~>
+ZMspUr;QqA6MKXlPgTLA!8db4!<<'!hZ$JWkN?#/q#;oBIq%-[<dX`DO;LF"s8.:Tg<s#KqgWDH
+s/8h!kN?#/s8N)Us8N)Us8N)UkPkVODh%cd'"M29mtb;ls-u)Zn'2cXs4.1irRV#K3]U^=c5<th
+ec:s'ei?dAs05UhhMY:>s-ui`hK*;_s05UhhMY:>s1)<"pZEuis8NXpmu/+`s4.1irRUoH!T!hU
+s":QWPhq<r[JualWSV].g?NHG_;^5N\a!s&_;a$+F8u8]6MKXlPlLc)6MKXlPkP+YW+*=7rrVV,
+J,]HP\QYNlLgJ3qrrLsVrVm%B6MKXlPct)gl>(nHrs#E&T]_t>SGrNi(a48*rt/.4kN?#/s8N)U
+s8UpUs8N)Mq#;-,Iq%-[<dXF^;UXuk*.RBp+ctQ=8Z_^e$/P[^KG_,c]cdCRrrB1u!!--Op\t<_
+Dh%`c!e5.Vrr32jDZKgW!8d_T&,-?os5sqscKD#8C]FD7`r,#orrR[[f)=b3oD\al\Nppfp&>$m
+hYR6U!8dbU!65!#s8N-#`n(+O!;$!c#H0e,db^3\T`+llIfS@(rru@M^$!sE6N-obh>mKR!<C.;
+k7$t^IrFb_8i<:AIrFcMrsPbgF4/p0;F:E`!64s"s8N*"`r5*#rrE,>r9++[#kNC#PhO,\4gk:h
+!q'uVq>UYt<hSWK=ulT^!Z3)-rr3R.>3G'P3WK*ZhZ*W4!<<'!f(f7a_+nUjeo)+LpNL94_*Vr&
+s*nhLp[8+-s+CC'rVloT!;c]qXnr(uXnD\qmVdUPrs#E&T]_t>SGrNi(a48*rt/.4kN?#/s8N)U
+s8UpUs8N)Mq#;GP:1hr*D\.EmGA$'S6>PldIr"?DGA$'SKE0U'ec<_gf)PaMF7ZL8kEJSh~>
+ZMsp]r;Qoo@gE?]d/OUVhZ)F4s8N)Us6j+s#YO:Ss!u>t$kR(&s8TbqDsmZ*butMeB@d*U+^3Uo
+mofu&9'?6S!8dbU!8dbU!8co=!q'uVrr3Q,XYgAI\c;]thDkQQSH&VZqZ-Zr"Pu-=(nCU*-+,0%
+&:;+js8/`L#W]0es6bdb$sLpUs8/`L#W]0es8/p.#RGMNrs,qT!%Gqfs.&rdr;QfS!<3!=qku4T
+3O/J]mY`%n>0[*Ig2@Z27D8a$g2@Z2&:=EV"SZC3#]p"F"SZC3#]o\=!eXh5qu6`cDh%cd"oGDZ
+#X,`irrLsVrVm#p@gE?]Y5\RkDh%Za#5=oJ#Uu/4rr3%H!9a@]'(9!0#YO:[rrCpUs5!bUs$?^n
+q#;)R=ptsTf)N]a#T.J\J*q5M<X^RQp\=aph>mTUKGX\DV#]c[!q'uVrVlqKDsmW)"o!3@s(aXm
+rs;jhs8UqR#QQ$$rr;fp!VcKerr@QG!!dlJs8VA"3P"h_!<D!QrrW8Xs8Vrr!Up'b!!.HDq>U]s
+YsAd(3N;cOrrRZMhYmHYpM1TG&7b2-rrLsVr;ZTn%"%l$DslUp9$.*_DsmE#$2^tn$j\k'n,NFa
+!!2ioqZ$Zcs7u^%p](9]Qn8FP;Si>3!q'uVq>UZnUbN-(9'?3R!daq1rr3Z#=pPC+kPtP^hZ*W4
+!<<'c!4CPVru/^K$lEbXJ,d2J$r1F]KE%Sf>2'"'#S;q]#lXc(h>l^<!q'uVqu6lpUbN-(R.L=W
+!daq1rr3W"=pPC+kPtP^hZ*W4!<<'c!4DV%*5PAY(i*$!s1L],:1kl*s.CN=g:]c\:5hLFs.&rd
+s8N(Po=Y4oS5+S~>
+ZMspZr;Qoo@13Qed/OUVg]-".s8N)Rs6j)!#YjLVs!uB!$kd4&s8T_oDt!`+c<C\iB@QsS,$W^o
+mo^&):$;QV!8IPR!8IPR!8H]:!psiSrr3Q,X>UJP])Vg!h`M#]RfEDVqZ-Zr"Q)<E*1Hm,-*f'%
+'R@:gs7rNG$9GEgs6kpi&6mBYs7rNG$9GEgs8/m+$k.:Xrs,tT!%c1js-ifbr;QfP!<3!Eq5,hQ
+3jAM]mu8G$>Km-IfP_N47_8QufP_N4'RBTUs7]q1%!DRL"SZ=5%!D:D"9!dVf_b[Mm;7@Prrr;$
+2@Mj^oD\jG!<)p#pL+I=Fft`Gm;7@Mrs&4n1(#M"oD\akGlZn(rt=d'$j]Sjs8N)Rs8UgRs8P@f
+ZM=G7c<C\iB@Qt$;%+F_<IaCQ:K\/[UA+H_$/5I[s+2'f0W"j7rrVS)J,TBKIr4TPrrr.@!<6am
+r;R1.3<0$5;%*FIK)>TJq>^Qfq>($jJ,93NH27L?l"N,ep&>$mg\UpP!8IPRqZ$Z_s7u]rH27:9
+#PkSj$jo%mp&4mlIfS7%rs&(3(]Y7Yli$hagAq0Oq>^qLq1!8KiF,C%s*nnQq#:ZrYX/a*3aq@S
+s7u]roDe[f!UKd^!"/>ts6Z+)"qXYGrVlfum;7@Krs&4n1(#L*kPkJ_GlZn(rtFj($j]Sjs8N)R
+s8UgRs8P@fZIo!Q)Sf&U(i*'"s1Uf0;/%G4s.CQ?f`-@*'TPTjrVloQ!9X:_m;7@Mrs&4n1(#M"
+oD\akGlZn(rt=d'$j]Sjs8N)Rs8UgRs8P@fZM=G>^eG4SCK#`_^-W<,Bde]8TH[Um^-W<,N^XBV
+Rem*brr@ZB[K>c`9n3~>
+ZMspUr;Qoo@gE?]d/OUVhZ)F4s8N)Us6j+s#YO:Ss!u>t$kR(&s8TbqDsmZ*butMeB@d*U+^3Uo
+mofu&9'?6S!8dbU!8dbU!8co=!q'uVrr3Q,XYgAI\c;]thDkQQSH&VZqZ-Zr"Pu-=(nCU*-+,0%
+&:;+js8/`L#W]0es6bdb$sLpUs8/`L#W]0es8/p.#RGMNrs,qT!%Gqfs.&rdr;QfS!<3!=qku4T
+3O/J]mY`%n>0[*Ig2@Z27D8a$g2@Z2&:=EV"SZC3#]p"F"SZC3#]o\=!eXh5qu6`cDh%cd"oGDZ
+#X,`irrLsVrVm#p@gE?]Y5\RkDh%Za#5=oJ#Uu/4rr3%H!9a@]'(9!0#YO:[rrCpUs5!bUs$?^n
+q#;)R=ptsTf)N]a#T.J\J*q5M<X^RQp\=aph>mTUKGX\DV#]c[!q'uVrVlqKDsmW)"o!3@s(aXm
+rs;jhs8UqR#QQ$$rr;fp!VcKerr@QG!!dlJs8VA"3P"h_!<D!QrrW8Xs8Vrr!Up'b!!.HDq>U]s
+YsAd(3N;cOrrRZMhYmHYpM1TG&7b2-rrLsVr;ZTn%"%l$DslUp9$.*_DsmE#$2^tn$j\k'n,NFa
+!!2ioqZ$Zcs7u^%p](9]Qn8FP;Si>3!q'uVq>UZnUbN-(9'?3R!daq1rr3Z#=pPC+kPtP^hZ*W4
+!<<'c!4CPVru/^K$lEbXJ,d2J$r1F]KE%Sf>2'"'#S;q]#lXc(h>l^<!q'uVqu6lpUbN-(R.L=W
+!daq1rr3W"=pPC+kPtP^hZ*W4!<<'c!4DV%*5PAY(i*$!s1L],:1kl*s.CN=g:]c\:5hLFs.&rd
+s8N(?o;r)WPY-H~>
+ZN#L4J_kt7J_kt7J_kt7QJMUpo=Y4oS5+S~>
+ZN#L1J_Pb1J_Pb1J_Pb1QJ2Cko<n_dRSA;~>
+ZN#L,J_#D'J_#D'J_#D'QIZ%Wo;r)WPY-H~>
+ZN#L4J_kt7J_kt7J_kt7QJMUpo=Y4oS5+S~>
+ZN#L1J_Pb1J_Pb1J_Pb1QJ2Cko<n_dRSA;~>
+ZN#L,J_#D'J_#D'J_#D'QIZ%Wo;r)WPY-H~>
+ZN#L4J_kt7J_kt7J_kt7QJMUpo=Y4oS5+S~>
+ZN#L1J_Pb1J_Pb1J_Pb1QJ2Cko<n_dRSA;~>
+ZN#L,J_#D'J_#D'J_#D'QIZ%Wo;r)WPY-H~>
+ZMsp]JV8T-JV8T-JV8T-JV9DD!Uk^5]`RYm:4N~>
+ZMspZJV&H)JV&H)JV&H)JV'8@!UG@/[K>c`9n3~>
+ZMspUJTHB`JTHB`JTHB`JTI3"!U"OqXTI[M8q6~>
+ZMss^K_59E!.k0$s+13$s+13$s7ZHnIpR]>_n?',o`"smmtC?5!s%e[:4N~>
+ZMss[K(T'C!.k0$s+13$s+13$s7ZHnIp7K4_mTR!o`"sml[nd/!s%YU9n3~>
+ZMssVF7fJ4!.k0$s+13$s+13$s7ZHnIo_-&_lWpio`"smkB$:q!s%MK8q6~>
+ZMt!_K`Cc&!h98jJ_kt7J_kt7J_kt7ptc(c:0rLb_n?*-me5K?S,i#2s7Y:PS,i#J:4N~>
+ZMt!\K)bQ!!h',hJ_Pb1J_Pb1J_Pb1ptGk]9j<1W_mTU"mIo9;RK2Z*s7Y1MRK2ZB9n3~>
+ZMt!WF8tsb!gE]bJ_#D'J_#D'J_#D'psoMS8lgMF_lWsjlLrd3PQ9lfs7Y"HPQ9m28q6~>
+ZMt!_K`Cc&!h98jJ_kt7J_kt7J_kt7ptc(c:0rLb_n?*-me5K?S,i#2s7Y:PS,i#J:4N~>
+ZMt!\K)bQ!!h',hJ_Pb1J_Pb1J_Pb1ptGk]9j<1W_mTU"mIo9;RK2Z*s7Y1MRK2ZB9n3~>
+ZMt!WF8tsb!gE]bJ_#D'J_#D'J_#D'psoMS8lgMF_lWsjlLrd3PQ9lfs7Y"HPQ9m28q6~>
+ZMt!_K`Cr+!!)uS!h98jJ_kt7J_kt7J_kt7ptc(c:0rLb_n?*-metuB!;kUUS,i#2s7Y:PS,i#J
+:4N~>
+ZMt!\K)b`&!!)uP!h',hJ_Pb1J_Pb1J_Pb1ptGk]9j<1W_mTU"mJYc>!;kLRRK2Z*s7Y1MRK2ZB
+9n3~>
+ZMt!WF8u-g!!)uK!gE]bJ_#D'J_#D'J_#D'psoMS8lgMF_lWsjlM]96!;k=MPQ9lfs7Y"HPQ9m2
+8q6~>
+ZMt!_K`Cu,rrE#S!h98jJ_kt7J_kt7J_kt7ptc(c:0rLb_n?*-meu#B!;t[VS,i#2s7Y:PS,i#J
+:4N~>
+ZMt!\K)bc'rrE#P!h',hJ_Pb1J_Pb1J_Pb1ptGk]9j<1W_mTU"mJYf>!;tRSRK2Z*s7Y1MRK2ZB
+9n3~>
+ZMt!WF8u0hrrE#K!gE]bJ_#D'J_#D'J_#D'psoMS8lgMF_lWsjlM]<6!;tCNPQ9lfs7Y"HPQ9m2
+8q6~>
+ZMt!_K`D#-rW)oR!h98jJ_kt7J_kt7J_kt7ptc(c:0rLb_n?*-meu#A!<(aYS,i#2s5)W/!<:mY
+S,i#J:4N~>
+ZMt!\K)bf(rW)oO!h',hJ_Pb1J_Pb1J_Pb1ptGk]9j<1W_mTU"mJYf=!<(XVRK2Z*s4c<)!<:dV
+RK2ZB9n3~>
+ZMt!WF8u3irW)oJ!gE]bJ_#D'J_#D'J_#D'psoMS8lgMF_lWsjlM]<5!<(IQPQ9lfs45ct!<:UQ
+PQ9m28q6~>
+ZMt!_K`D&.r;cfQ!h98jJ_kt7Mr"Q_L0DrThLXO7hX]M)]hVmb]u.MahX:@!r;ciR"IoJ\K`D&.
+quH`Q"IoJ\S5+S~>
+ZMt!\K)bi)r;cfN!h',hJ_Pb1Mq\?YKiu]PgO\+1g[a)#\kQC[[_oNSg?njnr;ciO"I]>VK)bi)
+quH`N"I]>VRSA;~>
+ZMt!WF8u6jr;cfI!gE]bJ_#D'Mq/!OJlg'Feq)D'f(.An[7XJNXi%7Af'<4br;ciJ"I&oLF8u6j
+quH`I"I&oLPY-H~>
+ZMt!_K`D#-rW)oR!h98jJ_kt7NnsrdL+Wo<[=R1chLXPRh?(Ac?@ff-]`I!XrSIMRrS@[I!:PU@
+rSIMRrS@[I!:QFQJ,~>
+ZMt!\K)bf(rW)oO!h',hJ_Pb1NnX`^Ke3`:Z[pk^gO\,LgB+r\>Cj6#[K5+LrS.;OrS%ID!:,7:
+rS.;OrS%ID!:-(JJ,~>
+ZMt!WF8u3irW)oJ!gE]bJ_#D'Nn+BTJh.?6YCY8Ueq)EBecN6O<e7BjXT@#<rRUrJrRM+9!9\G'
+rRUrJrRM+9!9]S=J,~>
+ZMt!_K`Cu,rrE#S!h98jJ_kt7Okp>iL+X,E!"Y<FhLXO7hXKA']hVmb]u.MahX:@!rrDuR"IoJ\
+K`Cu,!!)rR"IoJ\S5+S~>
+ZMt!\K)bc'rrE#P!h',hJ_Pb1OkU,cKe3oB!"Y6DgO\+1g[Nr!\kQC[[_oNSg?njnrrDuO"I]>V
+K)bc'!!)rO"I]>VRSA;~>
+ZMt!WF8u0hrrE#K!gE]bJ_#D'Ok'cYJh.N>!"Y-Aeq)D'f'q5l[7XJNXi%7Af'<4brrDuJ"I&oL
+F8u0h!!)rJ"I&oLPY-H~>
+ZMt!_K`Cr+!!)uS!h98jJ_kt7PhlPiL+X/FrVus-COt>nhLXPPh?(Ac?@ff-]`I!XrS@MSqq_IG
+!:PU@p>,qB!:QFQJ,~>
+ZMt!\K)b`&!!)uP!h',hJ_Pb1PhQ>cKe3rCrVus-Bn>#igO\,JgB+r\>Cj6#[K5+LrS%;PqqD7B
+!:,7:p=f_=!:-(JJ,~>
+ZMt!WF8u-g!!)uK!gE]bJ_#D'Ph#uYJh.Q?rVus,B7\Wbeq)E@ecN6O<e7BjXT@#<rRLrKqpkn7
+!9\G'p=9A2!9]S=J,~>
+ZMt!_K`Cc&!h98jJ_kt7QJMbrIM;bfr;Zj&6%RmDhLXPOh?(Ac?@ff-]`I!Xp>,qB!:PU@p>,qB
+!:QFQJ,~>
+ZMt!\K)bQ!!h',hJ_Pb1QJ2PlHkZPdr;Zj&5_7[@gO\,IgB+r\>Cj6#[K5+Lp=f_=!:,7:p=f_=
+!:-(JJ,~>
+ZMt!WF8tsb!gE]bJ_#D'QIZ2cGn^5ar;Zj&5(V:9eq)E?ecN6O<e7BjXT@#<p=9A2!9\G'p=9A2
+!9]S=J,~>
+ZMt!_K`Cc&!h98jJ_kt7PMQPbRlpiR!%$6JhLXO7hX95%]hVmb]u.MahX:*o"IoJ\K`Cc&"IoJ\
+S5+S~>
+ZMt!\K)bQ!!h',hJ_Pb1PM6>\R61QO!$p'FgO\+1g[<et\kQC[[_oNSg?nUg"I]>VK)bQ!"I]>V
+RSA;~>
+ZMt!WF8tsb!gE]bJ_#D'PL]uSQ9,0K!$omAeq)D'f'_)j[7XJNXi%7Af';t["I&oLF8tsb"I&oL
+PY-H~>
+ZMt!_K`C_8!<E.NS:R2oS-Fm&64Eo*NIdUNS:R3sS,lAkJ\At7!T))oS-&c[K`C_8!s%e[:4N~>
+ZMt!\K)bM4!<E.NRXpokRKeU!64Eo*Mh.=JRXppoRK6,eJ[WJ)!SYcjRKEQUK)bM4!s%YU9n3~>
+ZMt!WF8tot!<E.NP_#'_PQldi57@N%L4PS?P_#(cPQ=BWJZZhl!S5BcPQLpKF8tot!s%MK8q6~>
+ZMss^KRj,S!4;h,!<N?+"oJQ,"Tni-JH16$JH3Ld!+(5i_n?%Vo)Jg[K_#0Fn!m.'~>
+ZMss[Jq3oQ!.b-$!.b-$!9X=^>Cj6#[K'P'!!2D;o)JjXRSA;~>
+ZMssVF+F=B!.b-$!.b-$!9X=^<e7BjXT2Dn!!28(o)JjTPY-H~>
+ZMsp]Ja\0YL@5B&9j?TFR/ib.mt'qYmt'qbmfAqRJ,~>
+ZMspZJa7mQ\*F:`k2bR]i8<GihZ)I:i8N_WkN_0p#M;^RhWpL.R=X[Tl[eAQl\b!/RSA;~>
+ZMspUJ`hUI\*""Xio&_Mh;$c_g'?Bfh;-uHj6#Id#LlCKg?4\#Q\"=NkCMfIkDJF'PY-H~>
+ZN#L4J_mlmrSR2(rnlkp!h(O,rn[Z_B7\ojhLXO7hML(iS5+S~>
+ZN#L1J_R`i$/!hYda6:abK@s'a9fu2bg"G[daZn&l.Z9,.%1(h!FBAhgO\+1gO\+9gB!a;J,~>
+ZN#L,J_%B_$e*MLc-+8N`l?!9`;[[S`!OE&a2lEHc-Xnhl.,p#-^Ob_!F0,ceq)D'eq)D/ecD"-
+J,~>
+ZN#L4J_mrornm_5o&9T+rnm%u"4:%>c2HK!LOn<5hLXO7hMC"hS5+S~>
+ZN#L1J_Rfk$J<nXd*BhVaMu3:rkeZNrk]#\`Q$!@bg+Saf%TNG"3se9b5L&pKn8!0gO\+1gPFSb
+RSA;~>
+ZN#L,J_%Ha%F`\LbK7cC_nj1(^:h5Z]FDQg^;.S$_o9[<bKeMcmFDB^:e/P(ec:;Qeq)D'eq)D.
+ecD"-J,~>
+ZN#U7R_8^Gp>2ma$GO9j_8=(,_o0OCo]#l/rnmgm^[Bq[Ua_E&h>lC2h>kfh]`?=Oh>kfp]qX?b
+c+Ufdh>kfh^%U:_c(_o@h>s-AJ,~>
+ZN#U4R^rLAp=l^\%_&gNYcXt*Vl$8bYJ%T]r4E!A%)'Bj_Sa@6b0@/rf%TWJ!hq-(qqD,)rn@Fq
+R^rLApY,\jU:R)R!m8*cUtYmlR_&4I!6V%InCmu49n3~>
+ZN#U/R^E.7p=?@R%^N=@X/MnlUS4?PX1>aLr3d*E\@K2_]t_D$`lP3_dFIa;!hLfuqpkbtrmh(g
+R^E.7pXT>`U:$`H!l_RTUt,ObR^Mk?!6(\?nC@W)8q6~>
+ZN#U7!1]QS!KGY'h>j(M:(9us<**4,?=75QAnR^io],r1s5=+=UX7oUo%jK"?U2[*h>t<4S5'+0
+eb@o$]lg,G!6q7p!kktcUtu-cFdu2,c1]up]lg,G!6t#i!Luo8~>
+ZN#U4!1KEP!K>M$gAm\H9b9uk8P)EA779L16:#e"[^NUAZk'RQ[^`l[]YD>$a,RgZe(=3G"4LR@
+`:hpd\oXB9!R0$egB"m,UeLj5U>#a\Zco6"!P3?B9`WE2gB"m,UeLj5nCmu49n3~>
+ZN#U/!0j!G!K#.rec:r=8e=Qb7n,p86UF((5<j7lZE^\4YlCs;ZF%$J\@]Gh_MGhIcI2=8"3t.8
+_"Q=[[;VR-!Qi[^ecE0sUe1X/U=KCRY0!Kj!OZj98c[!,ecE0sUe1X/nC@W)8q6~>
+ZN#U7!Ls.iJ,_b-If_iame5K<S,fjE%RNU<LP^qJNf]BeP[KgIp#Q)3ro+'Xs5;hmo\KYP/;<`Q
+!kh>nWdb!Kp4!,Ds6fX<!kh>nZ@;iSp4!)Cs.\?O^!6SQh?(Ac5H925!;:mC!<;cL!kh>nZ[`!>
+p4!)Cs7"kGS5+S~>
+ZN#U4!La"gJ,_b-If_iamIo98RK0XC&O&@'GBItHDf0B,C,BV>Yck5-XV%_>Yd(OB[^j#`^kq6r
+c-Xtop=fYM.tdKK!kM)jWdb!Kp4!,Ds6]R8!kM)jZ@;iSp4!)Cs.\6L]$12MgB+r\5H925!;:mC
+!<;cI!kM)jZ[`!>p4!)Cs7"bDRSA;~>
+ZN#U/!L*SaJ,_b-If_ialLrd0PQ8"=&O&@'GBItHDf0B,C,BV;XK/B!W=c/2XKA\2ZF.-O]7f@d
+aNMr\p=9;D.Y.0B!jtWbWdb!Kp4!,Ds6B@0!jtWbZ@;iSp4!)Cs.\'G[E8HEecN6O5H925!;:mC
+!<;cD!jtWbZ[`!>p4!)Cs7"S?PY-H~>
+ZN#U7!Ls.irrIUnp[/*,J+!$e!Ls.qrrIe%rpTdSs7$/RRdp(4rT+"=#ND`_iS`YOhtZ%1fkWR`
+oA0P^:4K;D!!)`\!W`8gpYGtb:4KSL!!)`\!<E.oh?(C8s.nKQ]hX'Wrr<&mmK!=fp>,ka:4KVM
+!Io=emK!=fnD429:4N~>
+ZN#U4!La"grrIUmp[&$*J*lsa!La"prtG6TDqimmd*9\P`50/nA@SY<Vl0Nks/-I-WiE/'Yd1[G
+\qT+]aNMlXg%jA)enI(Wo@j>X9n02C!!)`[!W`8fpY,b\9n0JK!!)`[!<E.ogB+t1s.nBN\kR[S
+rr<&mm/[4ep=fY[9n0ML!Io:dm/[4enCmu49n3~>
+ZN#U/!L*SarrIUlpZ_g&J*QaY!L*SjrtG6TDV3Idc-")F_7mQfA@AA2USIg_s.^1%VPgAmXKJh7
+[Xd>P_oBjEeG7Ytd:YAKo@<uN8q3l@!!)`X!W`8cpXTDR8q4/H!!)`X!<E.oecN8$s.n3I[7YqK
+rr<&ml2^nbp=9;Q8q42I!Io7cl2^nbnC@W)8q6~>
+ZN#U7!Ls.irrIUfpYGsiJ+!$e!Ls.qrs+=*iSieUj5^.""6GW9o(D/Ejo4<Hj/`4>iSi_Phtl13
+[kN*_o%jG]:4K;D!!)`L!W`8gpYGtb:4KSL!!)`L!<E.oh?(C8s.nKQ]hX'Wrr<&mh>mWVp>,ka
+:4KVM!Io%]h>mWVnD429:4N~>
+ZN#U4!La"grrIUdpY,adJ*lsa!La"rrtYP/oQOib_S3Xk['?g9W`*<2US=HTrgsmtTq\<XVPpMr
+YHbKdg:kGCaj/;cqqD4\0R2:AgB+r\J#`MK!;>.K!<;H\gB+r\J$T(S!;>.J!<8eJ!kQVUUtYs^
+9n02C!!)`I!<E/ngB+r\J$].UIr4o6!<E/hgB!a;J,~>
+ZN#U/!L*SarrIUbpXTC]J*QaY!L*SlrtPJ.oQOc\]t1YYYcXt)VG^g+T:VVOS.hHbT:r!TVPpPt
+Z$b9:]tq\0bgQC>"0jJ$eFM/l[7YqKrr<&mecGjOlM&j2[7YqSrr<&mec>dNU=KCRaoA0f!jtXM
+WrE&!p=96Es7Y"F[7YqTrrIUbp=96Es7"S?PY-H~>
+ZN#U7!Ls.irrIUfpYGsiJ+!$e!Ls.qrs+F1io9"YjQ-=%"6PiAo(D2Fk5OHKjKAOCio8qTi8=Li
+"5J)U\a\GW]hX'Wrr<&mh?!]Wme>Q>]hX'_rr<&mh>mWVU>>sbc2XTr!kh?YWrE&!p>,fMs7Y:N
+]hX'`rrIUfp>,fMs7"kGS5+S~>
+ZN#U4!La"grrIUdpY,adJ*lsa!La"ss"F?GoBp^/^q@1bZ*(.,VPI$nX.5ZJR@0G1R@9V8StD^P
+VQ$W"IFG^=^r4==dFS<O"5.fO[d`#Q\kR[Srr<&mgB%BTmJ#?:\kR[[rr<&mgAq<SU>#a\bl=Kn
+!kM*UWrE&!p=fTJs7Y1K\kR[\rrIUdp=fTJs7"bDRSA;~>
+ZN#U/!L*SarrIUbpXTC]J*QaY!L*Sms"F?GoBp^-]=5/PXfA:qU7b7dW0ip<QBmf%QC!r*R[fqA
+U8=cgGgj%0]>2A+bgHF@"4V?FZLHEH[7YqKrr<&mecGjOlM&j2[7YqSrr<&mec>dNU=KCRaoA0f
+!jtXMWrE&!p=96Es7Y"F[7YqTrrIUbp=96Es7"S?PY-H~>
+ZN#U7!Ls.irrIUfrSIROrS@ToJ+!$e!Ls.qrs+O7ioB([\[qe&"6Z&JoC_>HkPjTTjfndFj5T(W
+i8EMLhS2!eg@*l"]hX'Wrr<&sh>hKlh?!]Wme>Q>]hX'_rr<&sh>hKlh>mWVU>>sbc2XTr!kh?Y
+WrE&!r8%Elr8%GSs7Y:N]hX'`rrIUfr8%Elr8%GSs7"kGS5+S~>
+ZN#U4!La"grrIUdrS.@JrS%BjJ*lsa!La"trtbS.oBka]?G!YPYCM(uU7[uN=JM1HPPgR^PE_B#
+R@Be@USXr8c*Ojj^Ve.:d+@$b2Jq(7gB+r\J#`MK!;tROD>`,i!<;H\gB+r\J$T(S!;tROD>`,h
+!<8eJ!kQVUUtYs^9n02C!!)rO!,_Yg!<E/ngB+r\J$].UIr5,<!,_Yg!<E/hgB!a;J,~>
+ZN#U/!L*SarrIUbrRV"ArRM$cJ*QaY!L*SnrtbS.oBka]?+.&BX*o>gSt)3A=J:n?OSk.XOHG]j
+QC"&1T:r*'c*+F]]>)8(bL4tO2/:S.ecN6OJ#`MK!;tCJC])`b!<;?YecN6OJ$T(S!;tCJC])`a
+!<8eE!k$/MUt,UT8q3l@!!)rJ!,MM`!<E/necN6OJ$].UIr"u5!,MM`!<E/hecD"-J,~>
+ZN#U7!Ls.irrIUfrn[aS2`IW5h?%VFme5K<S,fkp%ZlD)jQ*j`Bticnkae^Ep$)J>s6'FE%C?)q
+jQ#7ZiS`YOK.aFrh?(AcJ#`MK!<(aUDZF_Sh?!]Wme>Q>]hX'_rr<&th?%TqDuJMn!<8eM!klkY
+Utu0d:4K;D!!)uS!cJ'WrS@PTs7Y:N]hX'`rrIUfrS@To!,qhm!<E/hh>s-AJ,~>
+ZN#U4!La"grrIUdrn@ON2E%B1gB)5AmIo98RK0kt)#j=%mHESJ>dgo>IjldiS=,^8<Lo22NK!jp
+)2sQ8O-,TjQ^OD:UNOSZZ*q6X_T0mIIk@kkgB+r\J#`MK!<(XRD#eGOgB%BTmJ#?:\kR[[rr<&t
+gB)3lD>i2i!<8eJ!kQVUUtYs^9n02C!!)uP!c7pSrS%>Qs7Y1K\kR[\rrIUdrS%Bj!,_\h!<E/h
+gB!a;J,~>
+ZN#U/!L*SarrIUbrmh1E2)V'+ecKW:lLrd0PQ85n)#j=%mHESJ>-Y3/Hmg@aR$Nq,<L\r*MM_=g
+)2X6/N/`m]PEqW,T5_fMXg,=G^;@q6Hn;>cecN6OJ#`MK!<(IMCB//KecGjOlM&j2[7YqSrr<&t
+ecKUeC]2fb!<8eE!k$/MUt,UT8q3l@!!)uK!c%dOrRLuLs7Y"F[7YqTrrIUbrRM$c!,MPa!<E/h
+ecD"-J,~>
+ZMss^XSQi:^!1KYh>jGNDZPR*ZJGVP!36&/IrF3#VDeJT2l>HgDh%3Kh>s,HZMtDtLZIO-BLGC3
+_<C-WXRu2NrosIHs5sg!s5i>&j5].Xa?X7ep"fc#Su2DA!kh?YWrE&!rn[WnrVuq:rn[\Vs6fX<
+!kh?YZMsn)rn[WnrVuq:rn[YUs.\?O^!6TUh?D>lGAhi,e_U>GNV[Pp^!1KXh?(AcJ#`MK!<1gT
+DuK_:DuSSo!<;cL!kh?YZi:&UDuSSnDuK_:DuSSo!<;QF!Luo8~>
+ZMss[WqpQ6]Zb6UgAn&ID#o=%ZJ,DK!36&/Ir3rpUc&2Q2Pf*^D1CsHgB!`C\GmB@oBti%h.p2u
+XF;Pt!$uWKO[`36M2-i`KboK!M2R=ROcu-#ST2HDXK]+C^;@-9?./E#!n3^9qqD1`9n02C!!*#Q
+!,_]8!,__i!W`8fpY,b\9n0JK!!*#Q!,_]8!,__i!<E.ogB+t1s8C[Ub`[$aH`#?J!Q'ckD$%Ao
+D<BRS\kR[Srr<&ugAl*i!!$m8gAq<Sp=fY[9n0ML!IntcgAl*i!!$m8gAq<SnCmu49n3~>
+ZMssVW;:92\]JXMec;B@CB9!qZIT&@!36&/Ir!WdTJZ]L25&OOCObXCecD!8\GmB@oBti%h.p,o
+W-Tfk!$uNENC?^/L4k3WJes&mL51VENKB?jR;Ka8W3!83]"Y:+>Kuil!md=.qpkhV8q3l@!!*#L
+!,MQ6!,MSb!W`8cpXTDR8q4/H!!*#L!,MQ6!,MSb!<E.oecN8$s8CLPacLFVGGNd?!PaKfCBD&g
+CZa1L[7YqKrr<&uec9Lb!!$g6ec>dNp=9;Q8q42I!Innaec9Lb!!$g6ec>dNnC@W)8q6~>
+ZMt*bW+TaD!<-U4]u;klh?%UG?N+R<J%O+b!ii'KoA0PKGLH3A!Ls/err@iQruq9EK86,Ts8VuB
+QA)!es8V`1OF`_Dqu?Q>QA)!es8UrhrI4gXrr3ABLP)Q&s8VhlK87#9rsZ`!K;d2rs8CN;KqR6!
+rrdgihVP..D[!#phJ[o3p>,h?!<3!$ifnqWhZ!NZlC`WZW;$2frrV\p^]+6Bi1u'mdJa+;`K5Y:
+chmY?!TJV.rri5(K87#:rri(pK87#7rr@iNrsk<PjlO.@R%'Ybl0>+Lo_%PLlMp,KkR>!$k2k^c
+j5Z7QWSl\,h?(r.Du8Am]hX(Ts8U"9rrrAPRY-C+rr3,qW.Tl9rr3DlTRVTmp](9fW.Tl9rr3#U
+T)O3NSD=/Ei1u'mdJa+Bc^'9Xh#@<^i1u'ZW;HVpqltd/\blC,!<1jQDuSSp!<;K]h@mRtJ,fQ<
+]8;BTmf3=Z`K5Y:W;$5i"QFq2s3:Fj!:Kgc!TJV-rrp67KpL-brVuo8rVm&ZUkP,^rVccr_tsB5
+!<1jQDuSSo!<8eM!klkYrn[n.CJnVO;F.,7h?'^Qf_sY1_hVl2<WN,3!klQ1k2$0Q:4N3As24j9%
+K4kHKqR6$s81-@K87#:rs\1cItO]os8VhlK87#:rrBb2IfR%Yrs[h]KpL-bs81-.KqR6#rs[h]K
+pL-bs8CN;Knm59rr<&uhY_<kh>mWVp>-Ir:4N<Dn@OO6\aKLtoYloCQI#I,rrV]LJ,TBX_2!ZAq
+u?]]TS%lqoDej(rI4gXr;Zf7rr3K#`K5Y:chmbBi1u'mdJa%D!Io%ehY_<kh>mWVnD429:4N~>
+ZMt*_VIO+9!<-I0]#6AegB)4A>lJ46I(7SY!iVgAo@j>FFj0R6!La#drrN(TrVn&<Y_._(h#IEN
+c^'9WgA_-F`K5\;chd\<c^'9WgA_-.]`!<[])M^<^km]Dq>^KfWe6):rVlg*^km]DdJX%CeX;,a
+h#.0TIr3rpV#>-6UtaX@J*lsa!La#frrhAGJWnsirs%e^JV0uqqYgEqn?B\,rsdk^L6g6bs7O?m
+JsOaZr;QfVJ,]HNqlk^.])M^5or<Y"\GcC+)?#Eho^D&)h:QCBX/C8>9hS&oNJg.uO+Mo]IfOrs
+Ii!ZfKSG;@NffQnD7ZL?X0B"BH7#!'db=EL!mG"gqqD1`9n3-A!rg*Urr30#eX;&F])M^Ior<Y"
+\GcI-l_&f]WqHDlor<Y"\GcI-h4=Op+Iq6es50Z-QI5X1qTkI]TA';Es50Z-K<"bIs80$QLV!B_
+!!*#Qr,)Gf!W`8fpY-@m9n33Cn[j[9\aKLtou3#EQE'WUrrh;1s8UCAIfSm7rrM).rVm&:V1t;`
+r;Q]trkl\Qrrq;VL6g6brr3'!_o2EO!!*#Qr,)Gf!<E.ogB+t1s8LaXd:lHb@9#Reh:i"0U!rtp
+"i,e$>ZCe'@fj6[1?R<m\kR\QrrW2;`;]c[rRI<iT\TSIqTl0oLUd<_s6H>/K<"VEs7NCELUd<_
+s1J;[!4r10*8dTIQI5X1qTkI]TA';Es50Z-QI5X1rRI<iLV!B_!!*#Qr,)Gf!<E/ngCq.mJ,fQ=
+]8DKVmf3=[`K5\;chdV?!q>/urVmDDM1_i(s8VDZK8$>ss8Tb1IfR(YrrW2;`;]cHou3#EQI#F-
+s50Z-QI5X/rrIUdrnI?frn@GRs7"bDRSA;~>
+ZMt*ZUgmn4!<-I0\\U#`ecKV9>5i"4HaV8P!i2F6o@<u=F34.,!L*T]rr@iQruq9EK86,Ts8VuB
+QA)!es8V`1OF`_Dqu?Q>QA)!es8UrhrI4gXrr3ABLP)Q&s8VhlK87#9rsZ`!K;d2rs8CN;KqR6!
+rrdgef%-MmCB^B^en]d#p=98/!<3!$ifnqWhZ!NZlC`WZW;$2frrV\p^]+6Bi1u'mdJa+;`K5Y:
+chmY?!TJV.rri5(K87#:rri(pK87#7s#5`1o^D&)h:QCAVk\H191h`iMMFMmNIQA)I!g9gI!pHn
+JV/Z3MiEj`BtBq3Vl[/2G9rHoc.2O=!m+baqpkhV8q6d=s24j9"o[#@K87#:rri(pK87#:rs\1c
+ItO]os8VhlK87#:rrLuJrdPKLh#IE4UkP,^rVuc@QA)!err3DbUkOH"qu?]nZ%IhBqu6Wrrmq!_
+rmh,Ns6B@0'=CG^s8VT#M2Ae2s8V`1OF`^rp\b$oid_".c22tjmf!.did^q,"i7!gQI5[0s8U"8
+rrq>VKpL-brVuo8qYpNqrmq!_rmh)Ms.\'G[E8IJed'</:0Lt%6(m&b!i2F6rRM.cK4A(_!<-I0
+\\U#_ecN6OJ,K?H_uBZFrRREkT\TSIqp23nLUmEa%-jL8K;ePEs7`IELUmEa!58>\!4i+/%,dq8
+QI5[2qp1R^T\TPH%,dq8QI5[2rRREkLUm<^!!*#Lr+l;_!<E/nee>G`J,fQ<]8;BTmf3=Z`K5Y:
+chm\@!q>3!rVmDELP)Q&s8VAWK7g,os8Te2IfR%Ws8U"9rsn\?OF`_Dqu?]SUkP,^rVc`sIr#&7
+r+l;_!<E/hecD"-J,~>
+ZMt*bg=Fi_!<1ONhU\Lch?%V!`W"Ehf\Fm2!cqnuoA0Oi#f65k!Ls/hrr`#HU^6r!,-aa]Dd8.[
+s3#OqF^g9gs1;`JF's.8s3#OqF^g9gs0?5srbE[^s8U&AF*C6]s8SHaGB6[$s8U&AF*C6)f`0TP
+??'5,jSf)ZIrG)<!cNSVp>,h?!<3!$DcV'cB)_f7G><4#:7TT.rtP:62h1l-ifIbp@"$]-]4,/h
+@!0`nrr`)gDZKe:'<t/NDbA.Os-Q].F&L!Ws7b*?$Msc.R#^:jkND'nl2KrLWO2?lm/H>MlMp)W
+]Dq'VjlOo_=kDWjht>h-c!G>ch?gkjJ,fQGk.OfJrr5L@I9pu59$.,5Qr8-L;T8\9G><4#:7V@a
+Qr8-L;T8\9Z;=G7CQ@'IifIbp@"$]-bB7?<@Z07GifIbpG=o.?s051;DbA.Lrr<&mh?!]Wme>QO
+]hX(Ws0lHMBje7Hs1;`JF'qb5rVm&mDZKh;ao,uV4X'7mrrVe1!<3!,`EHkr@"$]-qrYRmKDtlZ
+ifIbp@"$]-qrYRmKDPTJ!;>7M!<8eM!klkYrn[m=0q?A6[8&a<h?%b/ci)](gt:2s[/g3W!oDM(
+k2$EX:4N<DqrYRmKDtlpfR7(G>`%PAbB6^,F&L!Ws*%4ZF&&8*s-Q].F&L!Ws(4:jCE]t_s5K,P
+F^TXMs3#OqF^g9gs5K,PF^TXMs4Da+EGnIkr;Q`sp>,fMs7Y:_]hX(Ws0lHMBje7Hs1;`JF's.8
+rr3)rZ#9XArt34RF*C6]s8RFLGB6fLs8Q[krbDbDs8ViU]iKdbrslYM?uo^uc2ZdbAp%L0f_tgN
+IrG&;!<E/hh>s-AJ,~>
+ZMt*_f?r!Q!<1@Ig!cVWgB)4q_Z%p`e(E(&!c__oo@j=d#ep#e!La#frr`#HU'gl!,-jg\DdA7]
+s3#RtF^p<erju]MFCB:8s3#RtF^p<es0H>trbE[]s8U)AF`g?]s8SHdGB6[!s8U)AF`g?*fDjKP
+?>s2-jSf)ZIr4r7!c<GSp=fV:!<3!.EE.9gC&S)1Gu&R(:R]N,rtP:52Lkc,if@_p@"$Z+]4>Am
+@<B`mrr`)gD#jS8/@%lfDbA1Ps-Qf1F&KmTs7b*=$23lRjPJP;AlY_&Ssbk,Nf/[H5Y?i[H?oF5
+(jUFTIXcs'Ll7:VBsXD*VQ6FQ8[ZIWcIDRB!mG"gqqDFg9n33CqrYOlK`;!AfR@.HDbA1Ps-Qf1
+F&KmTrHV1]F&/8)s-Qf1F&KmTs0GL!CMSp]s5K)PF^TXLs3#RtF^p<es5K)PF`g?]s8TAsEGnIl
+r;Q`sp=fWKs6]R8'=pnfs8TT=B51n^rr0N?@WZ$SRf36io5+L-s2b.S!^%[orr3&kD#jS8%)uF_
+F^TXLs81rk<eUJP%-!=\F^TXLs81rk<eU>L!!)`I!<E.ogB+t1s8LaYN%g^?ca6D+g"tHbEF[5k
+gBH9[dDE6jrm:f#e"GjX$+`i\s8VuY]N0^bs!$*E?>s2-jT!DH<HiL^_Z0R[:N^_SRfEDT<HiL^
+_Z0XK3<!\:YlFa_O(WTCIFnMBG%Pl,MW"NoO(WTCIFnMOIU6u39$7)3!!)`I!<E/ngCq.mJ,fPY
+@qTOcZi9s9A7BXhFNjaa"8T0<!<3!1``[G,9<eHpHX1i<=-WabB/om+)6j/@pZB+hK`D)O]4>Am
+@<B`nif@_p@"$Z*rrIUdp=fTJs7"bDRSA;~>
+ZMt*Zda$.C!<17Ff$9fKecKVh^])LZd+$Io!cMPio@<t]#efr_!L*T`rr`#HU^6r!,-aa]Dd8.[
+s3#OqF^g9gs1;`JF's.8s3#OqF^g9gs0?5srbE[^s8U&AF*C6]s8SHaGB6[$s8U&AF*C6)f`0TP
+??'5,jSf)ZIr"f0!c*;Np=98/!<3!$DcV'cB)_f7G><4#:7TT.rtP:62h1l-ifIbp@"$]-]4,/h
+@!0`nrr`)gDZKe:/?qfgDbA.Os-Q].F&L!Ws7b*?#PRZPjPJP;AlGFqR[0+sMhct;5>$ZUG]s"-
+(j:.LH[UBqKnkSHA[@hsU8OSD8?oqJajBb4!m+baqpl(]8q6m@qrYRmKDtm@fR7(IDbA.Os-Q].
+F&L!Ws*%4ZF&&8*s-Q].F&L!Ws0>I!CMSs_s5K,PF^TXMs3#OqF^g9gs5K,PFa$H_s8T>rF)O[m
+r;Q`sp=99Fs6B@0'=CG^s8TQ;B5(bZs8T]??uo^NSGiHko5=X/s2k4T!^.^prr3&kDZKe:%)lC^
+F^TXMs81rl<eLDO%-!@\F^TXMs81rl<eL8K!!)`D!<E.oecN8$s8LRSLFnb,ag"T$h:;XG@`eT"
+"k:oE^Tde<c2uSBSEAB/[7YrKs81rl<eLDO,1q<MEEn@]s3#O_GB6[$s8R:<F)t*Hs8SHaGB6[$
+s8Q[krbE[^s8V)?Ap%L0f`0-;A9D@>irA#"Ap%L0f`0TP??'mUao)/=!;=tE!<;cD'=CG^s8TQ;
+B5(bZs8T]??uo^uc2R_Fq6=i<rr3SL>'"m[Z2aiN>'G$gPlLbq3W<e!Z2ajuk.OfJrr3J?@UO7b
+Fj9sGOCiWCIG"Mu!InnYec>dNnC@W)8q6~>
+ZN'm[!PJL3h@.YIhVN1PHZ,R^GAj/Rh?McILNA*UgAKe/DdL]ch?p-ERZk_4R!WaqXT%&^Dle;(
+TWr]ZT`3dOg735*Ph,Ze*m:'tFdC(L4Yr5Fad@3lOi?26VNdO5P<AnX^#%"PqVD7C!<3!#ieUJ4
+rVn')GOFUd?Ej<c@*.iCCTR/T=Ng3I=H`Q?@*.iCCTRQ-4co[.+nu$:<dX-'PaMLF+e\GlHWpIL
+<dX-'Pa9MmSm&GbTO+l$rrIUfpYGsiJ+!<m"M'##Ha3S,':](&s76Z4pVdF0s6:#goBqP`P5bIq
+a_N#Ks8T*5ZgP_sbOg-`bOE2IP5bI`aco'krr3WpGOFTs@fQ0GT_%Gq>6"W^Lf+KSs%SrEk3(pk
+l07Kulg([^p$M.na3;*'b2_mVfXIugd-Bo\^&R9Yk+!W+MPJnai-)Y`DgT%OhSYIuGE#@9hUS3p
+hVPq@J,fQ<[;@@Brr5K[>-dSY>%7O++e\GlHWpI7%&EL_N$\Mu+e\GlHWpILSn>\$lL=]NWbJg-
+_j8LCN*scqZYQZBWbJg-o9>XBs#kSok#u6lrr<&mhB2gumbZgDS9K+Aa55[d:4N<>Iq79iApsLI
+HW\J\]o499rrnWQ!<<)rrosR=:72"[!gGtNrr3C-HaE.XQHT<t[;@@Brr3D,Bs[6FQHT<t[;@@B
+qYpNqp>,fMs8LjaDn1L=Hb&"ibFEd!QH->g!klkYrn[Z-KDjX0[:e@@DuST:c#;IqDn14rhJ]rO
+PJu=hLNA*Ug>8]kSp>IIbH*i_Oj3d[!mSCYrS@t-Dr0>hXF"lYZ$1,Zrn\FES9&b9f&#96Su1B$
+]hX(Ws7!F5.=_?s,+_uDlC_Ifqi"pUoBL[+s6:#goBqP`s7[\0oBL[+s8P6Drot[$s8T*5ZgP_s
+bPR6+amQKNXT,;7ZgP_sbQ"/;ZKgRU@f66+!;>7M!<<&T)nCH:Ha1WJhRu[6s7q.Tg>6Fiq=K#9
+bOE2IP5bI`a_O0Brr3R2Hg:3eR/cRc[I`gR+ohR*OT+M_p](9Q[;@@Bs8V_<=Ng3I=H`]aBs[6F
+QHT7,!Io%]h>mWVrn\0(\V"gI\_c2RIrB\=hOI>k~>
+ZN'mX!PSR4gC2;CgY6SHH#K@YF`3lNgBQ??KlVaMfDOA)D-tNagBsa>R#o/(Q[<RnW;bNWD6/#$
+TWWEUT)RIJf9gW!P106]*lj[kF-X_E4>W)A`g:dfO29T*Ulq+,O?<MU]%bGGqV)%>!<3!#iJCD3
+rVoAOH0sdg@']Zg@EIuECT[2S=j-?K=d&Z@@EIuECT[W/5`b0qlh1;X=*a-%Pa_XH,,"PnHX$OM
+=*a-%PaBVoSm/PdTjY2)rrIUdpY,adJ*m6i"LNSoH*I;&17A4Cs76`5pV[F-s5slfoC%VbP5kR]
+aD2rKs8T-5ZL5Srbk$-`bON8KP5kR]aHT!krr6XqH0sd!AcMKKT_%Jr>Q=`^M,43ClfI$We'2B#
+U7I[9OGo$MJq#pQJTZ$79Mmu9:MFlm@RWFLBSD;%B!%GlU2^r7?$s3%b%J,7DgAeGgVJtmG)f=7
+gXD^hgY9;6J,fQ<[;@=Arr5K[>I3_[>@mj/,,"PnHX$O5%]&^bN$eT!,,"PnHX$OMT4kn&lgXcN
+X(\g,_O&LDN+'isZYQ]CX(\g,nW]LBs#t_qk?DNqrr<&mgE6LrmG$C9R<<S9`S9.Y9n33=J7[Ei
+B70IFH<JG]]o4<;rs&Fd63.&cq>T[]fh@e4rr`4a63.#b$s._[m_Y=7s7!F5."D6r%'+'Im_Y=7
+s7!F5."D*n!!)`I!<E0!gC8#0K5Z%DgY9c:F`WheZeGPmbl@[s!A&ZtgB=`lg!"=4gEFdXgY6SR
+H)TJ7[X!tNfscZUJ[3n^Um%BqFI:.L4>W)AqqD1r^&\,d%*WSCgMO$;DkO7UDk?s_(>"ppEK\f*
+gXD^hgY9;6J,fQ<[;@=Arr5K[>I3Ug@']Zg@A*5XHX$O5%]&^bN$eT!,,"PnHX$OM5`b0qlh1;X
+X(\g,_O&LDN+'isZYQ]CX(\g,_O&LHSm/Pdk?DNqrr<&mgAq<SrnAX(I;O86`S9.Y9n33=J7[Ei
+B70IFH<JG]]igNus8L)T63.#b/m!>anW]LBm1?_tn!5*rs$2Y0lg+6Ds5CA&."D9so6OQ_n\&(g
+s/Th=m_Y=7rVlnJD>)]b!<<&Q%rJh/DgAeGgU)BGH*H%l9n3~>
+ZN'mS!PJL3edTZ9f%+W8GAE_IF).<FecsX1JT$%AdeqYtCL5-[edA(3QArSoP':\_V#JpNCT)Gm
+S>^LESGq(CdZeZgOO![Q*lF4^Dihf44#;l8_3/eVMnR]mTTGJ!NB7,P[FWH8qUP\3!<3!#ieUJ4
+rVn')GOFUd?Ej<c@*.iCCTR/T=Ng3I=H`Q?@*.iCCTRQ-4co[.+nu$:<dX-'PaMLF+e\GlHWpIL
+<dX-'Pa9MmSm&GbTO+l$rrIUbpXTC]J*R$a"L3/dF05Gm'9iLss76Z4pVdF0s6:#goBqP`P5bIq
+a_N#Ks8T*5ZgP_sbOg-`bOE2IP5bI`aco'krr6XpGOFTs@fQ0GT_%Gq>6"W^Lf"0ClfI$We'2B"
+Ssbk+N/<:@Isa@JIr]O.92@Z2:1nQe?pZtBB7bkp@]boaSo,<.>^Nio`auH*CNm2;f"I&_F,Ne/
+f$BeXf%.6$J,fQ<[;@@Brr5K[>-dSY>%7O++e\GlHWpI7%&EL_N$\Mu+e\GlHWpILSn>\$lL=]N
+WbJg-_j8LCN*scqZYQZBWbJg-o9>XBs#kSok#u6lrr<&mefXtmlIOP(P]:W'_:I2F8q6m:Iq79i
+ApsLIHW\J\]o499rrnWQ!<<)rrosR=:72"[!gGtNrr3C-HaE.XQHT<t[;@@Brr3D,Bs[6FQHT<t
+[;@@BqYpNqp=96Es8LRYCUJY-GI?#Q_j#.ZOMS9S!k$/Mrmh*%Hi;LuZ!u;+C];m.a_TJYCUJA^
+en_[;NP3iJJT$%Adak(QRWWV9`MP^QNQ(eG!m/+UrRMD!CY%'PW-<$IW,laErmhk5P](K%cIURm
+R\86_[7YrKs7!F5.=_?s,+_uDlC_Ifqi"pUoBL[+s6:#goBqP`s7[\0oBL[+s8P6Drot[$s8T*5
+ZgP_sbPR6+amQKNXT,;7ZgP_sbQ"/;ZKgRU@f66+!;=tE!<<&L)mOU&F03:0f!S,"s7q.Tg>6Fi
+q=K#9bOE2IP5bI`a_O0Brr3R2Hg:3eR/cRc[I`gR+ohR*OT+M_p](9Q[;@@Bs8V_<=Ng3I=H`]a
+Bs[6FQHT7,!InnYec>dNrmhTq[=;t9[FWp6GAD9%es&dW~>
+ZN'm[!PJL3hA3d)hVJ6EG>9l*F&"I@hVPea>\@#FYl*>ZDd:E`g*5>/hJY,TJ%^k.4_n4af&#6`
+Ap7!)B6-g&f&#8J;J0W.KDOFHg5o3A@SVr`4Yr5BN^6WR9SqK[D_YRJO$*JT^#$jtqVD7C!<3!#
+lEQiZrr5O\#ho=YfOg-9Fa*T[ibaPCWjDU&g16'5Fa*T[ibaPPM\pA^J#N,ApCO<ZK:LZqlN$DR
+s2GcQpCO<ZK:KR?q0d8Ls4CqCrVlnJ?MD-7?@VD"hUY;&CKa'YhVOb&s8V\?qu>(QoDdrkp](9$
+'T)kihLg#MJ,fCu>aU5,]Bo*gZhsdVA;U?dhLeFr!<<)j#ho=YYoNf0!:Tsf`YAIQlEQlfqYti3
+LX4>qe(*%$f\+uV]Ct[\\!sn=Xea/,lCk,YUQas.lG*A_g/gFWLP'!!iSY;aGAfcBhPbQk?tE@a
+Dr/rsOP\j-:4N<DoZa7.J,fQEI<"WRs03RDlN$DRs2GcQk&:"os0WR@lN$DRs2GcQs,06gJ!A:V
+q]:ApR"^X6m.GLFp]'5iM>Mp1R"^0_gAgaMgAh2X*;og:!;=)K!<;KDg5o3A@SVs=hRu[6s7s4=
+rTJ0Lq=:Plqu>BX'`S+7]h5(#qu6_UBD;E*,J?^F!<<)n&?2%NOLslZoZa7.J,fQGK3XdtOLslZ
+oZa7.J,90F!;=),!<<&T%KL*bDa@.Tg5o3A@SVs=[,)&$c2ZYWdKIPeh?23_]`A&g+h[m4h>h"g
+Utu)\>(=B!F'N?W@^+^-1N.>:8!^5>1QfrZh?(s8!<(bo]`?pG!+pFM0kYQ&1"P4<PYu.,6%e%N
+dtNn?hRu[6s8V`9VG;X@s7q(_m/P^MNV.F<n,NF-'`[<6p](9$'`[J!n,NF-'`\1MDh!88p](,C
+>aU5,]Bo35GPD-sD2J.B>aU5,]Bo?AEU<`*YoN]A!!)`+=TJKYhUY;&CKa&bgto_>J,f>T^&@/5
+J,/Z8ZhsdVA;U?dhLg$J!<<)n&?1G;SD+#2&A@u8S/hS/(iOnRW;$>llHQ2$J,fQ>WjDU&g16';
+K3XdtOLslXrrIUUp:UJ,s8Ljc!+pFn5u-:f8m6"66J@r)J,~>
+ZN'mX!PSR4gD7L'gY2^@F\so,EDJ:9gY9/U>@g]BYPd,VD-Y-\f-8o&gMJTLICbD)5\F:^dG*CU
+B6@',B5p^$dG*E=:M40(KDO=EfT&g<@8;cZ4>W)>NC$TQ8qkjND(f1CN'%)Q]%b4lqV)%>!<3!#
+l*?`Xrr5O\#h]1Wf4^6<Fa!KYibj\FWNl="fk-08Fa!KYibj\SN#H\aJZAJEpCO3YK:^itlN$>P
+s2>iTpCO3YK:]aCq0d5Js4:qFrVlnJ?2(pT?%;7rgXSeuBj!gRgY8.ss8V\?qu+kMn,MKdp&G'!
+(lSFogjsWHJ,fCu>F:/,]^>9hZ24LRArH]hgjr%m!<<)j#h]1WYTWu3!:Bgd`>JXTl*?TTmcWQ`
+eBZ-D7"p2?H$47ICh[K:6[EWe2&J20.O.N$CjmW`3&)b-KSO$8P`IpQ2c3C1E5BQp@<ZQT:YVah
+:LRg8-#MD`KTFmB\kR\Ss7FR59n33Cq0d5Js8T;Gs6B[Ps8U%Ts5e+js8TGCs6B[Ps8U%Ts8S$H
+GCPn)qtl"MR"g^8mIbUFpAa,iMu/-2R"g6bg]-jNf`1uU+T26>!;<uH!<;H@fT&g<@8;d6gU^+/
+s7s4=r8qmFp[Y;gqZ#6U)#jO;\k/[tqu6_UAbH'&,J$IB!<<)n&>khLOM'u\oZa7-J,fQGK3O^t
+OM'u\oZa7-J,90F!;<u)!<<&Q%KL'aD*h%QfT&g<@8;d6[+bhsbl?GPcNM&^gB?3UgV*[egEF92
+gY2^8>G0^N?X%rl[W#G^;IcobD)-!L=@e^W4>W)AqqD1r^&\,dEP;G-gAkl/;)2d(:GC2NgQG?F
+@mYh&gX(V7gY9;6J,fQ@c)+3bs8VnCE9mPUBTMh/G4#>0`>JX:D>!r/Zl&i/!:Bgd`>JXT)KC1V
+WqZPjK3O^tOM'uRFa!KYibj\OK3O^tOM'uVI;nNPs0*XDrr<&m\lf%5gY:7K>A75-N7cmr9n33=
+\\7q'DLM9MWNl="fk-0Bs4i0KU]CGppCO3YK:^itm1?r+pR30'ru,m*JZAJEs67e*9n33Cnu8nj
+s4M"Bqh&+?L60(8rVlnJ?1ti1!<<&Q%fg0bD*h%QeONhX=[U`.9n3~>
+ZN'mS!PJL3eeYq!f%'h1F&"H!Db;b0f%.0G=CP09Wr1ELCKeXTdN[2lenZpDHaSYo4_IeUcIUPH
+@WP:!@W+jncIUR.:1@ZuJ,7_<e;R./?;-6P4#;l4Ld+dD7t]7@CG/q>M)t]L[FW;`qUP\3!<3!#
+lEQiZrr5O\#ho=YfOg-9Fa*T[ibaPCWjDU&g16'5Fa*T[ibaPPM\pA^J#N,ApCO<ZK:LZqlN$DR
+s2GcQpCO<ZK:KR?q0d8Ls4CqCrVlnJ>5,F'>(>hgf$[#gB3%@If%-&cs8V\?qu>(QoDdrkp](9$
+'T)kihLg#MJ,fCu>aU5,]Bo*gZhsdVA;U?dhLeFr!<<)j#ho=YYoNf0!:Tsf`YAIQI-Ru(!:K%/
+gXONi@7#NoH?O=JCh[Kl0LL,%CGZka2(9_?C25(H2_QJ'JV7@.Oc2=H2GHt*D7m^c??9mJ:=c4^
+9jV4,,\tuUK8eC4[7YrKs7FR5:4N<Dq0d8Ls8T>Ds6B[Rs8U(Qs5n7os8TJ@s6B[Rs8U(Qs8OF(
+6[+$EchmTl>aU5,]Bo35GPD-sD2J.B>aU4tSD+#7#ho=YYoN]A!!)`#+9;H,f$oXR?=$<_eCM$"
+J,f>T^&@/5J,/Z8ZhsdV[1rW?"2.=&!;lctMeDe`s!,3LU]CGppCO<kKoiq5s7FR5:4N<Dqh&.@
+Koiq5s7FR5:4N-?!!)`#!<E0!ed_[hF)+':f$oXR?=$<_e?md3[E8I"f#\'.r71tlf"D(_efh^,
+f%'h->+F.D?<V]dZYrrT;IHNUCGBRB<_&=M4#;l8qpkhj]`A#^EP2A'ec90#:,-3r8hnWBerWX9
+@R5Lpf$/i+f%.6$J,fQ@c)+6cs8VnCEU<_XArZJ+GOPS3`YAI8Dtj;3[1rZ,!:Tsf`YAIQ(iOnR
+W;$>hK3XdtOLslPFa*T[ibaPLK3XdtOLslTI<"WRs03RArr<&m[93M0f%/8=<bGH"MU^4b8q6m:
+\\7t*Dh%TRWjDU&g16'?s5&BPU]CGppCO<ZK:LZqmL[)/pRE6'rto[(J#N,As6@k+:4N<DnuB%n
+s4V"?qh&.@Koiq5rVlnJ>5#?)!<<&L%fg'[CI(_HdRI8M<^P6!8q6~>
+ZN'm[!PJL3hA<j*hVJ6bg:[K9g:[L*hV<ZcYL9@EH.r5R.;peICMRjehVN0,Oic1CI@T#n!6*gO
+!/'"=!.W_9!6*gK.?)^'IiR&:hB1<]8@-F&U>0Znc.\V7]>IZYdGAdtOic<q!577Gg9LM2!Ls/f
+rrLsVrr5OK!;lfrl>;+JKjMsj[6K0>o_/19Me]s$KjMsj[6K0<M&^;\Dag?!joB=DF%W8.o,+:p
+l@/g6joB=DF%UZ(n8WmTs6=HPrVlnJB(sO\Aq07*hTc+_f"GkQhVOb&r;Sm/;I]\+qsOLY]iocr
+s6Ptq_/Fi'noHa2F^B:>rUfg\g5B^Zs6PtqUtu+Os5F%Us8UXQs77)'oBLf*rVloU&,Q;qT9.ja
+hV[8MioB([YeTo#n%>FEmGG"YlfWl?l.iH,lg)Ffkt%.OWSH6o5MP-3G1,63"PuR?LWR_t.rX;"
+`Q-il]hX(Us%Vp"J,fQ<EIIfcs4.>Qo,+:pl@/g6qsOLY]iod_o,+:pl@/g6pPD7[G?T(6noHa2
+F^B:>q1W.um^59/noHa2F`U0Ns5F%Us8UXQr;Q`sp<=*Js6eapB1TANPbQsi]hX(UrtE.]>-S&*
+o_/19MctK-s4U5Dh>mKR!n'*[rr3J^:8H_Hs8V3]Df^&-GL?Ei%.8%`s8VY22fj+JGL?Ei!q'uV
+qYpNqp<<U<s8Ljb!,p<BPQ]joB1TANPbQs?h?Ua=s5)VP!7q#'!PJL4hB9K3hVJ6E^"2$?B"c==
+JQf8*W(qWlD`=?A\P.#"DdL]bh?(s8!<(ar]`?pG!/'"=!.W_9!6*gK.?)^'IiR%rgr7=jhRu[6
+rVoU[Dh%fen8WmTs6=HPq1W.NoBLf*s826apUsaWs77)'oBLf*s7[LKIr@cKs714iF*1f5dJ8K&
+bO2c&J+@Y>F*1f5dI;.(rVuoK"T89"!;=YJ!<:p4c2`sW]ka@thRu[6rVnF`Bj.b@rUfg\g5B^Z
+s6Ptq_;51ls5j<"GB6BPs8R"(HZq?*s7[LKIr@cKrVmT"Dh%ferUfg\g5B^ZnoHa2F^B:>rVlnJ
+B(jIM!<<&T%fgOrhNS0"c2`sW]kc>l:4N~>
+ZN'mX!PSR4gD@R(gY2^Zf=V*5f=Ct!gY%'ZXNdP8H.`)M.;^VEBk_F]gY6R#ON5h;I%8`e!5dLF
+!.ib7!.WV3!5dLB.#Q?pI3-r9gE4sZ8[69uT@e!fbh&50\A)$PcJ*1kON5si!5@4BeZeo)!La#d
+rrLjSrr5OL!;ZZpl"ktIKjW'm[6T9@o_/18MJBj#KjW'm[6T9=M&pM^ECci(k5]FGF%`>/o,+@r
+l[K!9k5]FGF%^`)nSrsSs64?OrVlnJB(sL[Aq04&gWoq_e%08DgY8.srVo%ZI8aSQs823`pUjXU
+^&RG`GeS$Es7::jFEV#8dJ`_2qq6jA^&RG`GbWpms8V*Zq>^KD#6493VXs,'!ri3rrR:i4j5&;5
+b/@UXNerI@I<fsTDJM'nFD,;B(e7t3+u<b>!(^p83Hoq(?D<K5@iT*QTk,+O_Z48jfolWp6qW3T
+ab_KagXsB^gY9;6J,TCAm;7@Qs7()Vr;ZfG#6493VXs,'!rr/bs7a0/HiN[SVXs,'!rqqM7<Nf[
+FjT`$2fs4MGL?5??d.uH5_/HI2fs4a9;MUJ!;ZZpdg#aM!!)`:%flXsgXTt/Z,Vs!f\<u3J,]H^
+rk2uKYQ"LmpA<O#=aU2Kg.nBs!;uiucoT\UrsmaXU>#\Js5sB#FEV#8dJj.Sm;7@Qs7::jFEV#8
+dJj.Im;7@Lrr<&mbQ._Drn@n_CX:[t#2@[A8[69uT@gO*#J/.ZgY9UGe,%f"^&\/e+MIj1gAkft
+e(Xk6]Z8QP=fflD9mPB.24`7*9Q8a'?d/B$!mJ@YrS&F.!8H6.J_.O7J(M73_V<ZjMU0Lp*nB#t
+_St9a\kR\Qs%VltJ,fQ=EI@]al"ktIKjU_Kl[K!9qsFFX]NKU]o,+@rl[K!9oc@suECci(o5cj4
+G$fI@q1W2"n$PE2o5cj4G$fI@nSrsSs8UOPr;Q`sp<4$Is4c;S!g(mBBqO&4\kR\Rs"45`BNhV=
+rUfg\fnsOXs6Ptp^=rYfs5sB#H#lWSs8?e#H$;*'s7IFMI;qfPrVmT!D1DTcrUfg\fnsOXo5cj4
+G$fI@rVlnJB(jFL!<<&Q%fgCkfolWpcN93W\nT]`9n3~>
+ZN'mS!PJL3eec""f%'hJd^]@)d^9(kf$o+MW6(c,Fjg6>.;LG?B4l"Sf%+UkNPj&+H'm$U!5[7;
+!.3/)!.3/%!5[77.>Z*fHQ:?.efW7M8?]pmSCD=\ajQE![C]=EbLUG`NPj1[!56t7d]NAs!L*T^
+rrLsVrr5OK!;lfrl>;+JKjMsj[6K0>o_/19Me]s$KjMsj[6K0<M&^;\Dag?!joB=DF%W8.o,+:p
+l@/g6joB=DF%UZ(n8WmTs6=HPrVlnJAG=1VA:Nmqf#duScFIT9f%-&cr;Sm/;I]\+qsOLY]iocr
+s6Ptq_/Fi'noHa2F^B:>rUfg\g5B^Zs6PtqUtu+Os5F%Us8UXQs77)'oBLf*rr5gnf)Y*rh:Brq
+`*PunLP()'GB7\=BeqtoAn3V47:&h711=Pj882KlFaJUBU5U[3*G(\3A/DPd!+<dsO9F-'8V=pu
+KdgfgeA&iNf!S,"rVoU[Dh%fen8WmTs8UXQs77)'oBLf*s826apUsaWs77)'oBLf*s7_@;Fa%#1
+cgl-9F*1f5dJ8K&bO2c&J+@Y>F*2OrV#TESqu?]I"T89"!;=MF!<;?8ct,bO_iUD<f!S,"rVmPG
+Bj.b@rUfg\g5B-]s8UeJUtu+LrrUV/f)G[Zg.nI#!<<)]!,lq$??afrrs\=6J,fQ>F#S/_??afr
+rrVV,J,90F!;=M8!<<&L%KL+_erU$cct,bO_iUD<[+5JiaoBrC]`?@SecEGarmi4*!7o^$@_'e8
+!+NLVd!]#paeDFNdVCY+ca-5\en\U6qUP_i]`A#^+2%[*ec:'F\H%!)[/e%odOC!oaa5#Qf$qIN
+f%.6$J,TCAmVdUTs6t#VrVu/"Jbb"+V"<l$!<;ras7a31HiN[SV"<l$!<;d5CO^7kT`=S(2fj+J
+GL?5??H_cE5C`6F2fj+JGL>o"IJs3GecbpN!!)`7%flX\f#duScFISXeCM$"J,TBu^M-lUs8DT`
+qq?sC^&RG`H,8>;s8V3]Dg-7pV#UI56@3o6MuWMkCO^7kT`+m)mVdUTs8DT`qq?sC^%-5'F*1f5
+dJa(GIq88p!<E0!edhamajuOVf#duScFIT9PY-H~>
+ZN'm[!PJL3hA<j*hVJ7ChVJ7ChVJ7GhUZ<qCN!oA@aY/2.;pkODf9]shVN0O`STIhP^e=8!577G
+!4gtC!4gtC!5777!,$4g@fXLFhAb15>]"n^bMI/Dc/-@&JUp$lc/*A>`STHi!58*_!Ls/frrLsV
+rr5OO!;lfrl>;+P_eNS%C,:MBs5^&(HaWGE_eNS%C,:M>a-b<TmXHhgiW,Y>mYEUts+a?jG?tRT
+iW,Y>mYG,8noK6Xs6=HPrVlnJGPCM4GCT&;hUYS;F,.=*h>s,Hr;QkK;Hitss#%oNF+`WGq5S5<
+k\YbHn8V:Fm^l_ks8V/WH[E0kq5S5<pY#WEs5j=Ys8UXQs8RjLF*CprrVloU'Dh_2U7_&Krq-3_
+s7S1[_Y<Qh^piLsl+4[um&me._V4DDm)8qhkhSpoP)k2Gc/KVLhql$Hh@*T*hVQ.LDu8Am]hX(U
+rtOm>J,fQ>F++#es4.>Qs+a?jG?tRSs#%oNF+`WTs+a?jG?tRTpW']*p:"(gn8V:Fm^l_ks2/SZ
+F_W^bn8V:Fmd>lcs5j=Ys8UXQr;Q`sp?iFks6eatP[&'RTZc3K]hX(UrtN4^<iZ,us5^&(H\:J\
+o3ue8g&V$KrrHVVrr3N#@WV:t!;lfU!2.C#]3La&rs\=6J,fQ<EDX^D]3La&rrVV,J,90F!;>g]
+!<<&T%03ZihRrpGg6>iZIA"cih?Ua=s5)V\"Mt&n"PSLI]`A&g"haomh>jYVhA60nhVQgr1M^oC
+0k/OK=NB:C?>n\=?Hr?'!mSCYrSA='!8cQ4\_c0C\_c0C^#%$7B5_]u!6+il!kh?YrVmT"Dh%fe
+noK6Xs6=HPs2/SHF*Cprrr4jtK6)\-s8RjLF*Cprs7_o/s6b@gs6t#)a6pQER/b'=@!-3?KCEkW
+a6pQER.><HrVuoK"T89"!;>gk!<:p4el$.%LUkUbhRu[6rVnF`Bi_84s8V/WH[E0kq5S5<kh6%6
+s5F$Omd>lcs8QgsHZq3&s7_o/s6b@grVlreDh%`c%HOC5HaWG6EDX^D]3La%rrIUnp?hq]s8Ljc
+!3tD;]`?p?;J1'+\_`iOJ,~>
+ZN'mX!PSR4gD@R(gY2_<gY2_<gY2_BgXB^hBl.H8@aG#-.;^_MD/F9kgY6RG_qWn[P(/%2!5@4B
+!4^e<!4^e<!5@42!+g"a?NA%AgDee0>\e\XaP1Q=bhBgpJ:BaibhHu8_qWp_!5A0]!La#drrLjS
+rr5ON!;ZZpl>;.Q_e`h,CGLPBs5^))HF*2B_e`h,CGLP=a-kBSmt!+ki;fV@mtNOrs+aHoH!L^U
+i;fV@mtP&5noB-Us6=HQrVlnJG5(A2G(8o6gXT56EJ:k#gB!`CrVm$!IoBSKrr4juK6)V*o(fA'
+ZfPtMqsSK$aR?]EQiI*HVgE`ro(fA'Zh)cKq>KCTq>^KF#64^Y;0@.i#laioqTo6)hq?H%`P5YU
+TUV7/N/*%7H?M;1Cgpd*,u\&L-neq8-8.8D??LOA>Fg\5M#^+F<(m:h^]:(Ug:RF?$s::!gV6X'
+qqD1`9n3-A'^]aes8VY1I/O$EeHZ'RLJ`2>>mUH029LPmJ`Zq3LJ`2>>mUK'a0t1)\6,'dE)F^F
+\m(O$_e`h,CGLP3E)F^FmtNOrjT,,Vs4%>Orr<&mm103smG$9X>\e\XaP5I\9n30B)udQc=0)<"
+s5^))H@b2Xo4<"7f)YXFs8W%+H2dgSo4<"7f)YXFi;fUnn%)_irr3DoD1DTcn8M7Gn%)_irr3&e
+D1DE^!!)`[!<E0!gC4.cgY9@@gXq`qCO;YoZeG_rbl?GPblki\gB?,\^qKgJgBG4igY2_0rnA4h
+XP;LYAMRt:AhRW>D-+[1b?f&?D-tN`gB,U5!<(Xf^&ZpB!4^e<!4^e<!5@42!+g"a?NA%AgB+r\
+J,TB]m;7@Qs712Xr;Z&!K)``);0@.i#lai]b(Fbdjo>@9;0@.i#ljRcdf&Wc0)tE[;984;>F5B-
+Ch%[)15#(8;984;>F4o$I/O$EeHYsO!!)`[%flXagXT56EJ:jBgY9;6J,]I"rk<)JX8W(ujJR?N
+Zh!pnCpW6T!;ZTP!2ArNL+rZ+CHd#d15l2*RF;'&JM-p$!psiSrVm>fVgE`ro'gTqaR?]EQi6pb
+Is1PQ!<E0!gCF:egY9@@gXT56EJ:jURSA;~>
+ZN'mS!PJL3eec""f%'i/f%'i/f%'i7f$.YYB5;$2?HN/s.;LSICMRjaf%+V9^XguLOF)J$!56t7
+!4CD/!4CD/!56t&!+Te[?3%\9ef3%t>&/DP_q&U0ak".eI="%^ajt6,^XgtO!58*W!L*T^rrLsV
+rr5OO!;lfrl>;+P_eNS%C,:MBs5^&(HaWGE_eNS%C,:M>a-b<TmXHhgiW,Y>mYEUts+a?jG?tRT
+iW,Y>mYG,8noK6Xs6=HPrVlnJFnb/.Far]-f$7$'DhG=oecD!8r;QkK;Hitss#%oNF+`WGq5S5<
+k\YbHn8V:Fm^l_ks8V/WH[E0kq5S5<pY#WEs5j=Ys8UXQs8RjLF*Cprrr5LbdfAOfg!\*`^Ka[.
+R?WbiKn4VsFZ;Hu?sPB0;-HsI/mV^-0Ju.#Ecub1SVN,W!(Tja9)tWs!1_9`\H(1h<kHr6]23;?
+ecN6OJ,TB]mVdUTs715ZrVuoK"TSLW:31Vc#lai]ab+Yek5YI::31Vc#ljY>[HR=n<gN5p:ri"9
+>aYQ/C1)1!1P>1::ri"lLb\ql!;lfrecbpN!!)`X%flXpf$]R^CO)Adf%.6$J,TB]^M-`KrVuoY
+VL*ZBk5Y$^F8+Agqu-Nq@se4T&+a7OpY#WEs5F$Oa6pQER/[*omVdUTs6t#)a6pQER/[*emVdUO
+rr<&ml2^nbrmhMYW7KP1!7oSY>&/DP_m@o![E8I"f#\'.rRM,"J%`Mqrmh7`!7o^$W;b?a!3"K"
+c!iD?CLf))a_Okjf#M$2en\U6qUP_i]`A#^(;0_!ec<,/ec<,/ec<D7`;jC`CL."SqpkhV8q6g>
+'^fmhs8VY2IJs32D1V`)C//ho?3pQ129CJlKBE46LJDo7?3pT*R*u$&IkC]iEDX^D]3La'_eNS%
+C,:M3EDX^D]3L`oF++#es4.>Nrr<&ml43mpf%/,AB5`F-_q*DH8q6g>/AGn"Wr;ttjJI9N[IX-n
+CUNB[!;lfU!2/cJLb\r0C-?of0oQ)+R*u$&IkCX!!q'uVrVm>fVL*Zto'gWqa6pQER/R$cIs(JM
+!<E0!edhbZf%.A3f$7$'DhG=GPY-H~>
+ZN'm[!PJL3hA<j*hVJ7GhVJ7GhVJ7GhUZ<sD/X9#Ph#`h!cMDiqq`H6?Hq?\OBQFPPQ8DRh>k7G
+h>k7Gh>k7Gc2_WuDeiP$qq`:I_46-q>*@TX?Hq2c>'Gls?Hq>F?Hq?`DZIKEh>s,Hr;QfS!<3!B
+pB]XUs4V.Gs6dR\KoK?%s4E6NRb%B9s6dR\KoK?%o%M@fs!#Gks76BZs8U4Ms8UrGIuBC;s76BZ
+s8U5WL&6@@mf2!SNW&kXIrG)<;/^sPhVQtcOEY;3f&#8R!<<)nV#UJC"RlBjZ"AKnp](9WD)H6Q
+2*IVfH[#/_jD0JLfSag>f),L2D)H6YCB/_#pB]XUs0WjHs5'8qMi]CdrrM!mqYr^SSE]>(lg4!*
+mdBPV`qT#n`4kR-lb:=,n(Gt$[\rEXm)K(jl/#7%Q'$rLe`%Rchql$Hh@*T*hVQ.LDu8Am]hX(U
+ru:BEJ,fQGIrk&Xs0WjHs5'8qMi]Cfs060c[J0\#0&E+JMi]Cfk1\tts5IaHq0R>Ys5[sLs6dR\
+KoK?%q0R>Ys8U4Ms7ZfUs8TJHr;Q`sp>.D%s6eb!_46-q>*@Ur]hX(Wqp!Ogk\GJ<s4E6NRb%65
+s3_0_HYWV.`W,th+l<4u&(1_nHYWV.`Ua5up&F)gL&V)\mVdUTs7q"cp&F)gL&V)RmVdUOrr<&m
+h>mWVrn\+b^#%VZ!8cMIS:b]_P1m;"!klkYrn[Z)Hi;e(YnXmb!<1gYYlNY;!58Bg(BD/*hUZ<s
+D/X9#Pgs\Yc/-]ODr,D=c2-8uc+O,UhA3d)hVJ7GhVJ7GhVJ7GhTc+:Df9Dpc26?!]hX(Uru:BE
+J,fQGIrk&Xg1ZKGm_,-?Mi]Cfs060c[J0\##i;)$Mi]Cfk0<o*,/t&kq0R>Ys5[sLs6dR\KoK?%
+q0R>Ys5[sLqgW\Ts8TJHr;Q`sp>.k2s5)VdWK;=9:6O>f]hX(Wqp!Ogk\GJ<s4E6NRb%B9k\W1q
+F)(c&`Ua5us8U4Ms76Z0qtHHts5qT*rrL+JrVlreDh%cd%bQ\\Rb%B9q0R>Ys5[sLrVlnJDt`#g
+!<<&T%fj<"hRrpGg8U0XAkppI:4N~>
+ZN'mX!PSR4gD@R(gY2_BgY2_BgY2_BgXB^iC2I`pOja3_!c;;gqqE61?H_*UO'?IPOoW5NgAntB
+gAntBgAntBb5c0lD/!.qqqE(C^7'Ui=ch6P?d./`>Bboq?d.8A?H_*XD#h<DgB!`Cr;QfP!<3!B
+oa9IRs4V7Ls6m[_LQ5Z)s4E<PRFV06s6m[_LQ5Z)o@hLhs!#Jns7$<Zs8U1Ls8UuJJW5a@s7$<Z
+s8U2UL&-:>mJkmUO8](ZIr4r7;f.$OgY:>WNceo-e(`WG!<<)lV#C>?#4;HjZ>"`qp&G'UDDc9N
+1d%DaH[,5`jD'DKfSss?eb]=0DDc9VB`NFsoa9IRs0a'Ms50E!NK>Xis%*+_c2ckYe]u7P]3.af
+MhZe1G]Re=B/2GY>?WR(:f^C>/6Q.H5;b)@CNF`&Q\LEQ!(fsa;Fmb!!3FJr^&Zmr=hreH^J\qG
+gB+r\J,TBdm;7@Qs8%4cmJm3p+TMK!Sq2l_.f]OSBmmG_rr4V.Sq2l_.f\\ck5YJAC52M1GkM*t
+C5)]V^5n&0?'P,2GkM+:aUJ4B$JYU\[NPMJ!!)`I/cbq=gY'<0JSePOfA!l2J,fAhd/N3DH1q9j
+NH:N<p&G'?$=S3o!-uN_s3r1Hrr3MW$=S3o!-uNQ#4(s^jD'DJrs\:3J,fQDH[,5`jD'DJrrVS)
+J,90F!;>.J!<<&Q%KO/rgV*[BftNo+D-;tP[+bhsbl?GPfd_FKgB=_r\@qtBgBF_[gY2_@rnA4h
+]\D2iAM\(<CLN@RD-kE?b[55AD-tN`gB,U5!<(Xf^&ZpB!5@4B!5@4B!5@42!,$.cBj&UUgB+r\
+J,TBdm;7@Qs8%4cmJkmUO8n[_Sq2l_.f]OSBmmG_rr38]Sq2l_.f\\Wrr41_%fc<NGkM*tC5)]V
+^5n&0?'P,2GkM*tC5)M6Ep`o,[NPMJ!!)`I3ro<8gXi<_F_+:/fA!l2J,fAhd/N3DH1q9jNH:N<
+qZ#bs2/R>I!-uNQ#4)<haUJ4<%_DK/QluFlcMmhE`t&(J!psiSrr3J\NH:N<qZ$>;GkM*tC5)Wd
+!Int[gAq<Srn@q`]\D2T!8H,&Nceo-e!a!]~>
+ZN'mS!PJL3eec""f%'i7f%'i7f%'i7f$.Y[BkqEhNm7OR!c),aqplm*>fYFFN`p4JMu^QBec<D7
+ec<D7ec<D7`;jOdCM-\eqpl_9\X%_[<fGIB?HL]W>'5Ng?HLc6>fYFHCB2'AecD!8r;QfS!<3!B
+pB]XUs4V.Gs6dR\KoK?%s4E6NRb%B9s6dR\KoK?%o%M@fs!#Gks76BZs8U4Ms8UrGIuBC;s76BZ
+s8U5WL&6@@mf2!SNW&kXIr"f0;epmJf%/9BN,rH#cIUR2!<<)nV#UJC"RlBjZ"AKnp](9WD)H6Q
+2*IVfH[#/_jD0JLfSag>f),L2D)H6YCB/_#pB]XUs0WjHs5'8qMi]Cfs%*+_ciE([e]u7P]3.^a
+LP(&$F`D83AMH/T=]d1":/k"8.p#hA4u=l;BlS8pQ\1*G!(fp_:dq1i!3+)e]`?Ul<kHr6]i&YC
+ecN6OJ,TBdmVdUTs8.:emf3<p*<6&qS:?HY.KBFQAq.5_rr4V-S:?HY.KAPak5YJ@BncA0GP2!s
+CPDfV]oIf+>a5&2GP2"9ape=E#i>U][2f,E!!)`D/cbq:f$q6rIqi#CdakfuJ,fDjdJrEGH2%?k
+MfY?<p](9A#\/3s!.2]bs4/@Mrr3MW#\/3s!.2]V"RGa\jD0JKrs\=6J,fQEH[#/_jD0JKrrVV,
+J,90F!;=tE!<<&L%KO&jf"D(7e@ClpC0$;A[+5;daoD@k!@`Boec`)h[ClS>echuPf%'i3rmhkc
+\^o?V@P__6BjQhECL"p2a^/c6CL5-ZecNt,!<(Ia]`?X7!56t7!56t7!56t&!,$(_B3*"KecN6O
+J,TBdmVdUTs8.:emf2!SNW8F[S:?HY.KBFQAq.5_rr38\S:?HY.KAPTrr41^%0--MGP2!sCPDfV
+]oIf+>a5&2GP2!sCPDY8F70).[2f,E!!)`D3ro<3f$^4MF(.b#dakfuJ,fDjdJrEGH2%?kMfY?<
+qu>ks2/dPO!.2]V"RH*fape=A%(Z90QlQ.gc2R_D`XMhG!q'uVrr3J\MfY?<qu?J=GP2!sCPD`e
+!InnYec>dNrmhS[\^o?F!7oSkN,rH#cBLqO~>
+ZN'm[!PJL3hA3d)hVJ7GhVJ7GhVJ7GhV<TaZ.-16W;PKRDdL]chB-ZBc/.#a=L$_]!577G!577G
+!577G!577C-'6R+P]Q]X+53*Bc+-M^fPb$<en8+*_c0sehJZ`FhVN/N\_c2sZ23;XS,iKe!T!hT
+s$oA.qt$gsYlD\4ddEcC^%@=eYN5!6o`)n#ddEcC^$(PQanP(M63$sBR-sBl4obP?XnUs]HiO+'
+R-sBl?Cq1i@__Z;@^,h2!Io%^hApNambZgO>/Ap[!7K`\S,iThpFXM]`=2A<l7meFrotEom]M%h
+G;ha\igOMtm^HMooT!%WjQc%&m]QP=&oRc"`W&5Wqt"9+s8S"ZpZ>Y+rVloV)>aA&VP!,<lg4!*
+mdBQ5^rcBBo#\f9o'F98nF!sMma-aQmd8*qlg!YMZ/4E?O5o4B_r0Fc!8^.;LWR_t.rX;"`Q-il
+]hX(UrrVV,J,]H]TOP\5o3u2/s,4#Rk$!-3l7meFrp'O`/rQk+k$!-3dZBCFn?lYss-dT<m^HMo
+s2CMVm\"=.s-dT<md>Qfs8PB<qt"9+r;Q`sp>-eis6eatR#]G%9PN/9]hX(WqiZ<ahIqE7oT!%W
+jSnEFs5*a)#B'Tl`W,sf9)\bihYr!4DZG:+s#$1]m^HMorr3&fDh%cd#+B2Bm^HMorr3&fDh%W`
+!!)`L!<E0!h@9P!hVPpGhV+?Wc+-M^fX0K:^!6TVh@k\sR*!da8hno9!4C\3CB35J!58Bg(BD/*
+hV<TaZ.-16W8;H!c/-]ODr,D;bPL&sc+O,UhB0E2hVJ7GhVJ7GhVJ7GhV'9;dajY(hVR&,a55[d
+:4N6B!q'uVrr3Y)@__Z;@^,mOS?;PJ>'p;70n8'ZlMpl:Mlla9>'p:t:<E7qImO,7RV0P+[pG[+
+`LPBETPD1?RV0P+[pG[+TOP\1o3u2,rr<&mhEV)@hVQge_:k7VC"V:U:4N<@P'c-DBRfjMN``LG
+lK\$0Y((qFDZG:+s#$23mXID"o*i%umZ\mpdS@pYl@2+urtOm>J,fQ@N``LGlK\$ARV0P+[pG[)
+rrIUfp>,fMs8Ljc!577G]`?p?>/Ap[!7IB4J,~>
+ZN'mX!PSR4gD7L'gY2_BgY2_BgY2_BgY%!XY0aG*Vu59ND-tNagE19>bhLWZ=KpJU!4pq>!5@4B
+!5@4B!5@4>,`^3uP&pKS+4c^8b-juVe88L6e7Mh$^JeF\gML<AgY6QF]%buiYkm)TRK39c!S[VQ
+s$oJ/q=CXtZN%q8dI!WD^%@:fYN5$8p&E%&dI!WD^$1\Wb4k4O70!9HRd]Wn4TGG@Y4^m^HiO+*
+Rd]Wn?Ch+iA%hT:A?u16!Int\gDt-\mG$CC=h`LR!mTKSRK3Bfo.7oU_@5o5kq[hGrp(Kqm]V+i
+FuDR[igXZ#m^?GmoSm%XjQl.)m]ZV>Ao.Nt`rAGYq=A*-s8S(]p#TJ+s8Vrfb5gGPdE9D@[oZ+Z
+LOsr!F)G`)@P9QF<Dt:j8l&&(.8j"f:L-<fA8cNhP(JIH(h/`!E*K]\!3=;j^&ZnU98CU1MCWPu
+fYYV^gU^+/rVlrdD1DQb';8pLq=A*-s8S(]p#TJ+s62:ih>Za?s"9;6p#TJ+s3m-ji:43aU&UTr
+`9t'?Sc?^#dI!WD^&OR9`:!#B4TGFLK),"JAc2Q.!;>.f!<;H@es209[S1>`gU^+/s7q_$hV;al
+p[jGKYN5]K!WV$UIg9fjJ&_NgIn9P<!8d^)$Z,ln`rA#e`9t'?Sc8Wjm;7@Prs"s,`9t'?Sc8Wj
+m;7@Lrr<&mgAq<Srn@n_^>%DV!8H(iMorJ%B@O<C!kQVUrnA*B/saH%ZqW1%_uR*tb\7(3gAnte
+gD9k(gY:D0=g$,VJu@@??d.9K?Z"P7?-<#u!mJ@YrS&F.!8H6.^>%BB^>%BB^>%6bNmH+9F5,I%
+_St9a\kR\QrrVS)J,]H]Tjte0X(8O9`gs:*j^!65kq[hGrp0Ua/rd%,j^!65do"9^l[M>&s-m`@
+m^?Gms2LVWm@e@0s-m`@m^?Gms.Nr9p@Dd*r;Q`sp=hh4s4c;U=h`LR!b^$;\kR\Sq2]gXgh2'0
+oSm%XjQl.)m]V+iG&75/`rA#en*PTes6gH)oC%nfs3jifpZm;srVmT!D1DTcoSm%XjQl.)s-m`@
+m^?GmrVlnJD>)]b!<<&Q%fj>ugV*[Bd9438Q3,="9n3~>
+ZN'mS!PJL3eeYq!f%'i7f%'i7f%'i7f$ntGWlqMmUAWRDCL5-[efS[6ak"gM<isrK!4g\3!56t7
+!56t7!56t3+cOOgN,SRD+4?=-`N_sFctcn,ct-7o]i&+Uen\U6f%+U:\^o?[XnpTLPQ:X]!T!hT
+s$oA.qt$gsYlD\4ddEcC^%@=eYN5!6o`)n#ddEcC^$(PQanP(M63$sBR-sBl4obP?XnUs]HiO+'
+R-sBl?Cq1i@__Z;@^,h2!InnZefAOUlIOP3<k6Y?!6WmDPQ:a`pFXM]`=2A<l7meFrotEom]M%h
+G;ha\igOMtm^HMooT!%WjQc%&m]QP=Ao@[!`W&5Wqt"9+s8S"ZpZ>Y+s8Vrfc2cbSdE9D@[oZ(V
+KR\;jEGT;u?nO9B;c+nd8PVi$-r<_a9j9j_@r63_P(/.?(1E;mCKRgL!34&_]`?VP8V=puLF[/k
+eA&iNf!S,"rVlreDh%cd';/gLqt"9+s8S"ZpZ>Y+s6;=ghYug?s"953pZ>Y+s3d!ei:+-^T`:Hn
+_sY!?T)Zd"ddEcC^&OO6_sZrB4obOJK_t@M@f66+!;=ta!<;?8dZTC)Yt/HQf!S,"s8.t+i8/-s
+q=K\LYN5]J!WV$UIg9llJ&VHfInK\>!8d^)$Z?#p`W%f__sY!?T)S`kmVdUSrs"p)_sY!?T)S`k
+mVdUOrr<&mec>dNrmhPZ^"1cJ!7oS]LW-MhA^Ig8!k$/Mrmha8/WdfjYt?Un_#Uaka^tP(ec<D_
+ee\>"f%/>r<iX?FIA5;.?HLd??>J,->fZ]l!m/+UrRN((!7o^$^"1a7^"1a7^"1UTN60A(Dq<Lh
+^VSLP[7YrIrrVV,J,]H]TOP\1Wa`44`LO()k$!-3l7meFrp'O`/rQk+k$!-3dS@pYl@2,"s-dT<
+m^HMos2CMVm\"=.s-dT<m^HMos.Ei9p[_j'r;Q`sp=;J/s45cH<k6Y?!+jO.[7YrKqiZ<ahIqE7
+oT!%WjQc%&m]M%hGAdJ2`W%f_md>Qfs76Z,oBqhds3aZapZd5orVmT"Dh%feoT!%WjQc%&s-dT<
+m^HMorVlnJC\H<[!<<&L%fj;of"D(7c;qL(O9!Ff8q6~>
+ZN'm[!PJL3hA3d)hVJ7GhVJ7GhVJ7GhVP_Y=D:rJXSgoVDdL]chB-ZBc/.0.8mZ^c*+Id]!577G
+!577G!577GO@j/$8pgEk+5E#W@UN#qgjM8Bab<?%G=b#lhJZ`FhVNZ#>.re76MfO>S,iKe!T!hT
+rt;_;Is5@[jT!28@Wc:Om+bi#BDu[$[K"3^@Wc:Om.@#U??^Ho\c;]3;KHnWZ2ai^:3Ub_gAh2T
+;KHnWJ_:"VK5#[AMraj:"Fk@HhPU6i&uOOBDh%33hV(S*CK=']hVOb&rr3:6>'F.gs8TV0A,U0C
+[Jg+9mVdUTs42[/F(0^QgfuRHrbDMAr;QfS!<3!-[8MKu:<EP9Mb\J;>2&rT!T4sos$ir\lKcWs
+ZF79nnF=H@q""%$aR8]gaNa;G]"Z%iY3kZFb5^enlF)A1PBN;Rj!2M#hn9$HW-(a>B3Zm(hU@1?
+hVPq@J,TBKmVdUSrt=%<Bn(>%aoDC!:3Ub_gAe\`A,U3Cs"94)GB6sAs6?=`CNX6Gh#GrT@WQ"0
+f`/p,@Wc:Om/PXd@WQTgZ2aj3;L`mcao)/=!<1jQDuST5!<;KDglbQE?r3$AhRu[6s8T<0Bk_+e
+s4gj6BDlWDrrLsVrVlmMPkk=[h>mQT#-Cd4F(0^Qrr3&fDh%cd#1e95F(0^Qrr3&fDh%W`!!*#T
+r,;Sk!<E0!h@9P!hVPpGhV=8l@UN#qgpGo>^!6TVh@n=L8mZ"*4eUZ_4\fp>@K>9A!58Bg!<Bh4
+h@mA8=D:rJXPRl%c/-]ODr,n(Mp;.U!mSCYrSAX0!8cQ4^#%TG^#%TG^#%V-8nVp3Hf!W.Kok0J
+]hX(UrrVV,J,]H\g4O*d@Z0=I`GA:nF'@;t\H$.<C]FDeMb\J;>2'#A>$cDo>.O\5eph.M@Y*23
+`GB"+At&)deph.M@Y*23g4O*dG>?9Xrr<&uhY_<khAcOqhVQsY>&./2P2+p-:4N<DY[2$XA@MTo
+>VTmjCB1d@rrVWF!<3!5X\s4];R-9%G?T'/;O%4H>$cDo>.OV3#juV\s8UkZ0k^K$#ds]`Iq!J.
+J_9r$!Io%ehY_<kh>mWVrn\.c^#%VZ!8cF%>&./2g71og~>
+ZN'mX!PSR4gD7L'gY2_BgY2_BgY2_BgY9&N=_:cGXSgfSD-tNagE19>bhLa&8R6C[*+@UV!5@4B
+!5@4B!5@4BN(mkr8U^Hi+4uTN@UN&pfR#`=`e6osF@\TegML<AgY7&p?+Se16i,O<RK39c!S[VQ
+rt;b;IsGR`jT!5<A9DOQle5PtBDu[$[K"6bA9DOQlh.#W@<Zir\GuT1;fd"VYlF`_:j6tbf`1uQ
+;fd"VJCjhTK4oXCN9's;"Fk:CgSFdb+/IZGD1Cs-gXSeuBidsXgY8.ss8W%-=a+(grVs;+A,U0C
+[Jg+9m;7@Qs4)U/F(0[Og06:ErbDMAr;QfP!<3",[S_O":<NV:NDOh?>M/uUq!lE*gss]j^q-jP
+7Yub(4?5>X94;'V0j.:H,p5TI6m*dL9c>6+,p?c5Dc2REKS`ni7S>[LYdOP2aNhBtgST$c?tN[o
+D;3EjO5&F#9n3-A!psiSrr3VbK4oa[:<NV:NDOh?>M/ta!+YtCs8O^2:j6tbf`194?>OdtLths[
+Iq*P/JCjh@De+!'RHsn'Iq*P@:pC!"[S_O":<NM7!!*#Qr,)Gf*!$$+gXqN`@UN&pf\<u3J,fMP
+?>+%a[f4ub0k^H#r;QfP!<3!"r@F*,rrLjSrr32(;e'lXJCjf#!psiSrr32QIq*P/JCjf#!psiS
+qYpNqrnI?frn@GRs8La_!5@4B^&Zp?N_s7n;39G;gB+t1s8LadcY#mV@9#L]gXA8ZDfoIggY2_B
+rn@GR^Ack#ZYWcV=C\GeD-tNAb[55AHT[5/qqD1r^&\,d+2.a0gAntBgAntBgAntBgPej<B1[O+
+gX(V7gY9;6J,TBKm;7@Prt=%<BRF?LjT!5<:j6tbf`/A[A,U3Cs"9:-GB7!@s6EltGBI#ts8UW!
+@rl+0fDij/A9DOQli5Lb@rl+0fDjQWBRG)#b5D8>!<1aND>r90!<:g.eONhX=%eY-gU^+/s8K6/
+BPD%drn:R2BDuZH[Jg+,mFqX?rtVV6F)t0^s8@4IF`gWIs6EltGBI#trVm/jD1DTcg06:ErbDeI
+s4)U/F(0[OrVlnJD>r;fD>r8j!<<&Q%fj>ugV*[BeONhX=%h)49n3~>
+ZN'mS!PJL3eeYq!f%'i7f%'i7f%'i7f%.$=<b,6;VYo!HCL5-[efS[6ak"mk86U(U*+%4I!56t7
+!56t7!56t7Le;,h7X+^[+4Q6E?<g0_e9<p._1>-hF%8B^en\U6f%,$^>.)r#6Mf76PQ:X]!T!hT
+rt;_;Is5@[jT!28@Wc:Om+bi#BDu[$[K"3^@Wc:Om.@#U??^Ho\c;]3;KHnWZ2ai^:3Ub_gAh2T
+;KHnWJ_:"VK5#[AMraj:"Fk4<etDtW&tmh,CObX#f$[#gB2V4If%-&crr3:6>'F.gs8TV0A,U0C
+[Jg+9mVdUTs42[/F(0^QgfuRHrbDMAr;QfS!<3",[8MKu:<EP9Mb\J;>2'#Vq!lN-gss]j^q-jP
+7>?=t4#f,T8mY[O0j%1D,TfBD6Q[RG9H#'(,9LB.D,-(<JVI;_6q]@BXKhi)`6,Xketd:W>[gkc
+CY$a_N7QRf8q6g>!q'uVrr3VbK5#gZ:<EP9Mb\J;>2'"e!+YtCs8O^0:3Ub_gAgH4>\eIoM;8-^
+Iq!J.J_:"ACgqO!RdC(*Iq!J?;R-9%[8MKu:<EG6!!*#Lr+l;_*!$$(f$oXR?<g0_eCM$"J,fPQ
+?>4+a\,Y5g0k^H#r;QfS!<)ou/X6)2!T!hUrs#T'@WQ"0f`(mPmVdUSrs%&(@WQ"0f`(mPmVdUO
+rr<&uf)0=_ec>dNrmhPZ^"1cJ!7oYY:0q1!N7>5c!k$/Mrmhb)Ak#s1;E:,qc8eX8F'\jtec<D_
+ec>carmhadBi\bF?Dc:h?HLd??>J,93JYTNecNt,!<(Ij]`?X7!56t7!56t7!56t7Le;,h7X*G7
+c%Cu+f!S,"rVlreDh%cd'&%tPHX_oos2AeLGB6sAs1&,>rG2H5/rNJKF'@;tl<7M<F'?-Ss42[/
+F(0^Qs2Ae`F_7*/s42[/F(0^Qs4W*>HZr6,r;Q`srmq!_rmi%hs45cL7TO/"7Z>jJ[7YrKs0,gD
+Bk4^QgfuRHrbDMArVlreh>mQT's1ATF&K:Cs*%XfF&J8&l<7M<F'?-Qrs8%2J,fQ(>VTmjCC%?J
+eph.M@Y*21rrIUbrmq!_rmh)Ms8LR[!56t7]`?X37TO/"7adMnJ,~>
+ZN'm[!R5Q]hA4@ShVN1qhVN1qhVN1qhVR%sK6)UKf_jS-VOl?8hB/Vde_]0!MfX*DMf[b3Dp@.q
+Dp@.qDp@.qg6?Z"OOEs]*m'^hFdgM1[!e7b_2EGuS:@KoVOl>phR&2Z^#%"PqVD7C!;uitmXP38
+&Gr_bK:^lus7XEkKrjG:k,/'+&&8/<`JoSQk5YJJg6@)B^&J$?qlGF&[JU"(m[Scbc2R_PqlGF&
+[FkHXrRREiT%s8D%Y&ERhPN43!&pe3hJ[o3rn[dcGAhi=rn[[G!<3!'g5pfKirB&'qgSU\rVm?#
+\%htCrR7-dSCmf&VYkoD^\n*4mXP69"T,HVK=V!]"R_e0Mp;2"!Ul'Fs$j#`lKc]ZI=n9GnaXZH
+q=F7=i:?R3i8XD#jikceiUH=(bl@%qlK>[KR]P<*j+Pn?i6H8thSYCqH(:%phUS3phVPq@J,TBK
+p:%g9rrrAPRY-7'rr35kS:?IAs8U@@J,fNOm[Scbc2R_hm'hh(U>GqMrR7-dSCmf?p;N#FXQKQ_
+rR7-dK=1UVs80'RK=UmZ!!*#T!,qi:!,qkn)?Bg*hVQA?F*3qphVPq@J,fQ8[>0UNnGhXJqg\PD
+!UbI9rrIc+q>UK`J,]HPqlH0;SCmf>rrVo'^]+6;rR7-dSCmf>rrVo'^\[s1!<1gTDuK_:DuSSo
+!<<&T%<'MJhT]uqhT;()FdgL[h?(C8s8CdXc&d!bH`6r#$*8>hK=PpWhJ^[<h>qQ>rn\=D[tAaQ
+Z.Rp1T%2]JSu1AOI?r.Th?)6PDuJN7c#;IqDp@.qDp@.qDp@.qg6?Z"OOE"BeXiYphRu[6rVlrm
+\%hqB&H11KK:^lus7XF%IuDSOs3:Fjs8N5iS:?IArr3,TP^eJ%rr4#;e!PcXf_tjD`JoSQk5YJ[
+e!PcXf_tjKes_5D\blC,!<1gTDuK_:DuSSo!<<&T't&7(Hb%>VhRu[6s8VGnLP`Y4s5p3VIfR7^
+rrVo^J,]H^qlGF&[JU"(lC`WZW:U&hg6@)B^&7m7p:%g:s5p3VIgEghrR7-dSCmf=rrIUfrn[Wn
+rVuq:rn[YUs8LjcDp@.qc#;Iq[<HP9\_`iOJ,~>
+ZN'mX!R,EZgD8"MgY6ShgY6ShgY6ShgY:AfJoQ:Df)48(Un-!3gE35^e(`WlMK*d=M0%G+D9Ubh
+D9UbhD9UbheWb&nNm[[W*lX@aFIC5)Z@%q[^P[)nR=;'gUn,uhgTlZS]%bGGqV)%>!;uitm=5*7
+&Gr\cKqI0#s7aNoLTT\<jehs*+2@jM`fGnWjo>AHfTgrC]`%m1q5f4&[/9n'n"##hbl7VOq5f4&
+[+G9VrRI?jTA9AE%Y&?MgS?_-!&gY-gMMH-rn@R[GAV]8rn@IB!<3!'g5g`Kj8]/'qgSU\rVm?#
+[_MkBr6gpbSCd`$VYkoD^\n*4m=5-8"T,EWKt@9`=mqo4NQhG&rUoU0DqWR^`4`U_<(2Lj>9!VC
+(e@n5.5"Li7l)ha69m4]7nGio.5=P*Ant2!H@U^*@SK^6TWYY,Zc:81D;3g[NH064Oega\SYY#p
+\kR\QrrVo&^]+6:rRI?jKt@9`#Oe47NQhG&bklnirrhe]JW7nQs!@!?MM._Zrr;oEQ\:m\rVuW3
+O,'k!s8W#FQ\:("qu?]nY_@eBqu6Wrrn@EirVuq8rnA=ks6\Rq`KYCbRE4.;\kR\Ss6R.KMS/KZ
+jehp)r;QfbJ,]HLrI`burrMM:rr32uXI"U1fDY^K!qs(;rr33#d[,WWfDY^K!qs(;qYpNqrn@Ei
+rVuq8rn@GRs8La^D9Ubhb\c+h`KYCbRE2_h!kQVUrS%M"OE58cVZ,<VWc`64[VadRD9W"6!H$'[
+gCr5HJoQ:Df%[!ke(`?BUt`2&Q-0!Y!n5A1rS&F<D;3f^bhLlhbhLlhbhLn&P]:]'dG*F)SYY#p
+\kR\QrrVo&^]+6ErRI?jTA9JHpVrbTNQhG&bklnirrhe]JW7nQs!?<_Iu1i:s8W#FQ\:m\rVuW3
+O,'k!s8W#FQ\:m\rVuiHRY?I,qu6Wrrn@EirVuq8rn@GRs8LafY]jr2[`I4X\kR\Ss6R.KMS/KZ
+jehs*!5JL4!qu#2rr3`/XFl56qu?]^U4J#soDejCQ%+Y'rVca#p9qa9s5g-UIgEghr6gpbSCd`<
+rrIUdrn@EirVuq8rn@GRs8La`D9Ubhb\c+hY]jr2[bI6FJ,~>
+ZN'mS!Qf-UeeZACf%+WYf%+WYf%+WYf%/?UIrBb8chu>qTUO4(efUQRcdp[ZLMq70LMtbpCWY/Y
+CWY/YCWY/YdZABcN61nH*l3qVEKnAlXETcF]8(BaQ@#@WTUO3XeuXL>[FWH8qUP\3!;uitmXP38
+&Gr_bK:^lus7XEkKrjG:k,/'+&&8/<`JoSQk5YJJg6@)B^&J$?qlGF&[JU"(m[Scbc2R_PqlGF&
+[FkHXrRREiT%s8D%Y&9Fet=l#!&^G#en]d#rmh4SF)-!)rmh+7!<3!'g5pfKirB&'qgSU\rVm?#
+\%htCrR7-dSCmf&VYkoD^\n*4mXP69"T,HVK=V!]=mhf0Mp;;%rUoU1DqWR^`4`U_<'u7c=W@DA
+(e.\/.5"Ig75?M\5X-nW77]Nj.54A#@q\PmG^Y0u?VF7/R]<SrYeeE!CY%(KM/RO(NhFtLR\86_
+[7YrIrrVo'^]+6:rRREiK=V!]#O\+3Mp;;%c23"jrrhb[IuDSNs!@$@M1_PZs8W&HR"Lp]rVuT1
+NJ4Irs8W&HR"L%!qu?]nZ%I\>qu6Wrrmh'brVuq6rmhtfs6A1d_2rSTPf))'[7YrKs6R.KM7`9W
+k,/$*r;QfcJ,TBJKA-/$!UbI:rs&A%R"Lp]rVlfup:%g9rs&GNR"Lp]rVlfup:%g5rr<&uec9Lb
+!!$g6ec>dNrmhNoak#%bCY%(QODf-'_m@nq[E8IIecj0SDejQirmhCOF)-91CY%'Pao9ilCWZS,
+'@a::DgeY3etAJXf$BeXeuX(W`V\3fccKu$efW"Lf%+WYf%+WYf%+WYf%/92Df:TVf%/09T[q]%
+8q6g>!qs+<rr3Q.es_5_h#IEJ`LMF9c2[ggqg\YG"R_e0Mp;8$"PT)iLV<]e*W=HSK:LTms7XEk
+KrjG:s8CE6K:LTms8CN;K7g`3rr<&uec9Lb!!$g6ec>dNrmhgdF)-!)_q*DH8q6m@m'VV*]C>j_
+VYkoD^]"06p?mG0rtP@3K7gT/s8VAWItO]ks8Uf;Itt`8rs&2+^]4>rVYkoL^]48]R"Lp]rVc`s
+Ir#&7!,MQ6!,MSb!<E0!edlQ<f%.rYf%-sECNm&7PY-H~>
+ZN#U7!Ls.irrIUfrn[aS2`IW5h?%VFme5K<S,fkp&?M_om-W/iT\&`(o%E7)qY'aXs7@0$p\FUY
+nF+[&mHj0(l0.<mk2bU`io/hQn_O>\:4K;D!!)uS!cJ'WrS@SUs6fX<!kh?YZMsn)rS@To!,qhm
+!<E.oh?(C8s.nKQ]hX'Wrr<&th?%TqDuJMn!<;cL!kh?YZi:&UDuJMoDZF_Sh>mWVnD429:4N~>
+ZN#U4!La"grrIUdrn@ON2E%B1gB)5AmIo98RK1)%*W#BojPAD5aMGHoXAVE;I!8O.)+e(7?Xo8(
+X^+-g4<-ON6V(mQYdUE;B2"#'I=d98Pa\5@XKo@M`6-HsgB+r\J#`MK!<(XRD#eGOgB%BTmJ#?:
+\kR[[rr<&tgB)3lD>i2i!<8eJ!kQVUUtYs^9n02C!!)uP!c7pSrS%>Qs7Y1K\kR[\rrIUdrS%Bj
+!,_\h!<E/hgB!a;J,~>
+ZN#U/!L*SarrIUbrmh1E2)V'+ecKW:lLrd0PQ8Gt*r>KpjPAD5aMGHoXAVB7H#uq&(e7b0?"9&&
+XBRhLr]2&]4[28&B99=)V-db)KlhWjKo;([S=uma[(=&mbOO-b[7YqKrr<&tecKUeC]2fc!<;?Y
+ecN6OJ$T(S!<(IMCB//Kec>dNU=KCRaoA0f!jtXMWrE&!rRM$c!,MPa!<E/necN6OJ$].UIr##6
+!c%dOrRLuLs7"S?PY-H~>
+ZN#U7!Ls.irrIUfrSIROrS@ToJ+!$e!Ls.qrsGm+lg4$,eCO-]rVZZqq"aUaqu6Qo'`@Ihci<D!
+lg!a!ki_*ijQ#7Yi8=(]!kh?YWrE&!r8%Elr8%JTs6fX<!kh?YZMsn)r8%Elr8%GSs.\?O^!6T*
+h>kmOh?(AcJ#`MK!;t[RDuAGm!<;cL!kh?YZi:&UDuAGlDuAGm!<;QF!Luo8~>
+ZN#U4!La"grrIUdrS.@JrS%BjJ*lsa!La#&rtbD"l/LIIc,IE+Yc1GcIsH*P:.\`HkktG^D`BZS
+2$>fs41k4brtXHt@nD5mH%1O+P*hi:Wj&qE_T:$Uo%O5W9n02C!!)rO!,_Yg!W`8fpY,b\9n0JK
+!!)rO!,_Yg!<E.ogB+t1s3fX%bgbAK\kR[Srr<&sgAl*ggAq<Sp=fY[9n0ML!IntagAl*ggAq<S
+nCmu49n3~>
+ZN#U/!L*SarrIUbrRV"ArRM$cJ*QaY!L*SurtbD"l/LIIc,IE+Yc1GbI!9RG9LrBAkktG]D)_DM
+">r+u](Z+&(#N5(7Y,Q'I=d98Pa\8BXKf:L`6-U#ecN6OJ#`MK!;tCJC])`b!<;?YecN6OJ$T(S
+!;tCJC])`a!<8eE!k$/MdaeE=eCF]/8q3l@!!)rJ!,MM`!<E/necN6OJ$].UIr"u5!,MM`!<E/h
+ecD"-J,~>
+ZN'gY!P>Ckh>s,HWrE*LDti)iDh%3Kh>s,HZMtQ@WU0$>mdKZ8p](9jpAb0fp\4[^s7[K+rVulq
+rVufcnBh4&mHj0(l0.<mjlGI]iS`Yah?(AcJ#`MK!;>7N!<;K]h?(AcJ$T(S!;>7M!<8eM!klkY
+e_UDKGq>*-h?(AcJ#`MK!;>7M!<;cL!kh?YZi:&UDt`#g!<;QF!Luo8~>
+ZN'gV!P#+fgB!`CWrE*LD>2cdD1CsHgB!`C^],DTp@%2&g!\$\]X=l>:I';NEGK,m>*f3gn'1n4
+C,%FA/fl]%2;eH4iTL6u>$sjKEHch`M3!pkTr>-$]"uG3f(.Ps\kR[Srr<&mgB%BTmJ#?:\kR[[
+rr<&mgAq<SU>#a\bl?5J"2oC6O4;nc\kR[Srr<&mgAq<Sp=fY[9n0ML!Int[gAq<SnCmu49n3~>
+ZN'gQ!OS\^ecD!8WrE*LC\QB]CObXCecD!8^],DTp@%2&g!\$\]X=l>:Hs,GDJ3Nc=I&pdn'1n4
+C+q:>/KQN!1uJ?3iTL6u=C"@DDKL2TL5_:^SYW9i[_0JudIPii[7YqKrr<&mecGjOlM&j2[7YqS
+rr<&mec>dNU=KCRaoBoB"2K".N7?D[[7YqKrr<&mec>dNp=9;Q8q42I!InnYec>dNnC@W)8q6~>
+ZN'p\"M8:_+OZ5*!Ls.irrIUfpYGsiJ+!$e!Ls.qrt)E7m-X60nF?&@p@Zqls8Voop]1-hp`0&(
+q"==Vs8;EWdf8b&m-Es$ki_*ijQ,@\iS`Vah?(AcJ#`MK!;>7N!<;K]h?(AcJ$T(S!;>7M!<8eM
+!klkYf\QePGpF%+?IRa4]hX'Wrr<&mh>mWVp>,ka:4KVM!Io%]h>mWVnD429:4N~>
+ZN'pY"Lr%[+4#o#!La"grrIUdpY,adJ*lsa!La#'s$?SUmH39Wd)a&7ZE'cr5^INiBOY4IDM;@=
+3WK+k.k)ko-n6`#H=fT3XoI6Z>X`sVFF&ImNK]d&VQ@)6^W"FHo%O5W9n02C!!)`I!W`8fpY,b\
+9n0JK!!)`I!<E.ogB+t1s4H'0`-3I>"C0F1!kM*UWrE&!p=fTJs7Y1K\kR[\rrIUdp=fTJs7"bD
+RSA;~>
+ZN'pT"LMYS+3TVo!L*SarrIUbpXTC]J*QaY!L*T!s$?SUmH39Wd)a&7ZE'cr5'V*aAmeeAD1l+8
+3WK+j.OZYk-RgMtH"B?-XT.-W>!dOOEd3"cMNF-oU8Y6&]>;P6o%!lM8q3l@!!)`D!W`8cpXTDR
+8q4/H!!)`D!<E.oecN8$s4Gm+^iUe6"Bs:*!jtXMWrE&!p=96Es7Y"F[7YqTrrIUbp=96Es7"S?
+PY-H~>
+ZMt-@B,hQc%`+([!Ls.irrIUUpUpW7J+!$e!Ls.qrsuB.g>(QCioB.`l0?^Us8W&n!;c]js7dN,
+p@\:^r:9C,s6f:@lg!a!ki_*ijQ#7Yi8=+^!kh?YWrE&!p:UM-s6fX<!kh?YZMsn)p:UJ,s.\?O
+^!6T3h?_/I,SL:\"?,)bh?(AcJ#`MK!;=),!<;cL!kh?YZi:&U?M;&5!<;QF!Luo8~>
+ZMt-=AfMEa%_dkU!La"grrIUTpUUE3J*lsa!La#'s$?PRm,[!RcH!]0Z)OHl2.g9$<`)O\69R:G
+2uine,pOQU+X8<`/i,FLX8h$U>!mLNF*W7hMisI!UoL]/^;S1Bo%O5W9n02C!!)`(!W`8fpY,b\
+9n0JK!!)`(!<E.ogB+t1s4c96`-3I>"98Q_g=+dX\kR[Srr<&m\cDg2p=fY[9n0ML!InDK\cDg2
+nCmu49n3~>
+ZMt-9@iH$]%_@SL!L*SarrIUQpU('+J*QaY!L*T!s$?PRm,[!RcH!]0Z)OHl1h0ip<)6+T5W^nB
+2uine,U+?Q+<i*\/M]4HX8h$S=@%.GE-?V\LlR^hTr5$!]"l>1o%!lM8q3l@!!)`#!W`8cpXTDR
+8q4/H!!)`#!<E.oecN8$s4c*1^iUe6"98Q]e^N(N[7YqKrr<&m[/g:-p=9;Q8q42I!In;H[/g:-
+nC@W)8q6~>
+[JpNaG9IV#!!!M,MV\B(!35GfY*Sgq!g^=`p>,h?!57h#n,MnWnc/1[o+:Q>_V<o'i8Wh[kj%Ko
+mf3=cq>gElqAf>+p\4CXs8;HXeGnt(mHj0(l0.<mjlGI]iS`Vah?(AcGH1'2Dt^jGDu]8"h?(Ac
+GI$W:Dt^jFDuZQg!klkYhVJCUGpF"*r;Zj?e'd(S]hWdOmJq2!]`E'Op>,ka:3X&4!Nqa^]`E'O
+nD429:4N~>
+[JpNaG9IS"!!!M)MVA0#!35DeXd&Rk!gL.\p=fV:!5Inekht1Cbf.<*Yc=FfQ"O',?WpH*8ju!,
+2'tWhs'?fg)AsG6+=&Ei1ch];h,7?AF_Yo?I>!K>Q^sqPYdV3^ajBV5!kM*LWpKe'p::<Bs6]R8
+!kM*LZL%X/p::9As.\6L]$132gB>H=,SC7Y!!+.fdb=i79m3Q(!,_G@!H%l1gB+r\G-gQ:Xd&Oj
+!H%l+gB!a;J,~>
+[JpNaG9IS"!!!M&MUhfm!35;bWfZt_!g'hTp=98/!5IebjkeV9ahk]tY,@q]P@d^$>Zap!84,R$
+1aPHfs'?ce)AsG5+!`9f1HDK8h,%-:F_GZ7H@^j1PF8)@XKo@N`QRi'!jtXCWp0S"p9as;s6B@0
+!jtXCZK_F*p9ap:s.\'G[E8I*ec`d1,7t(W!!+.adaeK-8p.0!!,M;9!Gh`/ecN6OFgL?6WfZq^
+!Gh`)ecD"-J,~>
+\Gl]^IN&Uqr;Zj-Iu3"_S:@*t!VYsTh>s-r^$bphs7$'Ys763]s7H?as7ZKes7lWis8",@s8Vum
+qtp<gqtg0bq"OLYs8;HXl2U5?mHj0(l0.<mjlGI]iS`Vah?(BM\"2pfs6fX<!kjT&V="?`U>>t%
+k5X>q"hnLq&/5KN!!*bNdG=r<NOPJH!<;cL!kjT&V="?`nD429:4N~>
+\Gl]^IN&Uqr;Zj,IYle[RX^mq!VYpSgB!am^[4ANhq?H$`4`U_W1f]ENJ2k,EGAug<_l7P4%oVR
+>8n@m',26%+=/Nm2lZi5:KCM;BlA0BJr,PSS>3'e[_0JuceA!F!kO?!Sa?IXmJ#?:\r=(om/[0\
+gB,jcs52Q7]ON<#'FOg>!><2qgB+sF[[ldcs7Y1K\r=(om/[1UgB!a;J,~>
+\Gl]^IN&Uqr;Zj,H\p;SP^f7h!VG[NecD"b^Zn/Hh:Bon_7R%UVOs9=MhHM&DeWZb<DH%M3_TMQ
+=rJ.j',23#+!`<i2Q?`4:/k57B5M^8ItioFR%L4UZ+%HcbLQ48!k!lmSa$7UlM&j2[>D;fl2^jY
+ecO1Ys52B2[p^To'FOg>!><#lecN79[@QR_s7Y"F[>D;fl2^kRecD"-J,~>
+\Glm+`/[V<%fcS7</BB2]pnEik4[X3]tEe5n,MnWnc/1[oDeI_p&Facp]($gq>^:=qu?]nqu$Bj
+r;?Hgq=s^XqZ$Kbo(VnImd9B,lKRNqk2k[aio/hQo%jDleXPt,k4d^5c./TWU>>t6mdAid"cj?)
+!"Z$Th>tmOS*p",!R9/imdT'6S5+S~>
+\Glm+`/[V<%fcS7;i'0.\sr'ejS%=.]"[Puk24h>b/Cs$Y,J"^P)P'CG&V/)>Z=Hg5WMC8s&^'M%
+1E^Z(EF_L0/]a/h+q$\BkVC,H\.'7Q(+MHYI2$[aNiN2gB#IGS*^4:pY,_ke"c<)gB-I'mG$A!N
+>)^"&#R_.!Qrl\mIo98b1!-QnCmu49n3~>
+\Glm+`/[V<%fcS7;2Ed'[@?F]i:b_%[D(omj5&83aMGHoXJVSVOG\[<F`1r%>#S-b5<)15s&TsJ%
+1E^Y(*"MH/i9O,geC^VBP)($G^kF+P*_c9X0K.I`6-X%ecEb9S*C"3pXTAac_Kd"ecOdplJ'knM
+A-Bt&#.G%!QEBSlLrd0`Qt=EnC@W)8q6~>
+[JpHo:,r:U0\_08J_nc15i:MYioB+]k3(smlKdg(mdKZ8o(2MHp@n@^s82]krVlcnqtg-aq"O[c
+r:BLLnF,f4m-Es$ki_*ijQ#7Yi89+BJ_lgO#1d-GCB+fqJ_kt7leVZ4:4N~>
+[JpHo:,r:U0\Cs2J_ST,6Ia<%_7R(WVkKQDNJE%1F)>Pu>#\3d5WU_hs8Q.7%1!.E%MTg)-S@6S
+s4pFL>@D/]FF&LnNg-$,W33P?_T:$UJ_Pb1RbJ%q?9W''%=j#aJ_TMF!Lc`5~>
+[JpHo:,r:U0%5C&J_&6"6I<il]XG&EURda6MM-D&EGK)k=Ahd\4ukDcs8Q.7%1!+D%MTg(-7q$P
+s4g:G=C,QSEd3%dMij?sUoL].]u/"BJ_#D'Raq\g>Wl^"%=NfYJ_'/<!L-3,~>
+[f6Q22T.cZ)ps5nJ_n`05i:MYioB+]k3(smlKdg(mdKZ8o(2MHp@n@^s8;fnrVlcnr;-9cq"O[c
+r:BLLnF,f4m-Es$ki_*ijQ#7Yi89+BJ_ljP#-KM1hE_?HJ_kt7lJ;Q3:4N~>
+j8T,Yqu$Noh#@SX2T.cZ)pX#hJ_SQ+6Ia<%_7R(WVkKQDNJE%1F)>Pu>#\3d5WU\gs8Q+5$jH\9%
+20X&-S70Rs4pFL>@D/]FF&LnNg-$,W33P?_T:$UJ_Pb1S(e.K.tZM@#$$6/J_TJE!Lc`5~>
+j8T,Yqu$Noh#@SX2T.cZ)TmW^J_&3!6I<il]XG&EURda6MM-D&EGK)k=Ahd\4ukAbs8Q+5$jH\9%
+20X%-7gsOs4g:G=C,QSEd3%dMij?sUoL].]u/"BJ_#D'S(7eB.Y$#5"]L!'J_',;!L-3,~>
+\Glg$=_RI-((tV<KRng&KL(BONfoZqSY2dWX08h;]"Pr!aNVuZf%T!>kPtSSoCi"Vq=aCJm-*Nh
+nGi73ccaDJ^qI:eZEC7+UnF9HQ'%)aJV8T-a+OGHqM,$(i.MAe5Tt0$KF]&SJV8T-l\#?.S5+S~>
+l2M"fr;-6`p@\+WoEP!^p\=R^ro="`m9+,prtZ5dJV&H)c[nK4H?O=ICM.-a>?Fj$9LqQ;4ZPAS
+/Li(k+#Ers:CIL5"9o/@&/,j!+.iMa/i#=G4[DM.9Mnbk>[LuRCN"9<H@^X!JV)$r"G))RIt.EG
+s*t'!!.j-]#_,&]E.WZP*.WTlJV*3>!pc:LJ,~>
+l2M"fr;-6`p@\+WoEP!^p\=R^ro="`m9+,prtZ2VJTHB`cZ;EkCh[Hi?<^K1;,0_R6U3ao2DQp:
+-m^&Y)__6k9aV+/"9f&=%M9Em)k?rZ.4d,.2EEud6q9jE;,gY%?XdS\CiY)JJTJtTs)J*ZqJcIS
+s)R+?#]M^B@rl]#(ib+JJTL-u!p>e?J,~>
+\c2rD27W\dnH>Y@o`"mkrk7_!!InF,]n*lj]cXu(_SjI8b08/XdaZh!g"Y??iT'%_l0I^(nc/Xa
+p\Fgb*r5R'o^_M>pAb!Pjl>=Wh:pW7e^MpmcHOGP`l,a0J\?WJbe="irkJ6Ds1eTJjh1qj.VHB,
+]t#;kJ\?WJpq?>"!s%e[:4N~>
+m/Iq%qt^!ZoC;>=md9E.m-X3.n*ol=p%S=]kPkgr27W\dnH>S<o`"mkrjM4o!In=)[Xkm\[R%1"
+VP0KFOGejEHZjCEAmnqF;+jAE4#SfE4obO^'+bQ\%1j3j*?lj^V#T187ncc]>[_5\EHce]L5V1[
+S=uj^J[U-<c*dkbZa-j>Y-+o(XT,C+Y-5+9['f)*#aZrL['mEK+KL(%J[Y?^o`#!nl^COu~>
+m/Iq%qt^!ZoC;>=md9E.m-X3.n*ol=p%S=]kPkgr27W\dnH>G)o`"mkriPSf!In.$Xb!VJX[/n\
+Ssbe'M1gA)F`;,.@9cl39h.Q73&E9<4TGF\&e>BY$kF!f*$HUXU]9%36V'pL='T0HCN4NDJ:rf@
+PaS,<JZXL*c)h8QWi;qoVPU)arM0@fs/#msWN3,`XU't7?E:31W?.dbXb!VLXn;Vq!9]S=J,~>
+]Di!)Am4X%rrg0*hLtq&h>s,Hrk/=3n(n,Z:0rLbJ\Ccj+25P-`5]m@bg+P^e(*('gYLcGj5f@d
+lKms.s8Vfdp\sq/p\+7NnaGl=s8(m=j5AhNgY(3/e'ZLdbfRrG`59<@]n*lC^&PhH^]2+K_>1tI
+_>h=N^Au"5]`YlZ.\6OO!N;cE]n*lk]`A*+h?9>Kn!m.'~>
+mf*dqqY0XPn*TH*ki_*ijlHF&$KgO8lKmp-o(DbSli.(YAm4X%rrg0*gOfJ!gB!`CrjDh,n(RoT
+9j<1WJ[Y9\6*[MhU7@R4N.un2GB.M4@9cl39h7T63&<0Os8Q.:'G:uj'Gqc3,q:REs4]n39i>%u
+@V9OuGC4ssN09NuU8P,E[Xkm6[L'@JZ*1=3X/W(srhodnrhg%#WMur"Y-5+:la?o&@k!cC[K3+n
+J[U-<pU1)%p=f_=!:-(JJ,~>
+mf*dqqY0XPn*TH*ki_*ijlHF&$KgO8lKmp-o(DbSli.(YAm4X%rrg0*eoUlbecD!8riH2#n(%QJ
+8lgMFJZ\XJ6)^QMRZrkjKn+MnEGT8s>Zap"8OPd(2)$REs8Q.9'+kcf',MQ.,:G+=s4T\*8PW2d
+?".G_EHZ\ZKo;"WR\-C,Xb!V$XU;/0W2?DeU7n6QTDP2dT:hjNU84W_W2f0c"05`UO8Z0]R[&H+
+JZ\[K!<;cD"I&oLPY-H~>
+]`/&M26-TS"R5sCK`Cc&!Ls/h]`A*$h?(Ac?@fe@^%T,]^;.V'`lH3Ec-Oede^rL/gtpuKjQ>Xi
+lg=0@s7Z*Xrq7E+o^hYCmd9`JqW?kui838Cf[n[&dEg(\aiDB<_7tQ7J\BIE#JRsf^qmk(_Z%IK
+`;[[S_Z.FR^q[YO]`Y#`?+GO"J\CQd!<;cL"IoJ\S5+S~>
+nG`srq=aFLmHWosjPo+ThYc40h@&6"ioK7clg=35p\aIZ!l?gpr;Qoas4`/*p=fV:!<0D,s6n\D
+\kQC[[Xkm\[R%4#VkT`LP)Y6KI<T^KBOb@N;bfnP5<:YU6N@'h*#TP/(`=;9,:>#sVZ5C=8P`;g
+?=RYcF*N+cLlIUcSYE'cJ[U-<d^BRlZ`pU6Wi;nnUnaZYqk=%a$)=;mVl6VsY->8#[KE'Q=gEUe
+J[Y'V!<;cI"I]>VRSA;~>
+nG`srq=aFLmHWosjPo+ThYc40h@&6"ioK7clg=35p\aIZ!l?gpr;Qoas428kp=98/!<0)#s6nM?
+[7XJNXb!VJX[/q^T:2%,MhZb0GB%J5@pW;;:J+&A4?##J5l^je)]0>+(Dn)4+XJTjV>o:978$HV
+=^GTOD/siJJVK)EQ("ACJZXL*d]EqZWi)\hU7e-MS=>t9qjIJQ$(IHUStMgQV5L?]XTOh><N1PO
+JZ\FD!<;cD"I&oLPY-H~>
+^Ae<1F&(oorrV&1s81XQ!<(aTS,iQ%!<;NE!kh?8J\?WJot;E]_8F74aihrTdF6Urf\5-;hr<\X
+kNV9umf3=[oCMtRs776#nF,c2p&FmMj5JnPgtLE3eC2djc-+5L`P]O,J\?WJe%H.'^V@S#_SX4/
+`5T^i`rF$X`;d^X_SO%'^[So<E@7'']n*lb]`A*2h>dQQh?9>Kn!m.'~>
+o)B:#qY'LKlfdHji838Cg"4g+rRDG0f@\d2gtq#Mk3;7%oCr1Rrr`%;:?VHQ!o&>,qqD)NrS%@A
+!<0D,s6n\D\kQC[[Xkm\[R%7&W2#oNPE(KPIX-$QBk1RS<DQ4V5s.+_7K<Bn+<DOC*?H=K-S$i,
+VuPL@92JVl?Y*tjFEr@hM2mdfSti9hJ[U-<e@#mqZ`pU5WMcSfU7e-MSXc5JRgkmYStD[MUSOfe
+X0&V4n[8L9-'3\dJ[Y!T!<<#P!!)oN"I]>VRSA;~>
+o)B:#qY'LKlfdHji838Cg"4g+rRDG0f@\d2gtq#Mk3;7%oCr1Rrr`%;:?VHQ!nMGmqpk`IrRM"6
+!<0)#s6nM?[7XJNXb!VJXWOR>TUV4/N/*"4G]Rb:A7&M@;+jDH4ukJS6N@'j+!(>"*ZZ=H,q1E#
+VZ5C<7ncc\>$toUDKC&NJqo;IQCFPFJZXL*e?'7_Wi)\fTUq^DR[BG-Q'@O2P7<bAQC!u-S"-(C
+U84]enZ;k*,DguRJZ\@B!<<#K!!)oI"I&oLPY-H~>
+^]+A[31TaC!oAV1r8.GRrS@RF!<0Y3s6neG]hVmb]n*li]cFl(_o9[<b08/XdaZk"g"Y??iSrq\
+kNV=#s8V`]rUU!Y*:WFam-F?EqW-Yohqd&?f@JI"d*BkXaN)9;_7kK6J\BRH$GO9j_8=+.`Poj:
+rl=iUrl>&Ys2>2\_ns7*^V9?R"0+:Y[t25D^$WK5s8CgS!;t[VS,i#J:4N~>
+oD]F"p[dk>kiC^ZgY(3.e'ZOgcMc!"cHjkbe(*('gu%,Ql0Rp3q>U'e!mN]pp\t<LK)bc'rrE#P
+!La#f[K-?rgB+r\>Cj56[e@-O['$C(T:2"*MM-J*F`;,.@9cl39h7W94#TV/s'[2urZWC/,q(8s
+1H)33gdt4<='T0GCN+EBJ;&lBQ(">@WNq)`J[X+;&@8XEX/VtlU7\$JR[TV2Q^7T8s-E\P%%3QS
+StDaQVPpPuZ*a24"/IeNY^s66[dCL's8C^P!;tRSRK2ZB9n3~>
+oD]F"p[dk>kiC^ZgY(3.e'ZOgcMc!"cHjkbe(*('gu%,Ql0Rp3q>U'e!mN]pp\t<GF8u0hrrE#K
+!L*T`XT8CiecN6O<e7B(XnJk_X/;S\Q]d>aK78)fDeirn>ZXfu8OYm,3&F)(s'Huo+WqpP,:4ij
+0Jo^-gI4\/;cm:5Anu=,H@CL'NKTWuTrEUFJZ[J)&?;\*U7e*JR[9>*PEM&iO,s7"s,RYOOcbil
+QC"&1StMgSW2oTn".V,?Vh(t$XmN4js8COK!;tCNPQ9m28q6~>
+_>aW7JOJDhrrV&1s8CgR!<(aTS,iQ%!<;NE!kh?8J\?WJot;?[_8=.1aND`Pd*^=mf@ep6hVdDR
+jn\cLqu?]orqclinF,i6oD\Rfr;Z`pp^luNg=Y$-e'ZLebf\#H`59<@]n*lI]aVWi^qmn*`5Ta9
+a2l@$ana*YaoBEha2Z-<`5BI.^q[VX]`NR-Ne+lp^$E?3s8CgR!<(aWS,i#J:4N~>
+p&>^)qXsCGl/gm[g=Oj%ccsYTaN)="`W*pia2lEHc-Xnhf\>9Bk3;=)pAOdd"8dX;htI'OgOfJ(
+g\q3OgB!`CrjDh,n(RoT9j<1WJ[Y6[5d78bTUM.-MhZe1GB.P6@pW;;:J4F5e^W7Os4u)Lcq#Q6
+.kQ;#e(!aapXn0Q\mAl[D/siJJVK)FQCFPEX0dGdJ[X1=&[epJXJr(mTq@mER$X)&PEM(*O:[P;
+PE_?!R$sS<TqeKaXKJo([K:XuM1N*d[d1@%s8C^O!<(XTRK2ZB9n3~>
+p&>^)qXsCGl/gm[g=Oj%ccsYTaN)="`W*pia2lEHc-Xnhf\>9Bk3;=)pAOdd"8dX;htI'OeoUli
+f)>[JecD!8riH2#n(%QJ8lgMFJZ\UI*2fO%R$3PeKR\;kEGT8t?<L9)91MS(eC3%Ls4mV#+@db+
+.4]nre(!aapXe'N\QW<LBPha4H[pd,O->s&U8rjIJZ[P+&Zht/US+3KR?s2&OcPN^Mi3JiM%GQ&
+MiEaXOcu&sR@Be@USb'cXTEJdJq:%TXm<(hs8COJ!<(IOPQ9m28q6~>
+_Z'_i4c]O7rrV&1s8LmR!<(aTS,iQ%!<;NE!kh?8J\?WJot;*S^r"%0aN;WMcdC4kf%A[1h;@/M
+jnJcYna>f3m.C)Q&GFl3f[eR$dEg(\aiDE>_SC`9J\BXJ&&,fp_Sa=2`lH-@aiV]KbP06\bQ#]m
+aiMQD`l5m6_SO%%qRm!75t\J7]n*l^]`A*2hYdHRh?9>Kn!m.'~>
+pAZ]Bq"4%?k2P7Of$i!jb/hQ>_SEq#^:h4o^;%M$`5]mAcI(.ngY_&Sm-s]GqYpZL4c]O7rrUr,
+s8LdO!<(XQRK3>q!<;NB!kM*1J[U-<osPU?XJ_e`Q]d>aK78)fDe`lm>ZXfu;>:(o="Q'Z17@q;
+&Ct9%CN+EAIY3K;PF.o8VlbNYJ[X1=&[\gGWi)YeT:D@;Q'7AmNfK(tMuS\6M\1o.Nf]BeQ'[r0
+T:r'YWi`P6qmHU+5"D]*[XkmP[K-@+g\h-OgB<rFl^COu~>
+pAZ]Bq"4%?k2P7Of$i!jb/hQ>_SEq#^:h4o^;%M$`5]mAcI(.ngY_&Sm-s]GqYpZL4c]O7rrUbm
+s8LUJ!<(ILPQ:]b!<;N=!jtX$JZXL*orSt-URmp>O,JaDI!B^MBk:^X=&Vjd:&"Yk<\#^R0UVY8
+&Ck#oASQ.)G^P*uMia3mT;7%?JZ[P+&Z_k,U7[sEQ^!YpNf8mQLPLT_K`?](KFronLP^nINfT?f
+Q^OA8U84`hqlKsn4%#fpXb!V>XT8D"f)5UJec_3;kEJSh~>
+`;]r=N]bnarrV&1s8CgR!<(aTS,iQ%!<;NE!kh?8J\?WJoXu3Z_8F74ai_iQd*gFof@em5hV[;O
+lKdg(mdKWDnG_bolg!j)mHj0(l0.<linE&:e^MsncHOGQa2Ps4^4EtK^"9q-^VI\&_o9X9aN2KG
+bKS30c1oTac2YurbK@rJaN)<>_ns7*^\kbHL*_S*]n*l\]`A*2hYmNRh?9>Kn!m.'~>
+p\ts+q"*q<jP\eEe'Q=\`l#U+]XkY_r3d<K\@K2`^;7_,b0A;_f\GHIlL4BArVm!!N]bnarrUr,
+s8C^O!<(XQRK3>q!<;NB!kM*1J[U-<osR)kXf/"dR?WbiKn+MnEc#K"?<UB-:3Uc!Des0&B4ba=
+1GgsJ;/C/kFE`%ZJ:r>\BPhd6H[pg-O-H')UoCVM[Xkm>[OnhiXJr(kT:MF;Q'7;iN/NOKLPCM:
+KS5&5L5(M@Mi<[XP*MB&SY)XQWN<>3rO)cY,CtESJ[XdN!<<#PrW)oO"I]>VRSA;~>
+p\ts+q"*q<jP\eEe'Q=\`l#U+]XkY_r3d<K\@K2`^;7_,b0A;_f\GHIlL4BArVm!!N]bnarrUbm
+s8COJ!<(ILPQ:]b!<;N=!jtX$JZXL*orUHYUnF3COc>0LIX6-UChI6a>#nNr8p#&kCh[QpARo:3
+0JP=>:24T`EccMOI=QTL@qTUtFaALhLlIO`S=lg3Xb!V,XV7_4UnF<JQ^*_pNJiXKKnP&/J:IHF
+'7YO`JqSi5M2R@SP*MB&SY2dVXSo7&H6ITcXb!V<XT8D"f)>[Jec_3;kEJSh~>
+`W$%t7">+)rrV&1s8:aR!<(aTS,iQ%!<;NE!kh?8J\?WJoXu6Z_8=.1aND`OcdC4kf%A[1gtprI
+ioK4`kNM0pr9F=H)<g8GjlGF[hqm/Cg"4g)e'ZLdbf\#H`59?A]n*lL]b%om^qmq,`Q#s>ai_fN
+c-=Q5chYrecP=aMc-4ARaiMNB`Pf[1^q[RrZq<WfJ\?WJkIglqrSIPSr8%RH!:QFQJ,~>
+q#;--p[[_8j5/J>dETeP_S3[n[^<?FYcn#.)m?KNZaI9Q]YD>'b0JGdgY_)Vmdp;Ts5-4oqssag
+gOfJ'g]%9PgB!`CrjDh,n(RoT9j<1WJ[Y6[5II\pV4a<DOc5'II<fpRCM%$^=]J<n8k)055!1ne
+3B0#Z4$5\l6UsaD;H6k+@V0CpFa8FgLQ%@]S"QUXZ[oQ9[b8)(Z`gI/UnXHMR$EksNf/aLKnP&/
+JUm]K)M!BiJqSi5M2R@TP*ME'StVsYXKT">X[kXTJ[U-<kI(BjrS.>Pr7_@C!:-(JJ,~>
+q#;--p[[_8j5/J>dETeP_S3[n[^<?FYcn#.)m?KNZaI9Q]YD>'b0JGdgY_)Vmdp;Ts5-4oqssag
+eoUlhf)GaKecD!8riH2#n(%QJ8lgMFJZ\UI5HL`VSX>V%MM6S.GB7Y:ARSkI<DcI^7RKF(4#o8Y
+2DmBN3&s&`5XS"5:/P"o?"%>[Df^/NJ;&lAPF.o8We%:'XkBfkWhuPaS=5b-Oc>9ULP180IXQTj
+H@#O8s*>N/I!pHoJqSl8MiEg^QC489USb)oUdR;;JZXL*kH+aarRUuKr72"8!9]S=J,~>
+`r?+12TtUi!oAV1qq_;QrS@RF!<0Y3s6neG]hVmb]n*lh]c=c%_SjF6aihrSd*gCnf@\g3h;7&J
+ioB+]k3(q*kl9f`k2k[aio/eOh:pW8f%&6sd*BkXaiDB<_SC`9J\BaM'Y_>t_Sa=2a2lBFbKS5V
+cd0tbdF%d<s3^kns3D8%c-4ARaiMNB`5BI-^Q0^hJ\?WJjh1ZorS@MSqq_IG!:QFQJ,~>
+q>W>Np[[\6in`89ccX8E^:Uk]ZELC2WMl_mVP^8hW2co#Yd1[H]YDA)bL"blhW*hfoD>%9bOGN5
+gOfJ&gAh6PgB!`CrjDh,n(RoT9j<1WJ[Y3Z*3lTCU7I[8NerI?HZsLIBk:^Y=]J?p91VK=5sY?3
+)aH\V77^'H;H6k*@:j7lEd)n]Ko1qTR%9tLXb!p3[b8)(Z`gI.UnF9IQBRDjMi!1AJq/?!I!ba:
+(OLOXIt3*'L5:bJOHYuuSY2dVX07@+GCd2R[cOpts8C[P!;kLRRK2ZB9n3~>
+q>W>Np[[\6in`89ccX8E^:Uk]ZELC2WMl_mVP^8hW2co#Yd1[H]YDA)bL"blhW*hfoD>%9bOGN5
+eoUlgec5^KecD!8riH2#n(%QJ8lgMFJZ\RH*2oX(R['"oLOsu$F`D83A7/YE<)HC_7n#a05!Ag*
+)a-AM6:FC::/P"n>[_2XD/j`FIY3H8Od2B-Uk,Y!XkBfkWhuP`S=#S)O,SpNKS"]%I!U$]G'3\(
+(NjnFG^=^bIt<9.M2[LXQ'e)6U8EMeEIk6CXlZYbs8CLK!;k=MPQ9m28q6~>
+aSuA*9l]prrrV&1s7Y:MS,iQ%!<;NE!kh?8J\?WJo=Z*X_8F73aND`OcdC1je^rI-gYL`Di8WeW
+jQ5M$k5XN\jQ#7Yi8<DIgY1<3e^W$occs\VaMu3:_7kK6J\BaM&\l,u_o0R8aN;TKc-FY^d*^;@
+e+qMmdh:*Vd*U+ac-4AQaN)<>_n9&2We%j7^#Zj,s7Y:PS,i#J:4N~>
+qYrGPq"!e7inW/6c,di=]=>5PXfA=sUS=ERT:VXHTV8*UVPpPuZ*h*S_8XRBe(EL:kh&IGp[A+`
+gOfJ!gB!`CrjDh,n(RoT9j<1WJ[Y3Z*ODoJUn=*@OGnsIIX6-VD.mKh?!13+:JFGP7R]`E6QAK_
+7n?6H:fCCt?"%;YD/sfGItNQ9Od;H.UoCVM[Xkm@[M?-PXJ_keSXGb+O,JjLKRnW#H[0gZrcS6_
+rcS6b'7"nOIt<6,M2RCWQ'e)6US:I>UOfk)[cFjss7Y1MRK2ZB9n3~>
+qYrGPq"!e7inW/6c,di=]=>5PXfA=sUS=ERT:VXHTV8*UVPpPuZ*h*S_8XRBe(EL:kh&IGp[A+`
+eoUlbecD!8riH2#n(%QJ8lgMFJZ\RH*NGs/S<oG"M1pJ-G][k>B4G=S=B/6o91_WB6U=$;5TE'V
+6UaL:9M\Pd=Bo6EBP_X0G^P'rMN<sfS=um4Xb!V.XVIk5US"'DQ'%)bLkLA0I<p-]F`VPBrbqgS
+rbqgV'6A8=G^=aeJqSo;NKKHlS!lo(Rt7\mXlQSas7Y"HPQ9m28q6~>
+ao;FA1V`>W!oAV1p>,h?!<0Y3s6neG]hVmb]n*lg]c4`%_SjI7ai_iQcdC4kf%8R.gYCZCi8N\T
+j5^'us5X.=s54UKh;$c=f[n^(e'ZLebf\&J`P]R.J\?WJftA-8^r"".`lH0CbKS5Vcd:(fe'umt
+ebRerec4,2e'cXkd*L"]bK@rI`h"Z&^qYH6J\C-X!<;cL"IoJ\S5+S~>
+qYqE.oBk`#gt0rta25R$[BZj5VPBfUS=5k5rKe@gR@B_=TqnTdY-PLI^Ve.;e(EKC0=(6Kn,EID
+K)bQ!!La#f[K-?rgB+r\>Cj56[e$pIYcOasSX>V%MM?\1G]dtABOtUY>$"[$:JFMT9)_E^8fCAt
+:Jt.n>@(`LBPh^2H$t6uMiX*iSYE$`[=Pc;[bJ5I['6X0Un=0EQ'%)aLP15.I!U!ZFE2A?E,TW3
+DfBZ8EccGJH@10mKSGADOHc-%Ij8O+Y^s66[cFjss7Y1MRK2ZB9n3~>
+qYqE.oBk`#gt0rta25R$[BZj5VPBfUS=5k5rKe@gR@B_=TqnTdY-PLI^Ve.;e(EKC0=(6Kn,EI?
+F8tsb!L*T`XT8CiecN6O<e7B(Xn/Y7Vk]iPQ'%#]K7A5lEc5`+@piPE<`;gi91_ZE7fGgr7Rp!@
+928;^<`r[8@qTRqF*Dt\KSYVMQ(";?XF[L)XkTrpX/D_bS<oJ&NJ`LDJ:;iiG'%_BDJa0)CAhi_
+C27U%DJsN:G'J=]J:iT5NKB?L,%.1DJZXL*jK/F^p=9A2!9]S=J,~>
+bPq\4=CUjfrrV&1s7Ml^!<0Y3s6cBX:0rLbJ\CWf)Sa,+`Q$!@bK\>ZdF6Urf@\d2gtgiEi8ESQ
+r8Rb8(uX</hVHuAg"=p-eC2glcHXPSaMu09_7kK6J\BdN(;@T#_o0R8ai_fOcHjkbdaQ^rf%/I)
+q:P`!s4.h5eC2jnd*L"^bf[n926=^3^qPB5J\C0Y!<;_^!s%e[:4N~>
+qu7Q1o^:r&h:L&ua2,EuZ`^=*US"'EQ^!\rOSt4XOHG`lQ^XJ<Uo18s[(3ogaN_[s<S6U+pAXR]
+!o&>,opPj\rjDh,m[=/N>Cj56[e$pH['$C(T:;.0NerF>I!BaPChREi?X-`8<)ZXjr(e5-;H$Rs
+=^5<CAnc+$Fa/:bKo(hQQ^aYDWNq)`J[X=A)7?`NW2-)VR$<\lM2$Y4I!U!ZEc>r6ChmeaBc(T#
+CMds.EclSPI"-a&M2[OY9du!rW3!7T[XkmK[K-@#RKEQURSA;~>
+qu7Q1o^:r&h:L&ua2,EuZ`^=*US"'EQ^!\rOSt4XOHG`lQ^XJ<Uo18s[(3ogaN_[s<S6U+pAXR]
+!nMGmoooFVriH2#mZ[`E<e7B(Xn/Y6X/2JZQ]mJgLOsu$G&hJ9B4G@U>$"^%:eseZr(@r%:/=_c
+<ENF1@:X"dDfU#IIY*?5O->s$TrEUFJZ[\/)6Bd4TU_C6Oc>3PJq&/nG'%_BD/3iuB4YZQAH-3V
+AnPgnD/XE9G'SIbJq]&=8LK1]TVSN;Xb!V9XT8CoPQLpKPY-H~>
+bl7aQ0sg0F!T&M$!<0[u!!$>V]n*lf]c+W#_Sa@5aND`Ocd:(geCN7(g"P39h;7#Ghu)F4huDOJ
+h;$c=g"=p,eC2glcHXSUaN)9;_SC`9J\BdN(V[Z#_o0R8ai_iPcHjnde'uq!f@S[.g%jA%fbE)j
+f@JL%e'cXicHWFFDoTf8_nj->]n*lY^%24*n!m.'~>
+r;R]5p@.A.h:U0"`kf<sZE:($TU_C7P)kT\M2;+c)2O0.NKB?iR@U%JWNNS;]u#gYPhFsUlgai@
+rrLl+o)Sculi7#iJ[U-<o!TIAXJ_eaR?`kmLkL8*GB@e@C1^sa?<gZ9=&o/t)-0g@>$PBB@qTOn
+EHQMRJ:r`;Od2B,USk5F[Xkm@[McBRWMH2XR$<\kM1pM0HZsUQE,BB)BP(gdrF6^UAS,UiCMe$2
+Fa&.\JV8l',>skuTVSQhZ[oQ9[cY$i!!;JT9n3~>
+r;R]5p@.A.h:U0"`kf<sZE:($TU_C7P)kT\M2;+c)2O0.NKB?iR@U%JWNNS;]u#gYPhFsUlgai@
+rrL\lo)Sclli7#dJZXL*nuWh/US"!@Oc>3OJUMfeEGfQ)ARSnM>$"a(;Gm?gs&'Y4<`iO1?=IJZ
+CN"6:H@CF!MN3jcS"HL-Xb!V.XVn+7TU_C7Oc>3OJpr&kF`D>:C1q3i@prbPrE^@K?t!PUAnYpq
+DfKlDH[^Qc+\n)_R%0hFWe%:'XlcbW!!;>J8q6~>
+cMn"<AlS-]rrCo,mt'rKn,DhUnc/1ZoD\C\p%nC[p\OU_p&4O^oDeC\nc&$/mt'r[n,DhUnc&+Y
+oD\C[p%%hTp&=ReoC@`"bjtc'rpYL-Ja_1Y!Luo8~>
+r;SePo'>Dpg!e3d_7[4]XJ_eaR?`npMhm(>Jq/B$It3*%KSG>AO-5ftT;/?eZE?ke\^&^Yi90M!
+rpg!ggO\[AlcSN4l/CFJd)s>B]!SZ@UnF3DP)bHUK7SJuH$=CRrcJ0_(jC7PIY!-,MiO!gS"QUX
+YdD!V`QHTZgus=TJa;(V)sH;:f$V[\^q7"YX/;V^R?`noMMHk9Isl]jHN&1.H@1-jJV/`8NKKKn
+SYDrg.[[f^`QHQXgu7OLl[eBSlN*GKJ,~>
+r;SePo'>Dpg!e3d_7[4]XJ_eaR?`npMhm(>Jq/B$It3*%KSG>AO-5ftT;/?eZE?ke\^&^Yi90M!
+rpg!geq*"8kK;s,jk\S;bf@Q4[]up3U7I^:OGo!LJUVulGBItJrc8$[(j1%JI"$X#Ll@F\R@U+N
+Xg,=I_8jgLf]7VHJ`keN)s#l.e'5tN]sk;LW2#uRQ]dDfLP:>0I=$9bGlDn*G^=^bIt<</MiX$e
+R\-<\.[INU_8jdJf\P\@kCMgKk5gf>J,~>
+ci4'j1Ss:7JXh:]aIF*<TVA9]WiWA-ZaI9Q]=kqo_Sa=2a2lBEqTAi[(!+G7`5BF,^:h.h\$`NG
+Y,nV#V4sT5S:R3aS/IolUSaujXfo%;[^`o^^;.V'`Q-'Ab08)Sqp$)(bfn8QaN)9<_SEn!RpNG.
+ZEUI3W2?AaSUm;^SCa82:4N~>
+rVnqUo^:o$gXONi_S!=^X/;S\Q]mJgLP15-I!U'_GB\:WH@13nKSYSKPaJ#9VhuaD^;J(>f%f9L
+n+ZAPJXV.YaI4$5P)kKUK7JAqF`MD:BkCma?<p`:<`N'r;GmEi),X:0;cQk#>$YKDA7fOlDfU#H
+I=R!+MiX'QRXpp^RQ?k%Oc>6QJpr&jF)Yu2An5=V>?Fp*;G^.`9MA)O8kViO9i"S`<*!+*?=78T
+=#Y#<G'\UhL5CnPQ@YKURb*u.9n3~>
+rVnqUo^:o$gXONi_S!=^X/;S\Q]mJgLP15-I!U'_GB\:WH@13nKSYSKPaJ#9VhuaD^;J(>f%f9L
+n+ZAPJWt_MaHRU*NJW@@IX?<]EGfQ*AR]%Q>?P$-;c-@e:/:d_s%XA+:f1.k='8a6?t*\\CMn-6
+G^FplL5CqAP_#(RPWG"hMhm%:I<g!VDes-"@UNJF=B/6r:JFMT8P)HC7n?3C8k_rS;,UCq>$PED
+;`/9-EclYUJ:r]9Ob&aJPh2-"8q6~>
+ci4%'jQHPo!.b-i!#Z%P'H/)@.krqD5Xe:@;cd11@V'4fCi401rc&fpDf0B+BOtXZ>?=`u8ju!,
+2D?X-*uP_#!J(6%!8@K8":GhZ+!iEl3'K`&:K:S*A8,q%G'\UgK8,2=MMmCMM26n>JUVohF)G`(
+?s?W-8jkj&1+Xao)%m>YJH16$f)U=~>
+rr3u;p[RP/h:Brq`4`XbXJV\\QB@/_KReJrGB@kFrGW]qF*2\QI=[*/Nfoa"U6;"P\\H,,db*F<
+m.1)Gs+(0$!.b-$!.b-$!.b-&!.Y~>
+rr3u;p[RP/h:Brq`4`XbXJV\\QB@/_KReJrGB@kFrGW]qF*2\QI=[*/Nfoa"U6;"P\\H,,db*F<
+m.1)Gs+(0$!.b-$!.b-$!.b-&!.Y~>
+Zi>THJXj]L(8%:rVPpMrYHY=>[^WfZ]Y;.r_8=+-qS`EO'>hT$^V7@m\[T#SZEUL5Wi2eiTn/_b
+SCsDNT:r'XWN32+ZaI9R]Y;2!`Q-*Cbg+P]dF-M@e/HfadEp4bbf\&J`P]O+]t1_^Z`pU6WMcPc
+Sq3D_SCa9]~>
+rr3u8o^1f!g!\*a^U^\QVkKTGOc+sGI<g!VDf'9(rFd-bCMe$3G'\UiLlIRaSYE'c[(=)ocICV-
+kjS9;s+-ViR`:d5R?WemM2$Y5I!KmVE,KH*B4PL\?X@#C>PqY@>?kH??t!PUB5)1"E-$2JI=Qs)
+MN*acJXV.YgR9+MQ&pu^Kn4YtF`MA7B4G=T=]SHt:/"8M7RTU1rBVAh6UXC68PDlU;c[%,?t3e`
+D/j]DI=R!,N0'?VRXppZRXb~>
+rr3u8o^1f!g!\*a^U^\QVkKTGOc+sGI<g!VDf'9(rFd-bCMe$3G'\UiLlIRaSYE'c[(=)ocICV-
+kjS9;s+-DcPfAq(PE(QVKRnPuGB@hCChdTn@piYL>?Y03qH"G7=^#'9?XRATB527$EclVRIY!0.
+MirXUJX"oR)j?>@LP(,)G][qBC1^s_>Zk*+:eaSS7n#d362Nkb5sdq-7S-6I:f::r>[LrPBl.g2
+G^FpmLPq7FP_#(NP^i~>
+Zi:#qJH16$`W.dr$4msl+=8Tm2*!ie7S6EQ<**4,?!guJ@:EYR?sd2D=]\R"9hIlA4ZP>P.O?2V
+'b:Ct!.b.(!#u+L&fDc</MfFQ7nlob?Y*tkFaAOiLPq4VQ'[m:RN.`^Q'.2lP_ag8F`;,-?WpE(
+7mT3n/LMYY'+=qn!.b.&!.Y~>
+s8O,=q!mY0gss`l_Rm4YW1ofJOc+sFI!9XMCM79h@fBaU@:EbZBl%a1G^Y1!N09R"UoLZ-]u/">
+fA>WTo)84\!1JH=JH16$JH16$`;frO)[_,rJH3RfJ,~>
+s8O,=q!mY0gss`l_Rm4YW1ofJOc+sFI!9XMCM79h@fBaU@:EbZBl%a1G^Y1!N09R"UoLZ-]u/">
+fA>WTo)84\!0i$7JH16$JH16$`;frO)[_,rJH3RfJ,~>
+Zi:&r!.j!XhSn=[hr*GOio9"YjQ5Lck5OQCkk=9?kl0cFk5XNJjQ#:[io/hRJ_kt7fA7D&i8N\U
+jQ5OdkNM0qlKdg(mI'N:q"t!eo_J%ZpA4aertG>(mHs9+lK[WtkN:pgjQ#7Yi89+BJ_o#8J,~>
+s8P:\p$V#$g!\'_^:1AIUn3p8N.uk0G&_>3A78eL>$4s0=^#';@V'7jEd)n^LQ.LcT;AWp\\H//
+eD&sGn+lVU!La">gO\,!gDAMic,df;]=,&LX/MhfSsu+6P`h/jO,j4!(64H;OckrqR%'\@Uo:>t
+Za[Q]`5p3SJ_Pb1g=mt.eBZ.P]XG)GV4a9BO,AX@HZjCGH^D1ki8AZT;,C%a:f1D\a7'$-'^<)O
+FaAOkMN=!jT;AQl[_0JucIRR$J_Si3J,~>
+s8P:\p$V#$g!\'_^:1AIUn3p8N.uk0G&_>3A78eL>$4s0=^#';@V'7jEd)n^LQ.LcT;AWp\\H//
+eD&sGn+lVU!L*S8eq)DleecfZaMYd)[^**;Vkg#WR[9;'OcPK\N/R[m(5n-1NK93cQ'[u2TqnTe
+YHt[L^r4=AJ_#D'g=@:pd)s;@\?`67Tq%I4N/*"5G]Rb;H'Ykgi88QP:]4#k:KWh$n,E>$l*YYS
+G^Y1!N00HsTr4ut\%T]$d=Kl"f%AQ(~>
+Zi:&r!.j!XhSe7[hr*GOio9"YjQ,Fak2uX*p?;M=roX7Bs5a4?s5F+=i8B1CJ_o#8'Aqa,io9"Z
+jlYail07L!m-X3.p&"ahp&=R_o`+L_qYpNprr2p1r9s%>lg!a!ki_*ijQ#:[iS`UEhLXP9hLG~>
+s8O,8o'>Amf$DFR]!ST:TUD"'LOjepE,0&p?!:</;Z0H4;cQn'?=RVaEHce^LlRaiTr>-%]Yhn>
+f\biYo^r.aRK.onJ_S/u("gpYaMbm,\?rKBWi)YdSt2@=R$O$8PSBCKR$jG7T;&-ZWiiV7\@fVq
+aN`7dgO\,4gD&;gbf7H0['$@&SX5LtL4O_rEc%`OrrR@;9)V<^9#CT-!W2Qhrt=[MG'eanMij?r
+U8Y3#\\H,,d=L&'gXt82~>
+s8O,8o'>Amf$DFR]!ST:TUD"'LOjepE,0&p?!:</;Z0H4;cQn'?=RVaEHce^LlRaiTr>-%]Yhn>
+f\biYo^r.aPQ69cJ_%fk(":CJ`5'!o['6X2VPBfTS!fV/P`h4-OoLRWPa7Z(S=ZFLVlHl([(*``
+`5p;Veq)E*eeHTXa2,BrYc=LkR?NYeK78)fDec0Hrs3^=8Ou?A84gYsrrN#irr3VsIrfj_Jr#DM
+R%C+QYI2!Y`ls"bJ_&K)J,~>
+Zi:&r!.j!XhS\4Mh[8<#iSrkWj5f:_jo+?8kPaQCjo=EAj8\-=i;qloJ_kt7f%q>&i8N\UjQ5Od
+kNM0qlg*p)mdKiKrVH?is7Z<])uKU/p%%\Dp\t3imHj3*lKRNqk2tddj5T%UhgsX8hV-fes6bC~>
++92?7nEAibe',eF\$2j,S<f4mJp_`\CLpmX=&Vpi9E%L(8kVoV<*3C6Ao)L3I>!K?Q_("RZFRck
+cIL_1lLFiGrrJPgJ_Pb1`7l!Zda#tR_S*OhZ`pR3W268_T:VUDr0n@iSXuIIUSXohXg#.?]"Pu#
+aj/LhgO\,3gE"hjahtg$Z)a^nR?W_gK78&dD.ogHl,U12s)CLrrB_Mm_<@P-;,q23rVtbqG^Y1"
+Ng#m'UoLZ-]Y_b9fn%n/gY:H`s6Y=~>
++92?7nEAibe',eF\$2j,S<f4mJp_`\CLpmX=&Vpi9E%L(8kVoV<*3C6Ao)L3I>!K?Q_("RZFRck
+cIL_1lLFiGrrJ>aJ_#D'`7>XPc,mr@]t(SWYH4_$UnOEOS=5k5r0J(aR@B_;T:r'YWN<;/[^j)f
+`Q?PZeq)E)efE,\`P8siXf%k_QB@)[J9uEXCM'FCl,U.1s):@nrBVGk^uqA*:K(c,rVt_mFaAOk
+Mia6pTr4ut\A#o)e:H2%f%\aVs6>+~>
+Zi:&r!.j!XhSS.LhuDU9iSrkrj8\3=jn@j8jo=E@j8\*@iS`YOJ_kt7f&$Ga);sK5j5f=akNM0p
+lKdg(mdKW7nac8Cs8Vfhoc*Yuo^qbGo'uJSs7,LClg!d"ki_*ijQ#7Yi8B1CJ_o/<!rne(J,~>
+63$lUmH3<YdE08;[&p3uR?EJ^IX#jYPd%X)?VF$\6UF()6:=:e^>7emRV6PZH%:X/PFA2DYI;-_
+bL5)&kjS??rrJPgJ_Pb1_qQ]qeBZ4W_nWjp[^33@X/`+qUnjc[U7n<UUSO]_W2co$Yd:dK]YMG*
+bKnjmgO\,3gE,(ucH*l7[BHR)SX5IsKn"DjDeW`uAQ;T?s8Qn#4oIJ`4_R8Q8PDr\>-Iu+NH9Ap
+Ko;(ZS>)sb[Ca8qc..C"J_Su7!rn_#J,~>
+63$lUmH3<YdE08;[&p3uR?EJ^IX#jYPd%X)?VF$\6UF()6:=:e^>7emRV6PZH%:X/PFA2DYI;-_
+bL5)&kjS??rrJ>aJ_#D'_q$?gccX8E^Upt_Z*17/Vl$8aTqJ$LSt2IET:hmPUo(&iXKSn:\@]Mm
+`llk_eq)E)ej.d3ahtg#Z)a^nR?NVdJphlaD.d<m@oH07s8Qju4?GSb4$7.C6UsaD;cp4&s,1l@
+I=d66P*hi:Wj0"F_T:)Teq)E-ecPl9[=A~>
+Zi:&r!.j!XhS@tPhr*GOiSrkrj8J'4jo+9>j8\-=iW%g9hgsX8hUUI%hr*JQj5]4^k3(smlKdg(
+mI'H4naZ2Ap&G'dq=aj]s7?<_rpp*h&bPJXm-Es$ki_*ijQ,@\iS`UEhLXP>h?3eJS@sF~>
+('".%lf?mPcH!`2Z)XUjQB-iQHDp?2rsE=,69[Lm3B9,_WVc]1dqs#GI"R9;Q_(%TZb"#qd+@.:
+mI^)O!La">gO\+rgCr;jd*0SM_S<ao[^<<DY,n\(Wi>ur&uhn2X/rJ.ZF%'N]YD>&aN`2fJ_Pb1
+f@rRCd`f_G\[/E9TUM+*M1^5#EGT5q>?4TpA,lRA3B&iR2)[BR4?l2(9Me`.s8Sm7G'nmtNg-!*
+VQ@)5^W"CEJ_Pb1h:i&3R[Ug<~>
+('".%lf?mPcH!`2Z)XUjQB-iQHDp?2rsE=,69[Lm3B9,_WVc]1dqs#GI"R9;Q_(%TZb"#qd+@.:
+mI^)O!L*S8eq)Dhee?T\bK%Q;]t:b]ZEUI4Wi2hmVPX9f&uDJ'Vl6VsY->4>\%BAj`5p6SJ_#D'
+f@D"lc,[Z4[BHR)S<o@rL4FSlDJ<Te=]A0h@K6@>3&^^l*B#l<5!h_2:/c$0s.XCPH%1O+OdDT4
+W33M>_8a`Neq)E.ecYr:PdQ#~>
+Zi:&r!.j!XhS7qIhuDX7iVqj8j7_R4j8S'<iW%g9hgsX8hUC=#hr*JQj5f=akND'nlKdg(mdKZ7
+nac;Dp&G'erqHHfrqHHd)>3XooCDGOs7PgIm-Es$l0.<mjlGI]iS`UEhLXP?h?<kKSDN+Q~>
+6N?iNlJgRJbf.<)YGe.`PDk3EGI[\QnD+'D?pHe41bpd?1Pu/3Vd!Dmp]&3JEd3(gNKfs.Wj0(K
+a3N5kjQlF:pAY/^!.imUgVDPRf@%sfaMbs1]XkV][Bm.;Yl:j*YRRnE[C3TW]YD>&aNMl[J_Pb1
+e_<CAd)s;?\$;s/SsY\"L4FSlDJ3Kb=&Ma`?iU.81GCI7/h\n72EF#g85)lfs8Sa/F*W7hMisI!
+UoLZ-]u.t<g4A"0gY^`gs-fD2gOK~>
+6N?iNlJgRJbf.<)YGe.`PDk3EGI[\QnD+'D?pHe41bpd?1Pu/3Vd!Dmp]&3JEd3(gNKfs.Wj0(K
+a3N5kjQlF:pAY/X!.i^Pf"fiHd`oqS_n`st\@/cMZ*1;/XT#:"X:;>9Z*LaF\@]Gj_oBjHJ_#D'
+e^d%7bJq?.Z`U.!S!B%kK7.ubCh@'Z<DZ=X?N:%71+t73/M8\32*!fc7S6H^s8S^,EHch_LlR^g
+TVnls\\H,,eUc;&f&,$]s-/c!epm~>
+Zi:&r!.j!XhS%eGhuDX6iVhd0j8J!:iW%g9hgsX8hU10uhr*JQj5f=akNM0qlg*p)mdKZ8o(2MG
+pAb0kq#C0hp`&u$p@\(MoC`.`na>f3m-Es$ki_*ijQ#7Yi89+BJ_o;@!rnd\rn`/~>
+6N?fKki(4CbJV!"Xeq_XOGSR9FH2Q'=F'rH=unMq/Lr8"2XpaF4$cA2N;rp4DKUA\MisL%W3<YD
+`QZidip-(4pAY/^!.imUgV;JQg=FZsb/hQ=_7mRo]"#6G[LK^U]">Vi_8F75bKeVkJ_Pb1eD!:>
+ccEu9[]la+SX5FqKRS/dCh@'Y<)6(Q>6"V0/Li1s-RgMs0JtjS6V1%.s8RO`EHch`MNF-oU8b?(
+]Y_b8fR_e.gYgffs-fDUgOK~>
+6N?fKki(4CbJV!"Xeq_XOGSR9FH2Q'=F'rH=unMq/Lr8"2XpaF4$cA2N;rp4DKUA\MisL%W3<YD
+`QZidip-(4pAY/X!.i^Pf"]cHe^;U_`l#X,]XkV][^<BHr36a;Za@0L\@]Dg_8F:7d+*]uJ_&?%
+6.!fn^:1AKV4X0>N/)t2F`1u(?!(!!7m^AYs'@6*-mg8h.4d,/3'BSu9SWTII;!M?H@Ud0P*hi;
+X0K.I_ogGZeq)E1ecPl9PlB6a~>
+Zi:&r!.j!XhRhYEhu;R5iUl./iVqa8hgsX8hTt$uhr*JQj5f=akNM0qlg4$,n*fc9o(2MHp](9h
+q"je*q"OLUp%7kRs82<Smd9B,lKRNqk2k[aio/hRJ_kt7i8+\<S=JHms6bC~>
+6N6]HkMOq=ahkWqX/);PNe`.0EGAug<H\?A=#DW\-6j]YFT;5)2EX>u;!%_mCiaoRM3+'rVQI8=
+_opK^iT]k0pAY/^!.imUgV)>Ng=FWrbK7fD_ns4(^:jHW%)'Bi^r"".a2uQNeCoK.J_SW-6.F3$
+_7R+XW1f]GO,/C8F`1u(>uslr7R1)Us'$ls+sA*R,UY)r2**rj:?)<'@VB\&H\%!5Pa\;DXgG[U
+a3E4egO\,<gBR\HRbQTsm=5~>
+6N6]HkMOq=ahkWqX/);PNe`.0EGAug<H\?A=#DW\-6j]YFT;5)2EX>u;!%_mCiaoRM3+'rVQI8=
+_opK^iT]k0pAY/X!.i^Pf"KWDe^;R^`l5g2^V.7k]".aK%(Ws]]=ktq_SsR<d+*]uJ_&9#6.!`k
+]XG)FUn*j8N.lb,Ec#Gt>?+Hj6p=ZOs&pcq+WqmN,UOun1c[`e:#Z-%?tO7rG^b@)OdDW6WN`hD
+_T:/Veq)E2ecu/=Ph+Fcl@8~>
+Zi:&r!.j!XhRVMBhu2L,iVh^7hgsX8hTjsuhr*GPioB+]k3(smlKdg(mdKZ8o(2MGp%SLdqYC$b
+s7mT.p\+:PqZ$QdnF,f4m-Es$ki_*ijQ#:[iS]:DJ_oAB#O]j,^#&2%eUR~>
+6N-TEk2+_9aM>?lWhZ&JNJ2h*DeNQ^;KVs=<%odI*ul1;YQ)fs1,qKf9s=T`C2nKKLQ7[kV6%#8
+_TL9Zi99Y,pAY/^!.imUgUl2Jg=Og"cHF>Na2Z'9r5/l[`Q#s>aihuWe_5T/J_SQ+6.F0"^q-kS
+VP'BANJE%1FDYZ!>?+Hj69J6Is&UEd*#]_8*[2p]0fD-\[f?,G@:sFuH%1R-P*qr>XL#IP`m!"b
+gO\,=gB[,iR_%8@bgV(~>
+6N-TEk2+_9aM>?lWhZ&JNJ2h*DeNQ^;KVs=<%odI*ul1;YQ)fs1,qKf9s=T`C2nKKLQ7[kV6%#8
+_TL9Zi99Y,pAY/X!.i^Pf"9K@e^Dadai;<;_SO%'r4`TS_84",`Q$$Dd+*]uJ_&3!6-mWh]=+oB
+U7@R3MM-D&Ebf5n=Aqpa5s&$Fs&L<b)]BV6*[)gZ0JtpX[K$#C?=[ejGC>+#O-Z<1W3<V@_8jrS
+eq)E3ed(K^PdT*-aj5J~>
+Zi:&r!.j!XhR;;>htH"-hgsX8hTOb@hr*JQj5f:`k3(smlKdg(mdKZ8o(2MHpA"[fqYL*dr;?Hh
+qYBp]p\+F_rq>mOn*]T0lg!a!kND!hjQ#7Yi.9a9hW!Atm`h98hX8XY]mp~>
+6N$KCjkeS7a2#3iWM5iFMhHM$DJ!6W:icU9:b3q8)&3btec23g/i>aY98roNE,TrLL5hIgUoUf4
+_9('VhrjG(pAY/^!.imUgUPuEg=Oj$cHaYWb0'_*s2kPhbg+M_f%P]0J_SK)6JBo4`kT'iXJMPV
+P)P*EH#mh7?s-E&7mT16s8Q%>)&<l!'c7u:-n[>;RK*8J=^P`VEd<.gMisI!V5po3^W"CGJ_Pb1
+j4ak,baQ,tmED$1J,~>
+6N$KCjkeS7a2#3iWM5iFMhHM$DJ!6W:icU9:b3q8)&3btec23g/i>aY98roNE,TrLL5hIgUoUf4
+_9('VhrjG(pAY/X!.i^Pf!s98e^Ddeb/q^'`r<sV`WaE)b0JDbJ_#D'cIP>4cH!c5[B?I%S<].l
+Jphf]C1CON;+j>B3DohV;]Q_j',)&s*?lj_1HCj&rf:,d@qfk)I"I07Q(+JFY-bgW`mB:fJ_&l4
+#jTNr[FXWbPdQ#~>
+Zi:&r!.j!XhQYl6hgsX8hSn>;hr*JQj5f=akND*olKdg(mdKZ8o(2MHpA"[fqtg3fr;HQjqtg-`
+p\Fjhq"!tEn*]T0lg!d"ki_*ijQ#7Yi89+BJ_oJE$1?'.^#&2%SA!0t~>
+6MpEAjk\M5a1o-gW1fZCMh?D!D.R$S:NHL8:F[S/'b:Z[nGe1f/2K=R8U:@9J8TOYKoD7cUT1W1
+_8t!ThraA%pAY/^!.imUgU5cGg=b-0e^W'qdF-Oof%8Q*gO\,%gHsTAbf.?,ZE'gnR$*A]Is?!L
+AR8J:91;');#gPm)AE_l$kO*j+!iElO8o6F;-.(7CN4TJKo;(\StrBk\%]f(dt-8)gZ7)qmED$1
+g[34R]#oO~>
+6MpEAjk\M5a1o-gW1fZCMh?D!D.R$S:NHL8:F[S/'b:Z[nGe1f/2K=R8U:@9J8TOYKoD7cUT1W1
+_8t!ThraA%pAY/X!.i^Pf!X'=e^W'qd*L"]bg"J\dF-Kpeq)Dpej@m2a2,BpY,@t_Q&^ZPI!'@@
+@pE&28OG[#:]LGl)AE\k$kF$i+!`<iNrT-E:K:Y/BPqs>Jqo>MR\?X]Zb!rlc@OPtf&YBglH,9u
+f':AA[DdX~>
+Zi:&r!.j!XhLXO7hLXPOhB(S4iSrnYjlYail0@R"m-X60nF?)@o_%qQs8Vunr;HR8r;6?dq"k$j
+q=F1InF,f4mHa*'l0.<mjlGI]iS`UEhLXPFh?r\qSA!eIc()K(hLG~>
+6MpB@jPAA3`kT!eW1fWBMM$7tCh6mQ:2p75:+7>)&dngGr;V$e.l'.O8T4Y/Li.BaKoD7cUT1T0
+_8t!ThraA%pAY/^!.imUgO\+1gO\,JgHsTAbJh3*Z)a[lR$*A]IX#jJA6r>78jkg$:B1>j(_R5]
+"q)"Z*@*+fs8SKY:f^k3C2nHHKSttZStrBj\%T`'dXg/(gZ@/smED$1g[34R]%bti~>
+6MpB@jPAA3`kT!eW1fWBMM$7tCh6mQ:2p75:+7>)&dngGr;V$e.l'.O8T4Y/Li.BaKoD7cUT1T0
+_8t!ThraA%pAY/X!.i^Peq)D'eq)E@ej@m2`kf6nXf%k^P`CNNHZa4>@U)o/8OGTu:&k5h(D.#Z
+"ptnW*$Znbs8SHW:/kG+BPqp=JVT5KR\6R[Zamlkc%4Gsf&bHilH,9uf':AA[FWoZ~>
+Zi:&r!.j!XhLXO7hLXPOhEg&WiSrnYjlYail0@R"m-X60nF?)@o_%qQs8Vunr;HWorVZQhq>1*j
+q=O:LnaQ#8md9B,lKRNqk2k[aio/hQJ_kt7k2$L6c()K(m`h98hX9NV~>
+6N$KBjPAA3`kT!eW1fWBMM$7tCh6mQ:N6@6:FRJ+'+>*Rs8R3d.l'.O8SeA+N,EfeKoD7cUT1W1
+_8t!ThraA&pAY/^!.imUgO\+1gO\,JgHsTAbJh3*Z)a[lR$!;\IX#jJA6r>68jkg$:B1>j(D$oU
+!soMS*@#t2s-lAI:f^k3C2eBFKSknYStrBj\%T`&dXg/(gZI5umED$1g[34R]%cW5J,~>
+6N$KBjPAA3`kT!eW1fWBMM$7tCh6mQ:N6@6:FRJ+'+>*Rs8R3d.l'.O8SeA+N,EfeKoD7cUT1W1
+_8t!ThraA&pAY/X!.i^Peq)D'eq)E@ej@m2`kf6nXf%k^P`:HMHZa4>@U)o.8OGTu:&k5h((U`S
+!soJQ*$Te0s-l>G:/kG+BPhj;JVT5KR\6R[Zamlkc%4Gsf&kNklH,9uf':AA[FXX$J,~>
+Zi:&r!.j!XhLXO7hLXPOhB(S4iSrnYjlYail0@R"m-X60nF?)@o_%qQs8Vunr;HR8r;6?frr;if
+o^hYDnF,f4mHa*'l0.<mjlGI]iS`UEhLXPHh@/hsSA!eIc()K(m`j:4~>
+6N$KBjk\M5a1o-gWM,cDMhHJ#D.[*U:icU9:b*e3(D.,fq>Ymj/MoOV8oan2L2V6aKoM=eUT:]3
+_9('VhrjG(pAY/^!.imUgO\+1gO\,JgHsTAbJh3*Z)a[lR$*A]IX#jJA6r>78jkj%:]LGk(_R5_
+#Rh=_*d.G]SNT>4:fgq5C2nHHKSttZStrBk\%]f(e:HA*gZR<"mED$1g[34R]%cVrdsq~>
+6N$KBjk\M5a1o-gWM,cDMhHJ#D.[*U:icU9:b*e3(D.,fq>Ymj/MoOV8oan2L2V6aKoM=eUT:]3
+_9('VhrjG(pAY/X!.i^Peq)D'eq)E@ej@m2`kf6nXf%k^P`CNNHZa4>@U)o/8OGX!:B1>j(D.&]
+#R_4\*H_8[S30,0:/tM-BPqp=JVT5KR\6R\Zb!rlc[jYuf&tTmlH,9uf':AA[FXWbc[Y~>
+Zi:&r!.j!XhLXO7hLXPOhB(S4iSrnYjlYahl07L!m-X60nF?)@o_%qQs8Vumqu-F5qtg3hs82N_
+o^hYDnF,f4m-Es%l0.<mjlGI]iS]:DJ_oSH%IVK2^#&2%SA!eIc()It~>
+6N-QDjkeS7a2#3iWhPuHN.l\'DJ*?Z;0)^:;(a7@*#KG,li2to0K)'_9Rd$AIrKU]L5qOiUoUi5
+_TC3Xi90S+pAY/^!.imUgO\+1gO\,JgHsWBbf.?,ZE'gnR$*A]IsH'NARAP;91;'*;#gPm)\s"q%
+M9EoDuK^/3'Kc(;-7.8CN4TJKo;+]StrBk\%]f(e:HA*gZ[B$mED$1g[34R]%cVrR_""~>
+6N-QDjkeS7a2#3iWhPuHN.l\'DJ*?Z;0)^:;(a7@*#KG,li2to0K)'_9Rd$AIrKU]L5qOiUoUi5
+_TC3Xi90S+pAY/X!.i^Peq)D'eq)E@ej@p3a2,BpY,@t_Q&^ZPI!0FB@pN,38OG[$:]LGl)ANen%
+M0<mDZ0U.2a'N":KC_0BPqs>JqoANR\?X]Zb!rld"0c!f'(ZolH,9uf':AA[FXWbPdQ#~>
+Zi:&r!.j!XhLXO7hLXPOhAbA1iSrnXjQ5OekiqBum-X60nF?)@o_%qPs8W)prVIW3qu6Wmp\+:P
+oCDG@n*]T0lg!a!kND!hjQ#7Yi.9a9hWWf+m`h98hX8XY^#&2%SA!0t~>
+6N-TFk24e;aMGHnX/)8NNJ;q,E+rcc<-A6@<AH*Q,9IsJbl=^r1cdom:6kkXDK:#QLl[jnV6%&9
+_ogE\iTTb.pAY/^!.imUgO\+1gO\,JgHsWCbf7E.Z`L$rR?EM`IsH*PB4+nB9h\#B=TAD),p=<E
+'c.d(r;WcX5Xe@E=C,EJCialOKo;+]Su&Kn\A-#,eUcJ+gZdH&mED$1g[34R]%cVrR_$Xl~>
+6N-TFk24e;aMGHnX/)8NNJ;q,E+rcc<-A6@<AH*Q,9IsJbl=^r1cdom:6kkXDK:#QLl[jnV6%&9
+_ogE\iTTb.pAY/X!.i^Peq)D'eq)E@ej@p4a2,BqYGe1cQB-lTI<TXFA6i;891hW;=9&;',p=9C
+'G_U&r;WcW5=A+?<a9!ABlJ6CJr#GPS"Za_[(F/pd"0c!f'1`qlH,9uf':AA[FXWbPdSJ\~>
+Zi:&r!.j!XhLXO7hLXPOhA+r+i8WbVjQ5OekiqBum-X60nF?)@p](3g!<)Zl&bkb^mHj0(l0.<m
+jlGI^io/gHhLXPJh@K&!SA!eIc()K(m`h98hVNb~>
+6N6]IkMY%@b/1ctXJMMSO,/@5Ebf2k<d=ZE=Z8)f.46DgVZ5C,3'Kc(;S<%iD01,VMNO:!VlmG@
+`66W`ip$"3pAY/^!.imUgO\+1gO\,IgD/5_a2#9nXf%h\PDt?KH?=%;@9Z`<p\t@]*$$-Kp\tl4
+B5M^9J;0&IR@pFYZamlkc.@O$J_TJE&+.T0]%cVrR_%8@baQ,tgOK~>
+6N6]IkMY%@b/1ctXJMMSO,/@5Ebf2k<d=ZE=Z8)f.46DgVZ5C,3'Kc(;S<%iD01,VMNO:!VlmG@
+`66W`ip$"3pAY/X!.i^Peq)D'eq)E?eeQNP_Rm7\WM>uMOG\^?G]IV3?Wg<5p\t@\)]TsIp\tl2
+ASZ:1I=mE=QCO\JYI2!YaO5XjJ_',;&*h9$[FXWbPdT*-acs3aepm~>
+Zi:&r!.j!XhLXO7hLXPNhA"l*iSrnYjlYail0@U$mI'E2nF?,Es8D`nrV-=(p[@P;m-Es$ki_*i
+jQ#7Yi89+BJ_o\K%IVK2^#&2%SA!eIc()KHhLG~>
+6N?iMl/C@FbJ_*%Y,@q\Oc"d=F`(i#>'g5K>s1/(0eP%0B`J*95!qn;=RlF!E-HbbN0B^)WN`kG
+`m*#gj6H47pAY/^!.imUgO\+1gO\,IgD/5`aMPQsYGe1bQ&gcRI!0IDA6rAGp\t@b+s\J_p\tl5
+BlA-@Jr#GOS"Za_[(F/pcId^&J_TMF%IMB.]%cVrR_%8@baQ-BgOK~>
+6N?iMl/C@FbJ_*%Y,@q\Oc"d=F`(i#>'g5K>s1/(0eP%0B`J*95!qn;=RlF!E-HbbN0B^)WN`kG
+`m*#gj6H47pAY/X!.i^Peq)D'eq)E?eeQQS_nEL`X/)>RP)P-FH#mh9@U)r@p\t@a+X88\p\tl4
+B5M[6It`fCQ^snOYdV3]ajYglJ_'/<%I2'"[FXWbPdT*-acs44epm~>
+Zi:&r!.j!XhLXO7hLXPNhAkG2iSrnYjlYail0@R"m-X60nF?)?oCV_Lp@n=Yq#C*gp)*JpoCMPC
+nF,f4m-F!&l0.<mjlGI]iS`UEhLXPLh@8ntSA!eIc()K(m`h98rSE&~>
+63$cOlJp[Lc,RN-Yc4@dP`:EIG]IS2?@MqS@RE=@3&WWO38OVZ84cQUZN'`JF*`CnO-Z?4X0T:O
+aNrGnjm;[5rrJPgJ_Pb1J_Pb1J_TVI6.O<'_S!=]Whc2POc+pCG]IV4@9Z`-8OPd)2DQp:.Ocer
+.k`Y93^6#(:K:S+Ao)L4IY<T?QCXeMYI;*\aNiLjgO\,GgC<PoR_%8@baQ,tmED$1rS)i~>
+63$cOlJp[Lc,RN-Yc4@dP`:EIG]IS2?@MqS@RE=@3&WWO38OVZ84cQUZN'`JF*`CnO-Z?4X0T:O
+aNrGnjm;[5rrJ>aJ_#D'J_#D'J_'8?6.!fo^::JMVP'?@NJE+5F`1u(?<C-$84,R$2)-^6.4?Sn
+.P<G43Bff$9iG/"@qfk(H\$s2P*qr=X0K.I`6-V]eq)E=ed^odPdT*-acs3alH,9urRQK~>
+Zi:&rIt@$=mXaeWmXafmmf2bUnGi%Yo)J=]o`"O`pAamdq#C0gqYU0gqYp<jq#C*gpAXabo`+O_
+o)J7[nGhs.mXafkmL9-?c0k$"c->\Es38gdmXP~>
+63$lTm,d*UccEr6Z`L!pQ]R&VI"pP8h;eP8hUpH18j5C$5&gH"fp7iEs8T->GCG4'P*qu@XgG^X
+b0el!kO/3>rrJR<JaJ$UJaJ$UJaMmm*pVb>eBZ(L\[/?5SsYXuKRS/dCM$pW<)6+T5s74drA5NQ
+3BTPp8PW2e?Y*tlGCG4'OdM`:X0T7M`m)ueidpKJmHa-Js3/^SmJkDSmHsqtbl$jY~>
+63$lTm,d*UccEr6Z`L!pQ]R&VI"pP8h;eP8hUpH18j5C$5&gH"fp7iEs8T->GCG4'P*qu@XgG^X
+b0el!kO/3>rrJ@6Ja.gOJa.gOJa2[g5j.%Wd`]SB\$;p-S<f7nK7%l^C1LXR;bfnP5Wh"a1c$pE
+2E3c_6V'pL=C,NPDg$M\M3+$nUT(K+]u8(@f\_8FJa2Rd%0+GklK\Dkam/0kaiXJGJ,~>
+Zi:#3JWPGEJWPGEJWT5[5EhG&SY2dVWi`M3[^j&c_SsR<c-Ohgf@o!8hr*JQj5].Yi8<AGg=Om(
+d*9bT`PTC&\[JiKXfA:pTUhO<P(A^GOP,_G~>
+'`\1+mcWN]d`]SB[]cX'RZredJ<0I)!*9(f"%Ge4nbrJ'qlap\H\%!5Q(4VKYd_?cbgY>+l1"]F
+rr?>UO+E@CO+E@CO6qunNerI@I<fsTD/!Qi?!10*:.e#D5<Lq`1+t4/-mg5c,9nH[-7C>p0/>CE
+4?l/%8ki/_=^>HHBP_[2H$t3sMh-q?O4fSE~>
+'`\1+mcWN]d`]SB[]cX'RZredJ<0I)!*9(f"%Ge4nbrJ'qlap\H\%!5Q(4VKYd_?cbgY>+l1"]F
+rr?5ROF`LEOF`LEOR8,NO,A[DIX60XDJEcm?<UB.:J42F5Wh%b1,(:0-mg8=,TS0X-n6f&1,V'S
+5=7q5:/Y+r?"%;YD/sfFI=[-3JWPGEfoU^~>
+ZiB>X!$Qn[JO4oSJO4rT*Cih%='T0HCiOWFJVK&CQ'n2<VlR#.\%BAj`5]msaW8IB`59:$\?rK@
+Vk]iPQ&poYJUDZ^ChI3_=Ahj\JO4oSn3R*ulU$+~>
+s8P:Xn`o,geBQ"J\[&94SsPRtKS,\YP)bESK7JDu;,'_Y9i"VkPHhTlGA_MKJ;0#GR@g@YZb!uo
+cdpq5lh'iLlUh."JP(JcJP(JcJk@%R770@*4ZbY_2)?s?/Lr7t-6j]W*uu:=)&O,)(&\ge'c%Q$
+(`F>6*ZuXO,pt,l/MAh72)dNW4[25"77i&&JP,E(!$LT"J,~>
+s8P:Xn`o,geBQ"J\[&94SsPRtKS,\YP)bESK7JDu;,'_Y9i"VkPHhTlGA_MKJ;0#GR@g@YZb!uo
+cdpq5lh'iLlZW=PJTlZhJTlZhJp/5VE,96#@UEAC<DlUd8Oc$24ZPGX0eY(--mg2a,5iZ*+sS?[
+-n6c$0f1gL4?l/$85)cV<ENI4@V'7iE-?eVJTpU-!$UZPJ,~>
+ZiB>t!$Qo"JR3n6JR3q75%%r9DK9rJJ:r`<Od2?*Tr"`jZ*h*R^;7b-aN;WLc-=JUb/hT@_8!Xm
+[BZm7V4sQLQB@/`Kn+PpF)Pf)JR3n6mp5u;lX#)~>
+s8P:[oBbSqf?h[X]X=rAU77F/M1^5$F)G]'@9m&=<`N*u<E<4+?=IM]Dfg8SKSkkXSYN3h\%]f(
+db3RAmeZSUlYunIJT66\JT66\JoMfLCM79g?X-`6;GTtY7RTO+4#o2T0eY+..46Gg,lAl+,UOlf
+.P*2,1H%3S5!_P*8PDoX<ENI3@:a+fJT66\mr8=MlZ%F~>
+s8P:[oBbSqf?h[X]X=rAU77F/M1^5$F)G]'@9m&=<`N*u<E<4+?=IM]Dfg8SKSkkXSYN3h\%]f(
+db3RAmeZSUlcK2NJ]`PdJ]`PdK$$9s^q-qWWhc8TP`CTRIX-'SC1^mZ=B&*j8Oc*75X.Fr5<qM&
+7S-9M;cm:5ASQ.*H%(C&NK]a$UT(H(]"im>J]dH(!$U[NJ,~>
+ZiB>l!$QnoJQ@>&JQ@>&4^2?+Bl8!9I"@!.NKTTrSt`*^Xg#1A]"Geo_SjC3`Pf^3_8!Xo\$WEC
+WhuM^R[0+sMM6V0G]Re<ARS_m<e4<?<WF</<e(~>
+s8O,=p@%5(g=4Be^q$bPVP'BBNei=:H$!t?BOkOY?2e(L?!^oJAS>n!FaAOjMN=$lTr5'#]>;S6
+e_K3Mnc&1\lXp2?JS0OHJS0OHJnH'8@piSG=B/6p9M.fD69dUo3&WQI0.e\(-mg5cq]d%*,pk#h
+.kND/1Gq-Q4?l/#7nHBM;,gV#?!q2oB7X^aB)j(?B7K~>
+s8O,=p@%5(g=4Be^q$bPVP'BBNei=:H$!t?BOkOY?2e(L?!^oJAS>n!FaAOjMN=$lTr5'#]>;S6
+e_K3Mnc&1\lb*9AJ\?WJJ\?WJK"X@\[]lg0Tq%I4N/3+8H$+(BB4G7P=&Vpi8k29:5s[b$5s[k+
+7nQHO;c[(.@V9IpFEr=eLQ%@]S"QXZYdf7tJ\CNc!$U[AJ,~>
+ZiB@@!6B`@J^f8#J^f8#(Y.*gf\5'7h;7&Iio9"[jlYail0@R#m/HDPmelPRmf2\SlkJdNl0.<n
+k2k[`iSi\Nh;$c<g"4f+e:H-;e,[SUe:7~>
+rr3u7o'>Dof?qaY]sk5GUn4!<Nei=;H?O=ICM@EmrF?jYB5)1#F*Dt]Ko1qUR\6OZZFIWfbL5)$
+k3_p7s6J;;aFVupfR_\+fR_ZpdEKYI]="iBURmm<Nf&I=H?F4EBOtRW>$"^%;Z'?1;H-_#?!q/U
+CN+EBItNQ;P*_c8WNW\?^rFULJ_5P+n(7W]le$^~>
+rr3u7o'>Dof?qaY]sk5GUn4!<Nei=;H?O=ICM@EmrF?jYB5)1#F*Dt]Ko1qUR\6OZZFIWfbL5)$
+k3_p7s6K%PaFW`0m=FYUm=FXEk24nAc,RQ1Z`^7$S!T4qL4O_rEc,T&@piSG>5_PC=^#*=@V'7j
+Ecue\Ko;%YS"Z^^ZamlkbgP2%l@J>RmI0EBaQr5D~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+rr5+[p@%5(gXONi_7R+YWM?&PPE(KRJUMfeF)Z#6Chmg&D/XE8G'\RfL5M%VR\-FVYdV3^aj8Pn
+j6H.5JcC<$JcC<$JcFO**<#QukMY(Cbf7H/Z`U.!S<f:qL4Xi!F`MD:C2!QY)e`u&DK0fEI=[-2
+OHl</Vl[27^W"FFg#2#[pjrHrs4@:$~>
+rr5+[p@%5(gXONi_7R+YWM?&PPE(KRJUMfeF)Z#6Chmg&D/XE8G'\RfL5M%VR\-FVYdV3^aj8Pn
+j6H.5JcC<$JcC<$JcFO**<#QukMY(Cbf7H/Z`U.!S<f:qL4Xi!F`MD:C2!QY)e`u&DK0fEI=[-2
+OHl</Vl[27^W"FFg#2#[pjrHrs4@:$~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+rVnqTo'GJqf[A!`^q-nUW2#rPP`UfYK7JArG]n4OF)uGGG'J@_JV8i<Od2B-V5g`,]>;P4eCrjD
+mJ2>5JcC<$JcC<$gAa80na#8lf?qaZ^::JMVP0KFOc5*LJ:)WcFE2>=DJjB3EH?;KI"-d(N00Eq
+TVecp\%T]%d+7%5lLFk)s+14%s*t~>
+rVnqTo'GJqf[A!`^q-nUW2#rPP`UfYK7JArG]n4OF)uGGG'J@_JV8i<Od2B-V5g`,]>;P4eCrjD
+mJ2>5JcC<$JcC<$gAa80na#8lf?qaZ^::JMVP0KFOc5*LJ:)WcFE2>=DJjB3EH?;KI"-d(N00Eq
+TVecp\%T]%d+7%5lLFk)s+14%s*t~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+rVmi9p@.>,h:Brq`4rjhY,S4hR[0+sMMHk:IsueEHQ.?\IXm$(Ll7=XQ^aYEWirhA^rFUHf\Y]T
+o)=4?JcC<$JcC<$gAa54p$V&&gXXWk_S!@_X/;S\Q]mGeLP(,*H[0j[G'8(SH$asiK8,8DP*_]4
+VQ6r0]Y_b8eCrmEmeMG6JcF=$J,~>
+rVmi9p@.>,h:Brq`4rjhY,S4hR[0+sMMHk:IsueEHQ.?\IXm$(Ll7=XQ^aYEWirhA^rFUHf\Y]T
+o)=4?JcC<$JcC<$gAa54p$V&&gXXWk_S!@_X/;S\Q]mGeLP(,*H[0j[G'8(SH$asiK8,8DP*_]4
+VQ6r0]Y_b8eCrmEmeMG6JcF=$J,~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+r;R]5o^:o$gXXWl`4idhY,\=lS=#S(Nf/aLKnTDW)2*a"M2[LYQC4;<VQ6r/]"c5-dFR+5l0nJ"
+s+13$s+13$s4I>jqXX"8hq?K'a2,EsZ)jjtSXGb*NJ`LFK7SN%rdG`7JV&Q1MN*a_R@U(LX0B%E
+_8jgKg#(oWo7?pms4.."~>
+r;R]5o^:o$gXXWl`4idhY,\=lS=#S(Nf/aLKnTDW)2*a"M2[LYQC4;<VQ6r/]"c5-dFR+5l0nJ"
+s+13$s+13$s4I>jqXX"8hq?K'a2,EsZ)jjtSXGb*NJ`LFK7SN%rdG`7JV&Q1MN*a_R@U(LX0B%E
+_8jgKg#(oWo7?pms4.."~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+qu7Q0o'GMsg=4Hj`4idhYcF[sT:D:6PE:ibN;\YON/`m\PEqW,TVSNfZ*q6Z`QHQYgYq>_p4<6p
+s+13$s+14%ru1n1nET)kf[A!a_7[7^Xf/%gS=#P'O,SsPL])rFLPUhHNffQnS"HISXKf4G_8a^H
+fA5KOnG@e:JcF:#J,~>
+qu7Q0o'GMsg=4Hj`4idhYcF[sT:D:6PE:ibN;\YON/`m\PEqW,TVSNfZ*q6Z`QHQYgYq>_p4<6p
+s+13$s+14%ru1n1nET)kf[A!a_7[7^Xf/%gS=#P'O,SsPL])rFLPUhHNffQnS"HISXKf4G_8a^H
+fA5KOnG@e:JcF:#J,~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+qu8SRp@.D0hq?N)ai(s*[]us6VPBcSR[BD+P`q8oPE_?!R%'Y>USk,pZa[T_`QHQXgYh5\o_sFA
+JcC<$JcC<$f)HWdp$_/*h:L&ua2,EtZ`^=*U7[sDQB[PoO8Y(UO-#NgQC+/5U8FrnZF@K_`llc\
+gu@PcpjrHrs4%(!~>
+qu8SRp@.D0hq?N)ai(s*[]us6VPBcSR[BD+P`q8oPE_?!R%'Y>USk,pZa[T_`QHQXgYh5\o_sFA
+JcC<$JcC<$f)HWdp$_/*h:L&ua2,EtZ`^=*U7[sDQB[PoO8Y(UO-#NgQC+/5U8FrnZF@K_`llc\
+gu@PcpjrHrs4%(!~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+qYrDOp$_2,hq?N*b/M30\?rKBWMcPdTUq[CS!oe8S=Q7EU8=cfXg,:E]u%e4d+-n/jm2L:JcC<$
+JcC<$JcF7"2#Hn3ki1CLdEKYJ^:CYVXf81mTUhR?R$X,(Q'Rc(R@Bb?U8=ijYdCsS_T0mJf%f6I
+mIl,2JcF4!J,~>
+qYrDOp$_2,hq?N*b/M30\?rKBWMcPdTUq[CS!oe8S=Q7EU8=cfXg,:E]u%e4d+-n/jm2L:JcC<$
+JcC<$JcF7"2#Hn3ki1CLdEKYJ^:CYVXf81mTUhR?R$X,(Q'Rc(R@Bb?U8=ijYdCsS_T0mJf%f6I
+mIl,2JcF4!J,~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+q>V90p$_2,hqHW-bK%N8]=5/PY,eP"V50mcUApu'Uo(&hXKJh8\@fVqaNW&_gYh2ZnGRq<JcC<$
+JcC<$df2-!o'PW"gt1!!aMbj*\$N<@Wi)\gTq@pJSXl@DT:r!UVl?c%Za[Q]_oU*NfA,?Jm.C:.
+s+14!s*t~>
+q>V90p$_2,hqHW-bK%N8]=5/PY,eP"V50mcUApu'Uo(&hXKJh8\@fVqaNW&_gYh2ZnGRq<JcC<$
+JcC<$df2-!o'PW"gt1!!aMbj*\$N<@Wi)\gTq@pJSXl@DT:r!UVl?c%Za[Q]_oU*NfA,?Jm.C:.
+s+14!s*t~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+q#;--o^D),i7li2c,mrA^:Un_Z`pU7XK2<"'s"F<YHbFB\@fSn`lcTUfA,?IlgXh's+13$s+13$
+s3Uc]q"!e7in`89ccX8E^:Le\Z*(1.W2HNkV&#r+W2cr%Z*UpN^;7e2cI:D#iTKRurdk*#s3gpt~>
+q#;--o^D),i7li2c,mrA^:Un_Z`pU7XK2<"'s"F<YHbFB\@fSn`lcTUfA,?IlgXh's+13$s+13$
+s3Uc]q"!e7in`89ccX8E^:Le\Z*(1.W2HNkV&#r+W2cr%Z*UpN^;7e2cI:D#iTKRurdk*#s3gpt~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+p\ts*p$h;0iS<)8d*0SM_S<ap\@/fOr3@$C['d?P]=l"t`lZKQe_/d<kNqd;JcC<$JcC<$JcF$q
+(&7@eki:OQe^2O]`PK:#\@/cMYck5.XVJ"BYd(OB\@]Jk`5p0LeCi[;kNqd<JcC<$dJn^~>
+p\ts*p$h;0iS<)8d*0SM_S<ap\@/fOr3@$C['d?P]=l"t`lZKQe_/d<kNqd;JcC<$JcC<$JcF$q
+(&7@eki:OQe^2O]`PK:#\@/cMYck5.XVJ"BYd(OB\@]Jk`5p0LeCi[;kNqd<JcC<$dJn^~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+pAZ]Bp$h>2j58SBe'H7[`l,^.^:_(h]",A_]">Yi^r"%1b0A;_fA#6EkjA$AJcC<$JcC<$JcEso
+/c##+l/^dWf@/'iaMl$3]t:hb[^ENM['d<M\@K5b^V[t2bKnYhgY_)UmI^C/s+13ss*t~>
+pAZ]Bp$h>2j58SBe'H7[`l,^.^:_(h]",A_]">Yi^r"%1b0A;_fA#6EkjA$AJcC<$JcC<$JcEso
+/c##+l/^dWf@/'iaMl$3]t:hb[^ENM['d<M\@K5b^V[t2bKnYhgY_)UmI^C/s+13ss*t~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+p&>^)q"!k;jl,%Lf$i!kbK7fD`5BIk_>h@`_o0R8air&XeCWI3io]OppOW?qs+13$s+13ls!mp<
+n*9&phV-Q0ccjMO`P]O,^:h4m]Y2"m^VRe*a2uQOdam+-iT9@mpOW?qs3CXp~>
+p&>^)q"!k;jl,%Lf$i!kbK7fD`5BIk_>h@`_o0R8air&XeCWI3io]OppOW?qs+13$s+13ls!mp<
+n*9&phV-Q0ccjMO`P]O,^:h4m]Y2"m^VRe*a2uQOdam+-iT9@mpOW?qs3CXp~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+oD]F!o^M52jPeqKf[\Htccs\Wb5KEnb0/#RcdC4mf\>9Bjlu1&qLSZts+13$s+13jrt>;'na,K#
+iSE5=eBuRcb/hWC`Vm^e`Q#s>b08/Ye(34.i8j+gnG7_9JcF!pJ,~>
+oD]F!o^M52jPeqKf[\Htccs\Wb5KEnb0/#RcdC4mf\>9Bjlu1&qLSZts+13$s+13jrt>;'na,K#
+iSE5=eBuRcb/hWC`Vm^e`Q#s>b08/Ye(34.i8j+gnG7_9JcF!pJ,~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+o)B:#q"!n>kiLg]gtLE3e^MsprQu/(e'uq"f\>6?ioTFknFup5s+13$s+13$s2G!MrqQ*Rlf[?f
+hV6]6eC)^icHZ=3&C&MHd*gCof\>6?jQGjso_j@@JcEsoJ,~>
+o)B:#q"!n>kiLg]gtLE3e^MsprQu/(e'uq"f\>6?ioTFknFup5s+13$s+13$s2G!MrqQ*Rlf[?f
+hV6]6eC)^icHZ=3&C&MHd*gCof\>6?jQGjso_j@@JcEsoJ,~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+nG`srp[[e>l/q'di838DgABP3g=tH?i8Wh\lKn$6rIP!"s+13$s+13drt#)&o'Yi-jl54SgY(61
+e^aTI%Fs%^g"Y??ioT@hmdp=,s+13ms*t~>
+nG`srp[[e>l/q'di838DgABP3g=tH?i8Wh\lKn$6rIP!"s+13$s+13drt#)&o'Yi-jl54SgY(61
+e^aTI%Fs%^g"Y??ioT@hmdp=,s+13ms*t~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+mf+:*p[dnBlfmTojQ#7YiS`YQiSrnYk32*smd^&MJcC<$JcC<$JcEF`%/onjn*K<%jl>=WhVJ(a
+$f0[siT'%_l0Rm1qgncus2b4j~>
+mf+:*p[dnBlfmTojQ#7YiS`YQiSrnYk32*smd^&MJcC<$JcC<$JcEF`%/onjn*K<%jl>=WhVJ(a
+$f0[siT'%_l0Rm1qgncus2b4j~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+m/IFlqtK^Pn*TK-lKS<3s60gSlg4$-nb;q[JcC<$JcC<$JcE:\)ZBI&na>c/l0%3jjQ,@]jQ,Fb
+kNM3tmd^#JJcC<$`rCP~>
+m/IFlqtK^Pn*TK-lKS<3s60gSlg4$-nb;q[JcC<$JcC<$JcE:\)ZBI&na>c/l0%3jjQ,@]jQ,Fb
+kNM3tmd^#JJcC<$`rCP~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+kl1kbq=jOPnaZSI"nD0VpA+Z<s+13$s+13$s0DY1rV?-WnF,f4m/?5Um-X60nFQGQrdk*#s2=qf~>
+kl1kbq=jOPnaZSI"nD0VpA+Z<s+13$s+13$s0DY1rV?-WnF,f4m/?5Um-X60nFQGQrdk*#s2=qf~>
+JcC<$JcC<$JcC<$JcC<$[Jta~>
+j8]/YrquirJcC<$JcC<$JcD_L%fZD'q=jUToCV_Mq"jmdJcC<$_#Jo~>
+j8]/YrquirJcC<$JcC<$JcD_L%fZD'q=jUToCV_Mq"jmdJcC<$_#Jo~>
+%%EndData
+showpage
+%%Trailer
+end
+%%EOF
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.png
new file mode 100644 (file)
index 0000000..0f2e986
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/lttv-numbered-5.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/user_guide.docbook b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/docbook/user_guide.docbook
new file mode 100644 (file)
index 0000000..9720c43
--- /dev/null
@@ -0,0 +1,557 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+                      "/usr/share/sgml/docbook/dtd/4.3/xdocbook.dtd">
+<!--<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" >-->
+
+<book>
+
+<bookinfo>
+<title>Linux Trace Toolkit Viewer User Guide</title>
+<authorgroup>
+<author>
+<firstname>Mathieu</firstname>
+<surname>Desnoyers</surname>
+</author>
+</authorgroup>
+
+<date>29/11/2004</date>
+<releaseinfo>1.00.01</releaseinfo>
+
+<abstract>
+<para>
+This document describes how to install <application>Linux Trace
+Toolkit Viewer</application> and how to use it.
+
+</para>
+</abstract>
+
+<keywordset>
+<keyword>Linux Trace Toolkit Viewer</keyword>
+<keyword>Linux Trace Toolkit</keyword>
+<keyword>tracing</keyword>
+<keyword>Linux</keyword>
+<keyword>visualization</keyword>
+<keyword>operating system</keyword>
+</keywordset>
+
+</bookinfo>
+
+<chapter>
+<title>Introduction</title>
+<para>
+Linux Trace Toolkit (LTT) is a tracing tool that permits to get all the possible
+execution information from the Linux Kernel. It is based on kernel
+instrumentation and a high-speed relay file system to copy the information from
+the kernel space to the user space.
+</para>
+
+<para>
+Linux Trace Toolkit Viewer (LTTV) is the second generation of visualization
+tool. It is 
+based on a trace format (the files where the data is recorded on disk) slightly
+different from LTT. As for now, November 29, 2004, the implementation of the new
+trace format in LTT is still not done, we must use a conversion tool to
+transform the original LTT traces to the new format.
+</para>
+
+<para>
+This document explains all the steps that are necessary in order to record a
+trace with LTT and view it with LTTV.
+</para>
+</chapter>
+
+<chapter>
+<title>Getting started</title>
+
+<sect1 id="install">
+<title>Installing LTTV</title>
+<para>
+First, you must download the latests version of LTTV. You should get it from
+this site : <ulink url="http://ltt.polymtl.ca">ltt.polymtl.ca</ulink>.
+I suggest that you get it from the "Packages" section.
+</para>
+
+<para>
+You need a recent gcc compiler to compile the project. You might want to use gcc
+3.2 or newer.
+You will also need some libraries in order to compile it. They are described in
+the README of the LTTV package. These are GTK 2.0, GLIB 2.0, "popt" and Pango 1.0.
+Install them if they are not on your system. Remember that if you use a package
+manager from you favourite Linux distribution, you will need to specifically
+install the librairies'development packages.
+</para>
+
+
+<para>
+Then, you are ready to compile LTTV. Extract and untar the file you previously
+downloaded : 
+</para>
+
+<screen>
+<prompt>$</prompt> <userinput>tar -xvzof LinuxTraceToolkitViewer-x.x-dddddddd.tar.bz2</userinput>
+</screen>
+
+<para>
+Then, go to the directory newly created, and type :
+</para>
+
+<screen>
+<prompt>$</prompt> <userinput>./configure</userinput>
+<prompt>$</prompt> <userinput>make</userinput>
+<prompt>#</prompt> <userinput>make install</userinput> (as root)
+</screen>
+
+<para>
+At this point, LTTV is installed in the default directory. You may find the
+lttv executable in /usr/local/bin and the librairies in /usr/local/lib. You will
+also notice the presence of the convert executable in /usr/local/bin. This tool
+will be used later to convert from the Linux Trace Toolkit trace format to the
+LTTV format.
+</para>
+
+<para>
+You are now ready to go to the next step : installing the LTT kernel tracer.
+</para>
+
+
+</sect1>
+
+
+
+<sect1 id="install-tracer">
+<title>Installing LTT kernel tracer</title>
+<para>
+The goal of this guide is not to describe the Linux Trace Toolkit project in
+details, as it is a
+seperate project for now. It just gives pointers to the basic steps you must
+take in order to generate a trace suitable for conversion.
+</para>
+
+<para>
+First, go to the <ulink url="http://ltt.polymtl.ca">ltt.polymtl.ca</ulink>
+website, in the "Patches for the Official LTT" section. Use the latest version
+of patches available. The file name convention used goes like this : 
+aaaaaa-x.x--bbbbb-y.y.patch. That means a patch made for aaaaa, release x.x,
+that adds bbbbb, release y.y to it. Notice the presence of the -- sign that
+separates the "from" field from the name of the patch applied. This way, it's
+impossible to be mixed up on the specific sequence of patch application. I
+suggest that you use the "relayfs", "ltt" and then "md" patches. The "md" patch
+adds events useful to LTTV that are not in the official LTT.
+</para>
+
+<para>
+Once you have the patches you need, get the matching Linux kernel version, apply
+the patches on it, configure it, install it, reboot with the new kernel. You then
+have an instrumented kernel ready for tracing. If you have problems during this phase,
+please refer to <ulink
+url="http://www.opersys.com/ltt">www.opersys.com/ltt</ulink>. If you need
+instructions about how to recompile a kernel, see
+<ulink url="http://www.tldp.org/HOWTO/Kernel-HOWTO/">Kernel-HOWTO</ulink>.
+</para>
+
+</sect1>
+
+<sect1 id="install-daemon">
+<title>Installing LTT trace recording daemon</title>
+<para>
+In order to install the LTT trace recording daemon, you should get the latest
+TraceToolkit (or ltt) package from the LTT ftp site.
+Use the link "Official Linux Trace Toolkit Packages" on the
+<ulink url="http://ltt.polymtl.ca">ltt.polymtl.ca</ulink> webpage to access it.
+As of November 30, 2004, the most recent version is 0.9.6-pre3.
+</para>
+<para>
+Then, you should apply the TraceToolkit patches from the LTTV website related
+to the package version. Get them from the "Patches for the Official LTT"
+section.
+</para>
+<para>
+You are now ready to install the daemon in your system. Please refer to the
+documentation in the package for details.
+</para>
+<para>
+You may now use the following command to record a sample 30 seconds trace in
+your current directory. Command line switches are described on the official
+LTT website.
+</para>
+<screen>
+<prompt>#</prompt><userinput>tracedaemon -ts30 sample.out sample.proc (as root) userinput></userinput>
+</screen>
+</sect1>
+
+
+
+<sect1 id="convert">
+<title>Conversion from LTT to LTTV trace format</title>
+<para>
+If you used the default directory for installation, you should find the
+conversion tool in /usr/local/bin/convert. Before using it, some other files are
+necessary. You will find them in
+/usr/local/share/LinuxTraceToolkitViewer/convert/. Those are sysInfo and
+core.xml.
+</para>
+<para>
+sysInfo is a script that get informations about the traced computer. It should
+be invoked like this :
+</para>
+<screen>
+<prompt>$</prompt> <userinput>sh /usr/local/LinuxTraceToolkitViewer/convert/sysInfo</userinput>
+</screen>
+<para>
+It creates a file named sysInfo.out. This file has to be present in the current
+directory where the convert tool will be executed. I suggest that you choose a
+destination directory where will be written converted traces right now, put sysInfo.out in it, at
+use it as current directory for running the convert tool.
+</para>
+<para>
+Once the sysInfo.out file is ready and you have a trace ready for conversion,
+you should invoke convert like the following example. This is for a uniprocessor
+computer. If you whish to get detailed explanation on the parameters, simply
+execute the convert tool without any option. You may also wish to see the
+/usr/local/LinuxTraceToolkitViewer/convert/README file.
+</para>
+<screen>
+<prompt>$</prompt> <userinput>/usr/local/bin/convert sample.proc 1 sample.trace sample.converted</userinput>
+</screen>
+<para>
+You must then copy the core event definition file to the converted trace directory :
+</para>
+<screen>
+<prompt>$</prompt> <userinput>cp /usr/local/share/LinuxTraceToolkitViewer/convert/core.xml sample.converted/</userinput>
+</screen>
+<para>
+You now have a converted trace ready for visualization in LTTV. Congratulations!
+</para>
+
+</sect1>
+
+<sect1 id="running">
+<title>Running the executable with basic libraries</title>
+<para>
+Starting the graphical mode with the basic viewer activated is as simple as :
+</para>
+<screen>
+<prompt>$</prompt> <userinput>lttv -L /usr/local/lib/lttv/plugins -m lttvwindow\
+-m guievents -m guicontrolflow -m guistatistics -t sample.converted/</userinput>
+</screen>
+<para>
+Using the text mode is very simple too. Look in /usr/local/lib/lttv/plugins for
+the list of modules. You may use the --help switch to get basic help on the
+command line parameters of every loaded modules. To simply output the events of
+a trace in a text file, try the textDump module. The batchAnalysis module
+permits to do batch mode analysis (state and statistics calculation ) on a
+trace.
+</para>
+<screen>
+<prompt>$</prompt> <userinput>lttv -L /usr/local/lib/lttv/plugins -m textDump --help</userinput>
+</screen>
+</sect1>
+</chapter>
+
+<chapter>
+<title>Using LTTV graphical interface</title>
+
+<sect1 id="mainwindow">
+<title>LTTV main window</title>
+<para>
+This section describes the main functionnalities that are provided by the LTTV
+GUI and how to use them.
+</para>
+<para>
+By default, when the lttv GUI starts with all the graphical modules loaded,
+it loads the statistics viewer, the control flow viewer, and the detailed event
+list inside a tab. Other viewers can be added later to this tab by interacting
+with the main window. Let's describe the operations available on the window :
+</para>
+<screenshot>
+<mediaobject>
+<imageobject>
+<imagedata srccredit="Mathieu Desnoyers, 2004" fileref="lttv-numbered-5.png"
+format="PNG" align="center"/>
+</imageobject>
+<imageobject>
+<imagedata srccredit="Mathieu Desnoyers, 2004"
+fileref="lttv-numbered-5.eps"
+format="EPS" align="center"/>
+</imageobject>
+<!--<imagedata srccredit="Mathieu Desnoyers, 2004" fileref="lttv-numbered-6.svg"
+format="SVG" align="center" scalefit="1"/>
+</imageobject>-->
+<caption><para>Linux Trace Toolkit Viewer GUI</para></caption>
+</mediaobject>
+</screenshot>
+<orderedlist>
+<listitem>
+<para>
+This toolbar allows you to navigate through the basic functionnalities of LTTV.
+The first button opens a new window and the second one, a new tab. You can leave
+your mouse over the buttons to read the information provided by the tooltips.
+</para>
+</listitem>
+<listitem>
+<para>
+This notebook, containing different tabs, lets you select the "Trace Set" you
+want to interact with. A trace set is an aggregation of traces, synchronised in
+time. You may also want to use one tab per viewer by simply cloning the traceset
+to a new tab. This way, you can have vertically stacked viewers in one tab, as
+well as different viewers, independant from the time interval. Note that once
+the Trace Set cloning is done, each trace set becomes completely independant.
+For Traceset cloning, see the File Menu.
+</para>
+</listitem>
+<listitem>
+<para>
+These buttons let you control the computation in progress on a trace. As
+sometimes the computation may last for a while, you may want to stop it, restart
+it from the beginning or simply to continue from where you stopped. This is
+exactly what those three buttons offer you.
+</para>
+</listitem>
+<listitem>
+<para>
+Buttons on the right side of the last spacer are semantically different from the
+others. While the other buttons at the left side of the bar are built in the
+lttv program and let you operate the basic functionnalities, the buttons at the
+right side let you add a viewer to the active Tab. They belong to the
+viewers themselves. The number of buttons that appears there should directly
+depend on the number of viewer's modules loaded.
+</para>
+</listitem>
+<listitem>
+<para>
+This is a tree representing the multiple statistics available for the current
+traceset. This is shown by the guistatistics viewer.
+</para>
+</listitem>
+<listitem>
+<para>
+This is the Y axis of the guicontrolflow viewer. It shows the process list of
+the traced system. You may notice that it grows : it dynamically adds
+process when they appear in the trace.
+</para>
+</listitem>
+<listitem>
+<para>
+This is a (missing) time bar for the X axis. Maybe will it be used for viewer
+specific buttons eventually. Work in progress.
+</para>
+</listitem>
+<listitem>
+<para>
+The is the current time selected. The concept of current event and current time
+selected is synchronised in a Tab for all the viewers. The control flow viewer
+shows it a vertical white dotted line. You move this marker by clicking on the
+background of the process state graph. This graph shows evolution of each
+process's state through time. The meaning of the colors will be explained later.
+</para>
+</listitem>
+<listitem>
+<para>
+This is the details event list. It shown the detailed information about each
+event of the trace. It is synchronised with the current time and current event,
+so selecting an event changes other viewer's current time and reciprocally.
+</para>
+</listitem>
+<listitem>
+<para>
+You can enter the values of start time and end time you wish to see on the
+screen here. It also supports pasting time as text input, simply by clicking of
+the "Time Frame", "start" or "end:" fields. A valid entry consists of any
+digital input separated by any quantity of non digital characters. For example :
+"I start at 356247.124626 and stop at 724524.453455" would be a valid input
+for the "Time Frame" field.
+</para>
+</listitem>
+<listitem>
+<para>
+This horizontal scrollbar modifies the window of time shown by all the viewers
+in the tab. It is linked with the fields below it (described at number 10 and
+12). Another way to modify the time shown is to use the zoom buttons of the
+toolbar (yes, the ones that looks like magnifying glasses).
+</para>
+</listitem>
+<listitem>
+<para>
+This field works just like the "Time Frame" field. It modifies the current time
+selected by the viewers. For example, changing its value will change the current
+event selected by the detailed events list and the current time selected by the
+control flow viewer.
+</para>
+</listitem>
+</orderedlist>
+</sect1>
+
+<sect1 id="ControlFlowColors">
+<title>Control Flow View Colors</title>
+<screenshot>
+<mediaobject>
+<imageobject>
+<imagedata srccredit="Mathieu Desnoyers, 2004" fileref="lttv-color-list.png"
+format="PNG" align="center"/>
+</imageobject>
+<imageobject>
+<imagedata srccredit="Mathieu Desnoyers, 2004"
+fileref="lttv-color-list.eps"
+format="EPS" align="center"/>
+</imageobject>
+<!--<imagedata srccredit="Mathieu Desnoyers, 2004" fileref="lttv-numbered-6.svg"
+format="SVG" align="center" scalefit="1"/>
+</imageobject>-->
+<caption><para>Control Flow View Color Legend</para></caption>
+</mediaobject>
+</screenshot>
+
+<para>
+Here is a description of the colors used in the control flow view. Each color
+represents a state of the process at a given time.
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+White : this color is used for process from which state is not known. It may
+happen when you seek quickly at a far time in the trace just after it has been
+launched. At that moment, the precomputed state information is incomplete. The
+"unknown" state is used to identify this. Note that the viewer gets refreshed
+once the precomputation ends.
+</para>
+</listitem>
+<listitem>
+<para>
+Green : This color is only used for process when they are running in user mode.
+That includes execution of all the source code of an executable as well as the
+libraries it uses.
+</para>
+</listitem>
+<listitem>
+<para>
+Pale blue : A process is doing a system call to the kernel, and the mode is
+switched from process limited rights to super user mode. Only code from the
+kernel (including modules) should be run in that state.
+</para>
+</listitem>
+<listitem>
+<para>
+Yellow : The kernel is running a trap that services a fault. The most frequent
+trap is the memory page fault trap : it is called every time a page is missing
+from physical memory.
+</para>
+</listitem>
+<listitem>
+<para>
+Orange : IRQ servicing routine is running. It interrupts the currently running
+process. As the IRQ does not change the currently running process (on some
+architectures it uses the same stack as the process), the IRQ state is shown in
+the state of the process. IRQ can be nested : a higher priority interrupt can
+interrupt a lower priority interrupt.
+</para>
+</listitem>
+<listitem>
+<para>
+Dark red : A process in that state is waiting for an input/output operation to
+complete before it can continue its execution.
+</para>
+</listitem>
+<listitem>
+<para>
+Dark yellow : A process is ready to run, but waiting to get the CPU (a schedule
+in event).
+</para>
+</listitem>
+<listitem>
+<para>
+Dark purple : A process in zombie state. This state happens when a process
+exits and then waits for the parent to wait for it (wait() or waitpid()).
+</para>
+</listitem>
+<listitem>
+<para>
+Dark green : A process has just been created by its parent and is waiting for
+first scheduling.
+</para>
+</listitem>
+<listitem>
+<para>
+Magenta : The process has exited, but still has the control of the CPU. It may
+happend if it has some tasks to do in the exit system call.
+</para>
+</listitem>
+</itemizedlist>
+</sect1>
+</chapter>
+
+<chapter>
+<title>Using LTTV text modules</title>
+<sect1 id="batchAnalysis">
+<title>The batch analysis module</title>
+<para>
+This batch analysis module can be invoked like this :
+</para>
+<screen>
+<prompt>$</prompt> <userinput>lttv -L path/to/lib/plugins -m batchAnalysis\
+-t trace1 -t trace2 ...</userinput>
+</screen>
+<para>
+It permits to call any registered action to perform in batch mode on all the
+trace set, which consists of the traces loaded on the command line. Actions that
+are built in the batchAnalysis module are statistics computation. They can be
+triggered by using the -s (--stats) switch.
+</para>
+<para>
+However, the batchAnalysis module is mostly a backend for every other text
+module that does batch computation over a complete trace set.
+</para>
+</sect1>
+<sect1 id="textDump">
+<title>The text dump module</title>
+<para>
+ The goal of this module is to convert the binary data of the traces into
+a formatted text file.
+</para>
+<para>
+The text dump module is a good example of a usage of the batch analysis module
+backend. In fact, the text dump module depends on it. You don't need to
+explicitly load the batchAnalysis module though, as lttv offers a rich module
+backend that deals with the dependencies, loading the module automatically if
+needed.
+</para>
+<para>
+The text dump module is invoked just like the batchAnalysis module. It adds more
+options that can be specified in argument. You may specify the -o switch for the
+output file name of the text dump. You can enable the output of the field names
+(the identifier of the fields) with the -l switch. The -s switch, for process
+states, is very useful to indicate the state in which the process is when the
+event happens.
+</para>
+<para>
+If you use the --help option on the textDump module, you will see all the detail
+about the switches that can be used to show per cpu statistics and per process
+statistics. You will notice that you can use both the switches for the
+batchAnalysis module and those for textDump. You will also notice that the
+options --process_state (from textDump) and --stats (from batchAnalysis) has the
+same short name "-s". If you choose to invoke this option using the short name,
+it will use the option of the last module loaded just before the -s switch.
+</para>
+<para>
+For exemple, if you load the textDump module with -m textDump, it will first
+load the batchAnalysis module, and then load itself. As it is the last module
+loaded, the -s switch used after it will signify --process_stats. On the other
+hand, if you choose to specify explicitly the loading of both modules like this
+:
+</para>
+<screen>
+<prompt>$</prompt> <userinput>lttv -L path/to/lib/plugins -m batchAnalysis -s\
+-m textDump -s -t trace</userinput>
+</screen>
+<para>
+The first "-s" will invoke batchAnalysis --stats and the second "-s" will invoke
+textDump --process_state. The list of options generated by --help follows the
+order of registration of the options by the modules, therefore the invocation 
+order of the modules.
+</para>
+</sect1>
+
+</chapter>
+
+
+</book>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/Makefile.am
new file mode 100644 (file)
index 0000000..13e1433
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST = c159.html c162.html c20.html c25.html c88.html c91.html index.html lttv-color-list.png lttv-numbered-5.png x127.html x130.html x169.html x172.html x46.html x54.html x61.html x64.html x78.html x81.html
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c159.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c159.html
new file mode 100644 (file)
index 0000000..b4395fe
--- /dev/null
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Using LTTV text modules</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Control Flow View Colors"
+HREF="x127.html"><LINK
+REL="NEXT"
+TITLE="The text dump module"
+HREF="x169.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x127.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x169.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN159"
+></A
+>Chapter 4. Using LTTV text modules</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="batchAnalysis"
+>4.1. The batch analysis module</A
+></H1
+><P
+>&#13;This batch analysis module can be invoked like this :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L path/to/lib/plugins -m batchAnalysis\
+-t trace1 -t trace2 ...</KBD
+>
+</PRE
+><P
+>&#13;It permits to call any registered action to perform in batch mode on all the
+trace set, which consists of the traces loaded on the command line. Actions that
+are built in the batchAnalysis module are statistics computation. They can be
+triggered by using the -s (--stats) switch.
+</P
+><P
+>&#13;However, the batchAnalysis module is mostly a backend for every other text
+module that does batch computation over a complete trace set.
+</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x127.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x169.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Control Flow View Colors</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The text dump module</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c162.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c162.html
new file mode 100644 (file)
index 0000000..037b802
--- /dev/null
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Using LTTV text modules</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Control Flow View Colors"
+HREF="x130.html"><LINK
+REL="NEXT"
+TITLE="The text dump module"
+HREF="x172.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x130.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x172.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN162"
+></A
+>Chapter 4. Using LTTV text modules</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="batchAnalysis"
+>4.1. The batch analysis module</A
+></H1
+><P
+>&#13;This batch analysis module can be invoked like this :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L path/to/lib/plugins -m batchAnalysis\
+-t trace1 -t trace2 ...</KBD
+>
+</PRE
+><P
+>&#13;It permits to call any registered action to perform in batch mode on all the
+trace set, which consists of the traces loaded on the command line. Actions that
+are built in the batchAnalysis module are statistics computation. They can be
+triggered by using the -s (--stats) switch.
+</P
+><P
+>&#13;However, the batchAnalysis module is mostly a backend for every other text
+module that does batch computation over a complete trace set.
+</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x130.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x172.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Control Flow View Colors</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The text dump module</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c20.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c20.html
new file mode 100644 (file)
index 0000000..e20602b
--- /dev/null
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Introduction</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="NEXT"
+TITLE="Getting started"
+HREF="c25.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="index.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c25.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN20"
+></A
+>Chapter 1. Introduction</H1
+><P
+>&#13;Linux Trace Toolkit (LTT) is a tracing tool that permits to get all the possible
+execution information from the Linux Kernel. It is based on kernel
+instrumentation and a high-speed relay file system to copy the information from
+the kernel space to the user space.
+</P
+><P
+>&#13;Linux Trace Toolkit Viewer (LTTV) is the second generation of visualization
+tool. It is 
+based on a trace format (the files where the data is recorded on disk) slightly
+different from LTT. As for now, November 29, 2004, the implementation of the new
+trace format in LTT is still not done, we must use a conversion tool to
+transform the original LTT traces to the new format.
+</P
+><P
+>&#13;This document explains all the steps that are necessary in order to record a
+trace with LTT and view it with LTTV.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Linux Trace Toolkit Viewer User Guide</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Getting started</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c25.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c25.html
new file mode 100644 (file)
index 0000000..c17f4f0
--- /dev/null
@@ -0,0 +1,214 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Getting started</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Introduction"
+HREF="c20.html"><LINK
+REL="NEXT"
+TITLE="Installing LTT kernel tracer"
+HREF="x46.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c20.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x46.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN25"
+></A
+>Chapter 2. Getting started</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="install"
+>2.1. Installing LTTV</A
+></H1
+><P
+>&#13;First, you must download the latests version of LTTV. You should get it from
+this site : <A
+HREF="http://ltt.polymtl.ca"
+TARGET="_top"
+>ltt.polymtl.ca</A
+>.
+I suggest that you get it from the "Packages" section.
+</P
+><P
+>&#13;You need a recent gcc compiler to compile the project. You might want to use gcc
+3.2 or newer.
+You will also need some libraries in order to compile it. They are described in
+the README of the LTTV package. These are GTK 2.0, GLIB 2.0, "popt" and Pango 1.0.
+Install them if they are not on your system. Remember that if you use a package
+manager from you favourite Linux distribution, you will need to specifically
+install the librairies'development packages.
+</P
+><P
+>&#13;Then, you are ready to compile LTTV. Extract and untar the file you previously
+downloaded : 
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>tar -xvzof LinuxTraceToolkitViewer-x.x-dddddddd.tar.bz2</KBD
+>
+</PRE
+><P
+>&#13;Then, go to the directory newly created, and type :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>./configure</KBD
+>
+<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>make</KBD
+>
+<SAMP
+CLASS="prompt"
+>#</SAMP
+> <KBD
+CLASS="userinput"
+>make install</KBD
+> (as root)
+</PRE
+><P
+>&#13;At this point, LTTV is installed in the default directory. You may find the
+lttv executable in /usr/local/bin and the librairies in /usr/local/lib. You will
+also notice the presence of the convert executable in /usr/local/bin. This tool
+will be used later to convert from the Linux Trace Toolkit trace format to the
+LTTV format.
+</P
+><P
+>&#13;You are now ready to go to the next step : installing the LTT kernel tracer.
+</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c20.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x46.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Introduction</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Installing LTT kernel tracer</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c88.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c88.html
new file mode 100644 (file)
index 0000000..1dcd862
--- /dev/null
@@ -0,0 +1,269 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Using LTTV graphical interface</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Running the executable with basic libraries"
+HREF="x78.html"><LINK
+REL="NEXT"
+TITLE="Control Flow View Colors"
+HREF="x127.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x78.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x127.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN88"
+></A
+>Chapter 3. Using LTTV graphical interface</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="mainwindow"
+>3.1. LTTV main window</A
+></H1
+><P
+>&#13;This section describes the main functionnalities that are provided by the LTTV
+GUI and how to use them.
+</P
+><P
+>&#13;By default, when the lttv GUI starts with all the graphical modules loaded,
+it loads the statistics viewer, the control flow viewer, and the detailed event
+list inside a tab. Other viewers can be added later to this tab by interacting
+with the main window. Let's describe the operations available on the window :
+</P
+><DIV
+CLASS="mediaobject"
+><P
+><IMG
+SRC="lttv-numbered-5.png"
+ALIGN="center"><DIV
+CLASS="caption"
+><P
+>Linux Trace Toolkit Viewer GUI</P
+></DIV
+></P
+></DIV
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>&#13;This toolbar allows you to navigate through the basic functionnalities of LTTV.
+The first button opens a new window and the second one, a new tab. You can leave
+your mouse over the buttons to read the information provided by the tooltips.
+</P
+></LI
+><LI
+><P
+>&#13;This notebook, containing different tabs, lets you select the "Trace Set" you
+want to interact with. A trace set is an aggregation of traces, synchronised in
+time. You may also want to use one tab per viewer by simply cloning the traceset
+to a new tab. This way, you can have vertically stacked viewers in one tab, as
+well as different viewers, independant from the time interval. Note that once
+the Trace Set cloning is done, each trace set becomes completely independant.
+For Traceset cloning, see the File Menu.
+</P
+></LI
+><LI
+><P
+>&#13;These buttons let you control the computation in progress on a trace. As
+sometimes the computation may last for a while, you may want to stop it, restart
+it from the beginning or simply to continue from where you stopped. This is
+exactly what those three buttons offer you.
+</P
+></LI
+><LI
+><P
+>&#13;Buttons on the right side of the last spacer are semantically different from the
+others. While the other buttons at the left side of the bar are built in the
+lttv program and let you operate the basic functionnalities, the buttons at the
+right side let you add a viewer to the active Tab. They belong to the
+viewers themselves. The number of buttons that appears there should directly
+depend on the number of viewer's modules loaded.
+</P
+></LI
+><LI
+><P
+>&#13;This is a tree representing the multiple statistics available for the current
+traceset. This is shown by the guistatistics viewer.
+</P
+></LI
+><LI
+><P
+>&#13;This is the Y axis of the guicontrolflow viewer. It shows the process list of
+the traced system. You may notice that it grows : it dynamically adds
+process when they appear in the trace.
+</P
+></LI
+><LI
+><P
+>&#13;This is a (missing) time bar for the X axis. Maybe will it be used for viewer
+specific buttons eventually. Work in progress.
+</P
+></LI
+><LI
+><P
+>&#13;The is the current time selected. The concept of current event and current time
+selected is synchronised in a Tab for all the viewers. The control flow viewer
+shows it a vertical white dotted line. You move this marker by clicking on the
+background of the process state graph. This graph shows evolution of each
+process's state through time. The meaning of the colors will be explained later.
+</P
+></LI
+><LI
+><P
+>&#13;This is the details event list. It shown the detailed information about each
+event of the trace. It is synchronised with the current time and current event,
+so selecting an event changes other viewer's current time and reciprocally.
+</P
+></LI
+><LI
+><P
+>&#13;You can enter the values of start time and end time you wish to see on the
+screen here. It also supports pasting time as text input, simply by clicking of
+the "Time Frame", "start" or "end:" fields. A valid entry consists of any
+digital input separated by any quantity of non digital characters. For example :
+"I start at 356247.124626 and stop at 724524.453455" would be a valid input
+for the "Time Frame" field.
+</P
+></LI
+><LI
+><P
+>&#13;This horizontal scrollbar modifies the window of time shown by all the viewers
+in the tab. It is linked with the fields below it (described at number 10 and
+12). Another way to modify the time shown is to use the zoom buttons of the
+toolbar (yes, the ones that looks like magnifying glasses).
+</P
+></LI
+><LI
+><P
+>&#13;This field works just like the "Time Frame" field. It modifies the current time
+selected by the viewers. For example, changing its value will change the current
+event selected by the detailed events list and the current time selected by the
+control flow viewer.
+</P
+></LI
+></OL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x78.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x127.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Running the executable with basic libraries</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Control Flow View Colors</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c91.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/c91.html
new file mode 100644 (file)
index 0000000..76ab982
--- /dev/null
@@ -0,0 +1,269 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Using LTTV graphical interface</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Running the executable with basic libraries"
+HREF="x81.html"><LINK
+REL="NEXT"
+TITLE="Control Flow View Colors"
+HREF="x130.html"></HEAD
+><BODY
+CLASS="chapter"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x81.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x130.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="chapter"
+><H1
+><A
+NAME="AEN91"
+></A
+>Chapter 3. Using LTTV graphical interface</H1
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="mainwindow"
+>3.1. LTTV main window</A
+></H1
+><P
+>&#13;This section describes the main functionnalities that are provided by the LTTV
+GUI and how to use them.
+</P
+><P
+>&#13;By default, when the lttv GUI starts with all the graphical modules loaded,
+it loads the statistics viewer, the control flow viewer, and the detailed event
+list inside a tab. Other viewers can be added later to this tab by interacting
+with the main window. Let's describe the operations available on the window :
+</P
+><DIV
+CLASS="mediaobject"
+><P
+><IMG
+SRC="lttv-numbered-5.png"
+ALIGN="center"><DIV
+CLASS="caption"
+><P
+>Linux Trace Toolkit Viewer GUI</P
+></DIV
+></P
+></DIV
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>&#13;This toolbar allows you to navigate through the basic functionnalities of LTTV.
+The first button opens a new window and the second one, a new tab. You can leave
+your mouse over the buttons to read the information provided by the tooltips.
+</P
+></LI
+><LI
+><P
+>&#13;This notebook, containing different tabs, lets you select the "Trace Set" you
+want to interact with. A trace set is an aggregation of traces, synchronised in
+time. You may also want to use one tab per viewer by simply cloning the traceset
+to a new tab. This way, you can have vertically stacked viewers in one tab, as
+well as different viewers, independant from the time interval. Note that once
+the Trace Set cloning is done, each trace set becomes completely independant.
+For Traceset cloning, see the File Menu.
+</P
+></LI
+><LI
+><P
+>&#13;These buttons let you control the computation in progress on a trace. As
+sometimes the computation may last for a while, you may want to stop it, restart
+it from the beginning or simply to continue from where you stopped. This is
+exactly what those three buttons offer you.
+</P
+></LI
+><LI
+><P
+>&#13;Buttons on the right side of the last spacer are semantically different from the
+others. While the other buttons at the left side of the bar are built in the
+lttv program and let you operate the basic functionnalities, the buttons at the
+right side let you add a viewer to the active Tab. They belong to the
+viewers themselves. The number of buttons that appears there should directly
+depend on the number of viewer's modules loaded.
+</P
+></LI
+><LI
+><P
+>&#13;This is a tree representing the multiple statistics available for the current
+traceset. This is shown by the guistatistics viewer.
+</P
+></LI
+><LI
+><P
+>&#13;This is the Y axis of the guicontrolflow viewer. It shows the process list of
+the traced system. You may notice that it grows : it dynamically adds
+process when they appear in the trace.
+</P
+></LI
+><LI
+><P
+>&#13;This is a (missing) time bar for the X axis. Maybe will it be used for viewer
+specific buttons eventually. Work in progress.
+</P
+></LI
+><LI
+><P
+>&#13;The is the current time selected. The concept of current event and current time
+selected is synchronised in a Tab for all the viewers. The control flow viewer
+shows it a vertical white dotted line. You move this marker by clicking on the
+background of the process state graph. This graph shows evolution of each
+process's state through time. The meaning of the colors will be explained later.
+</P
+></LI
+><LI
+><P
+>&#13;This is the details event list. It shown the detailed information about each
+event of the trace. It is synchronised with the current time and current event,
+so selecting an event changes other viewer's current time and reciprocally.
+</P
+></LI
+><LI
+><P
+>&#13;You can enter the values of start time and end time you wish to see on the
+screen here. It also supports pasting time as text input, simply by clicking of
+the "Time Frame", "start" or "end:" fields. A valid entry consists of any
+digital input separated by any quantity of non digital characters. For example :
+"I start at 356247.124626 and stop at 724524.453455" would be a valid input
+for the "Time Frame" field.
+</P
+></LI
+><LI
+><P
+>&#13;This horizontal scrollbar modifies the window of time shown by all the viewers
+in the tab. It is linked with the fields below it (described at number 10 and
+12). Another way to modify the time shown is to use the zoom buttons of the
+toolbar (yes, the ones that looks like magnifying glasses).
+</P
+></LI
+><LI
+><P
+>&#13;This field works just like the "Time Frame" field. It modifies the current time
+selected by the viewers. For example, changing its value will change the current
+event selected by the detailed events list and the current time selected by the
+control flow viewer.
+</P
+></LI
+></OL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x81.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x130.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Running the executable with basic libraries</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Control Flow View Colors</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/index.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/index.html
new file mode 100644 (file)
index 0000000..8c758e6
--- /dev/null
@@ -0,0 +1,210 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Linux Trace Toolkit Viewer User Guide</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="NEXT"
+TITLE="Introduction"
+HREF="c20.html"><META
+NAME="KEYWORD"
+CONTENT="Linux Trace Toolkit Viewer"><META
+NAME="KEYWORD"
+CONTENT="Linux Trace Toolkit"><META
+NAME="KEYWORD"
+CONTENT="tracing"><META
+NAME="KEYWORD"
+CONTENT="Linux"><META
+NAME="KEYWORD"
+CONTENT="visualization"><META
+NAME="KEYWORD"
+CONTENT="operating system"></HEAD
+><BODY
+CLASS="book"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="BOOK"
+><A
+NAME="AEN1"
+></A
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="title"
+><A
+NAME="AEN2"
+>Linux Trace Toolkit Viewer User Guide</A
+></H1
+><H3
+CLASS="author"
+><A
+NAME="AEN5"
+></A
+>Mathieu Desnoyers</H3
+><DIV
+><DIV
+CLASS="abstract"
+><P
+></P
+><A
+NAME="AEN10"
+></A
+><P
+>&#13;This document describes how to install <SPAN
+CLASS="application"
+>Linux Trace
+Toolkit Viewer</SPAN
+> and how to use it.
+
+</P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="c20.html"
+>Introduction</A
+></DT
+><DT
+>2. <A
+HREF="c25.html"
+>Getting started</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="c25.html#install"
+>Installing LTTV</A
+></DT
+><DT
+>2.2. <A
+HREF="x46.html"
+>Installing LTT kernel tracer</A
+></DT
+><DT
+>2.3. <A
+HREF="x54.html"
+>Installing LTT trace recording daemon</A
+></DT
+><DT
+>2.4. <A
+HREF="x64.html"
+>Conversion from LTT to LTTV trace format</A
+></DT
+><DT
+>2.5. <A
+HREF="x81.html"
+>Running the executable with basic libraries</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="c91.html"
+>Using LTTV graphical interface</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="c91.html#mainwindow"
+>LTTV main window</A
+></DT
+><DT
+>3.2. <A
+HREF="x130.html"
+>Control Flow View Colors</A
+></DT
+></DL
+></DD
+><DT
+>4. <A
+HREF="c162.html"
+>Using LTTV text modules</A
+></DT
+><DD
+><DL
+><DT
+>4.1. <A
+HREF="c162.html#batchAnalysis"
+>The batch analysis module</A
+></DT
+><DT
+>4.2. <A
+HREF="x172.html"
+>The text dump module</A
+></DT
+></DL
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c20.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Introduction</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-color-list.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-color-list.png
new file mode 100644 (file)
index 0000000..2fc6651
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-color-list.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-numbered-5.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-numbered-5.png
new file mode 100644 (file)
index 0000000..0f2e986
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/lttv-numbered-5.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x127.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x127.html
new file mode 100644 (file)
index 0000000..e9e40cd
--- /dev/null
@@ -0,0 +1,233 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Control Flow View Colors</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Using LTTV graphical interface"
+HREF="c88.html"><LINK
+REL="PREVIOUS"
+TITLE="Using LTTV graphical interface"
+HREF="c88.html"><LINK
+REL="NEXT"
+TITLE="Using LTTV text modules"
+HREF="c159.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c88.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. Using LTTV graphical interface</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c159.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="ControlFlowColors"
+>3.2. Control Flow View Colors</A
+></H1
+><DIV
+CLASS="mediaobject"
+><P
+><IMG
+SRC="lttv-color-list.png"
+ALIGN="center"><DIV
+CLASS="caption"
+><P
+>Control Flow View Color Legend</P
+></DIV
+></P
+></DIV
+><P
+>&#13;Here is a description of the colors used in the control flow view. Each color
+represents a state of the process at a given time.
+</P
+><P
+></P
+><UL
+><LI
+><P
+>&#13;White : this color is used for process from which state is not known. It may
+happen when you seek quickly at a far time in the trace just after it has been
+launched. At that moment, the precomputed state information is incomplete. The
+"unknown" state is used to identify this. Note that the viewer gets refreshed
+once the precomputation ends.
+</P
+></LI
+><LI
+><P
+>&#13;Green : This color is only used for process when they are running in user mode.
+That includes execution of all the source code of an executable as well as the
+libraries it uses.
+</P
+></LI
+><LI
+><P
+>&#13;Pale blue : A process is doing a system call to the kernel, and the mode is
+switched from process limited rights to super user mode. Only code from the
+kernel (including modules) should be run in that state.
+</P
+></LI
+><LI
+><P
+>&#13;Yellow : The kernel is running a trap that services a fault. The most frequent
+trap is the memory page fault trap : it is called every time a page is missing
+from physical memory.
+</P
+></LI
+><LI
+><P
+>&#13;Orange : IRQ servicing routine is running. It interrupts the currently running
+process. As the IRQ does not change the currently running process (on some
+architectures it uses the same stack as the process), the IRQ state is shown in
+the state of the process. IRQ can be nested : a higher priority interrupt can
+interrupt a lower priority interrupt.
+</P
+></LI
+><LI
+><P
+>&#13;Dark red : A process in that state is waiting for an input/output operation to
+complete before it can continue its execution.
+</P
+></LI
+><LI
+><P
+>&#13;Dark yellow : A process is ready to run, but waiting to get the CPU (a schedule
+in event).
+</P
+></LI
+><LI
+><P
+>&#13;Dark purple : A process in zombie state. This state happens when a process
+exits and then waits for the parent to wait for it (wait() or waitpid()).
+</P
+></LI
+><LI
+><P
+>&#13;Dark green : A process has just been created by its parent and is waiting for
+first scheduling.
+</P
+></LI
+><LI
+><P
+>&#13;Magenta : The process has exited, but still has the control of the CPU. It may
+happend if it has some tasks to do in the exit system call.
+</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c88.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c159.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Using LTTV graphical interface</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c88.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Using LTTV text modules</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x130.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x130.html
new file mode 100644 (file)
index 0000000..12cdb30
--- /dev/null
@@ -0,0 +1,233 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Control Flow View Colors</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Using LTTV graphical interface"
+HREF="c91.html"><LINK
+REL="PREVIOUS"
+TITLE="Using LTTV graphical interface"
+HREF="c91.html"><LINK
+REL="NEXT"
+TITLE="Using LTTV text modules"
+HREF="c162.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c91.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. Using LTTV graphical interface</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c162.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="ControlFlowColors"
+>3.2. Control Flow View Colors</A
+></H1
+><DIV
+CLASS="mediaobject"
+><P
+><IMG
+SRC="lttv-color-list.png"
+ALIGN="center"><DIV
+CLASS="caption"
+><P
+>Control Flow View Color Legend</P
+></DIV
+></P
+></DIV
+><P
+>&#13;Here is a description of the colors used in the control flow view. Each color
+represents a state of the process at a given time.
+</P
+><P
+></P
+><UL
+><LI
+><P
+>&#13;White : this color is used for process from which state is not known. It may
+happen when you seek quickly at a far time in the trace just after it has been
+launched. At that moment, the precomputed state information is incomplete. The
+"unknown" state is used to identify this. Note that the viewer gets refreshed
+once the precomputation ends.
+</P
+></LI
+><LI
+><P
+>&#13;Green : This color is only used for process when they are running in user mode.
+That includes execution of all the source code of an executable as well as the
+libraries it uses.
+</P
+></LI
+><LI
+><P
+>&#13;Pale blue : A process is doing a system call to the kernel, and the mode is
+switched from process limited rights to super user mode. Only code from the
+kernel (including modules) should be run in that state.
+</P
+></LI
+><LI
+><P
+>&#13;Yellow : The kernel is running a trap that services a fault. The most frequent
+trap is the memory page fault trap : it is called every time a page is missing
+from physical memory.
+</P
+></LI
+><LI
+><P
+>&#13;Orange : IRQ servicing routine is running. It interrupts the currently running
+process. As the IRQ does not change the currently running process (on some
+architectures it uses the same stack as the process), the IRQ state is shown in
+the state of the process. IRQ can be nested : a higher priority interrupt can
+interrupt a lower priority interrupt.
+</P
+></LI
+><LI
+><P
+>&#13;Dark red : A process in that state is waiting for an input/output operation to
+complete before it can continue its execution.
+</P
+></LI
+><LI
+><P
+>&#13;Dark yellow : A process is ready to run, but waiting to get the CPU (a schedule
+in event).
+</P
+></LI
+><LI
+><P
+>&#13;Dark purple : A process in zombie state. This state happens when a process
+exits and then waits for the parent to wait for it (wait() or waitpid()).
+</P
+></LI
+><LI
+><P
+>&#13;Dark green : A process has just been created by its parent and is waiting for
+first scheduling.
+</P
+></LI
+><LI
+><P
+>&#13;Magenta : The process has exited, but still has the control of the CPU. It may
+happend if it has some tasks to do in the exit system call.
+</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c91.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c162.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Using LTTV graphical interface</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c91.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Using LTTV text modules</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x169.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x169.html
new file mode 100644 (file)
index 0000000..d2409ac
--- /dev/null
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>The text dump module</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Using LTTV text modules"
+HREF="c159.html"><LINK
+REL="PREVIOUS"
+TITLE="Using LTTV text modules"
+HREF="c159.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c159.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 4. Using LTTV text modules</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="textDump"
+>4.2. The text dump module</A
+></H1
+><P
+>&#13; The goal of this module is to convert the binary data of the traces into
+a formatted text file.
+</P
+><P
+>&#13;The text dump module is a good example of a usage of the batch analysis module
+backend. In fact, the text dump module depends on it. You don't need to
+explicitly load the batchAnalysis module though, as lttv offers a rich module
+backend that deals with the dependencies, loading the module automatically if
+needed.
+</P
+><P
+>&#13;The text dump module is invoked just like the batchAnalysis module. It adds more
+options that can be specified in argument. You may specify the -o switch for the
+output file name of the text dump. You can enable the output of the field names
+(the identifier of the fields) with the -l switch. The -s switch, for process
+states, is very useful to indicate the state in which the process is when the
+event happens.
+</P
+><P
+>&#13;If you use the --help option on the textDump module, you will see all the detail
+about the switches that can be used to show per cpu statistics and per process
+statistics. You will notice that you can use both the switches for the
+batchAnalysis module and those for textDump. You will also notice that the
+options --process_state (from textDump) and --stats (from batchAnalysis) has the
+same short name "-s". If you choose to invoke this option using the short name,
+it will use the option of the last module loaded just before the -s switch.
+</P
+><P
+>&#13;For exemple, if you load the textDump module with -m textDump, it will first
+load the batchAnalysis module, and then load itself. As it is the last module
+loaded, the -s switch used after it will signify --process_stats. On the other
+hand, if you choose to specify explicitly the loading of both modules like this
+:
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L path/to/lib/plugins -m batchAnalysis -s\
+-m textDump -s -t trace</KBD
+>
+</PRE
+><P
+>&#13;The first "-s" will invoke batchAnalysis --stats and the second "-s" will invoke
+textDump --process_state. The list of options generated by --help follows the
+order of registration of the options by the modules, therefore the invocation 
+order of the modules.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c159.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Using LTTV text modules</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c159.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x172.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x172.html
new file mode 100644 (file)
index 0000000..b5fc335
--- /dev/null
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>The text dump module</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Using LTTV text modules"
+HREF="c162.html"><LINK
+REL="PREVIOUS"
+TITLE="Using LTTV text modules"
+HREF="c162.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c162.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 4. Using LTTV text modules</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="textDump"
+>4.2. The text dump module</A
+></H1
+><P
+>&#13; The goal of this module is to convert the binary data of the traces into
+a formatted text file.
+</P
+><P
+>&#13;The text dump module is a good example of a usage of the batch analysis module
+backend. In fact, the text dump module depends on it. You don't need to
+explicitly load the batchAnalysis module though, as lttv offers a rich module
+backend that deals with the dependencies, loading the module automatically if
+needed.
+</P
+><P
+>&#13;The text dump module is invoked just like the batchAnalysis module. It adds more
+options that can be specified in argument. You may specify the -o switch for the
+output file name of the text dump. You can enable the output of the field names
+(the identifier of the fields) with the -l switch. The -s switch, for process
+states, is very useful to indicate the state in which the process is when the
+event happens.
+</P
+><P
+>&#13;If you use the --help option on the textDump module, you will see all the detail
+about the switches that can be used to show per cpu statistics and per process
+statistics. You will notice that you can use both the switches for the
+batchAnalysis module and those for textDump. You will also notice that the
+options --process_state (from textDump) and --stats (from batchAnalysis) has the
+same short name "-s". If you choose to invoke this option using the short name,
+it will use the option of the last module loaded just before the -s switch.
+</P
+><P
+>&#13;For exemple, if you load the textDump module with -m textDump, it will first
+load the batchAnalysis module, and then load itself. As it is the last module
+loaded, the -s switch used after it will signify --process_stats. On the other
+hand, if you choose to specify explicitly the loading of both modules like this
+:
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L path/to/lib/plugins -m batchAnalysis -s\
+-m textDump -s -t trace</KBD
+>
+</PRE
+><P
+>&#13;The first "-s" will invoke batchAnalysis --stats and the second "-s" will invoke
+textDump --process_state. The list of options generated by --help follows the
+order of registration of the options by the modules, therefore the invocation 
+order of the modules.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c162.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Using LTTV text modules</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c162.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x46.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x46.html
new file mode 100644 (file)
index 0000000..b85e936
--- /dev/null
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Installing LTT kernel tracer</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="PREVIOUS"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="NEXT"
+TITLE="Installing LTT trace recording daemon"
+HREF="x54.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c25.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Getting started</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x54.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="install-tracer"
+>2.2. Installing LTT kernel tracer</A
+></H1
+><P
+>&#13;The goal of this guide is not to describe the Linux Trace Toolkit project in
+details, as it is a
+seperate project for now. It just gives pointers to the basic steps you must
+take in order to generate a trace suitable for conversion.
+</P
+><P
+>&#13;First, go to the <A
+HREF="http://ltt.polymtl.ca"
+TARGET="_top"
+>ltt.polymtl.ca</A
+>
+website, in the "Patches for the Official LTT" section. Use the latest version
+of patches available. The file name convention used goes like this : 
+aaaaaa-x.x--bbbbb-y.y.patch. That means a patch made for aaaaa, release x.x,
+that adds bbbbb, release y.y to it. Notice the presence of the -- sign that
+separates the "from" field from the name of the patch applied. This way, it's
+impossible to be mixed up on the specific sequence of patch application. I
+suggest that you use the "relayfs", "ltt" and then "md" patches. The "md" patch
+adds events useful to LTTV that are not in the official LTT.
+</P
+><P
+>&#13;Once you have the patches you need, get the matching Linux kernel version, apply
+the patches on it, configure it, install it, reboot with the new kernel. You then
+have an instrumented kernel ready for tracing. If you have problems during this phase,
+please refer to <A
+HREF="http://www.opersys.com/ltt"
+TARGET="_top"
+>www.opersys.com/ltt</A
+>. If you need
+instructions about how to recompile a kernel, see
+<A
+HREF="http://www.tldp.org/HOWTO/Kernel-HOWTO/"
+TARGET="_top"
+>Kernel-HOWTO</A
+>.
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x54.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Getting started</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Installing LTT trace recording daemon</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x54.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x54.html
new file mode 100644 (file)
index 0000000..e2453f7
--- /dev/null
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Installing LTT trace recording daemon</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="PREVIOUS"
+TITLE="Installing LTT kernel tracer"
+HREF="x46.html"><LINK
+REL="NEXT"
+TITLE="Conversion from LTT to LTTV trace format"
+HREF="x64.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x46.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Getting started</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x64.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="install-daemon"
+>2.3. Installing LTT trace recording daemon</A
+></H1
+><P
+>&#13;In order to install the LTT trace recording daemon, you should get the latest
+TraceToolkit (or ltt) package from the LTT ftp site.
+Use the link "Official Linux Trace Toolkit Packages" on the
+<A
+HREF="http://ltt.polymtl.ca"
+TARGET="_top"
+>ltt.polymtl.ca</A
+> webpage to access it.
+As of November 30, 2004, the most recent version is 0.9.6-pre3.
+</P
+><P
+>&#13;Then, you should apply the TraceToolkit patches from the LTTV website related
+to the package version. Get them from the "Patches for the Official LTT"
+section.
+</P
+><P
+>&#13;You are now ready to install the daemon in your system. Please refer to the
+documentation in the package for details.
+</P
+><P
+>&#13;You may now use the following command to record a sample 30 seconds trace in
+your current directory. Command line switches are described on the official
+LTT website.
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>#</SAMP
+><KBD
+CLASS="userinput"
+>tracedaemon -ts30 sample.out sample.proc (as root) userinput&#62;</KBD
+>
+</PRE
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x46.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x64.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Installing LTT kernel tracer</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Conversion from LTT to LTTV trace format</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x61.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x61.html
new file mode 100644 (file)
index 0000000..c58b1de
--- /dev/null
@@ -0,0 +1,204 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Conversion from LTT to LTTV trace format</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="PREVIOUS"
+TITLE="Installing LTT trace recording daemon"
+HREF="x54.html"><LINK
+REL="NEXT"
+TITLE="Running the executable with basic libraries"
+HREF="x78.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x54.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Getting started</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x78.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="convert"
+>2.4. Conversion from LTT to LTTV trace format</A
+></H1
+><P
+>&#13;If you used the default directory for installation, you should find the
+conversion tool in /usr/local/bin/convert. Before using it, some other files are
+necessary. You will find them in
+/usr/local/share/LinuxTraceToolkitViewer/convert/. Those are sysInfo and
+core.xml.
+</P
+><P
+>&#13;sysInfo is a script that get informations about the traced computer. It should
+be invoked like this :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>sh /usr/local/LinuxTraceToolkitViewer/convert/sysInfo</KBD
+>
+</PRE
+><P
+>&#13;It created a file named sysInfo.out. This file has to be present in the current
+directory where the convert tool will be executed. I suggest that you choose a
+destination directory for converted traces right now, put sysInfo.out in it, at
+use it as current directory for running the convert tool.
+</P
+><P
+>&#13;Once the sysInfo.out file is ready and you have a trace ready for conversion,
+you should invoke convert like the following example. This is for a uniprocessor
+computer. If you whish to get detailed explanation on the parameters, simply
+execute the convert tool without any. You may also wish to see the
+/usr/local/LinuxTraceToolkitViewer/convert/README file.
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>/usr/local/bin/convert sample.proc 1 sample.trace sample.converted</KBD
+>
+</PRE
+><P
+>&#13;You must then copy the core event definition file to the converted trace directory :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>cp /usr/local/share/LinuxTraceToolkitViewer/convert/core.xml sample.converted/</KBD
+>
+</PRE
+><P
+>&#13;You now have a converted trace ready for visualization in LTTV. Congratulations!
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x54.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x78.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Installing LTT trace recording daemon</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Running the executable with basic libraries</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x64.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x64.html
new file mode 100644 (file)
index 0000000..87d2a99
--- /dev/null
@@ -0,0 +1,204 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Conversion from LTT to LTTV trace format</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="PREVIOUS"
+TITLE="Installing LTT trace recording daemon"
+HREF="x54.html"><LINK
+REL="NEXT"
+TITLE="Running the executable with basic libraries"
+HREF="x81.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x54.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Getting started</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x81.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="convert"
+>2.4. Conversion from LTT to LTTV trace format</A
+></H1
+><P
+>&#13;If you used the default directory for installation, you should find the
+conversion tool in /usr/local/bin/convert. Before using it, some other files are
+necessary. You will find them in
+/usr/local/share/LinuxTraceToolkitViewer/convert/. Those are sysInfo and
+core.xml.
+</P
+><P
+>&#13;sysInfo is a script that get informations about the traced computer. It should
+be invoked like this :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>sh /usr/local/LinuxTraceToolkitViewer/convert/sysInfo</KBD
+>
+</PRE
+><P
+>&#13;It creates a file named sysInfo.out. This file has to be present in the current
+directory where the convert tool will be executed. I suggest that you choose a
+destination directory where will be written converted traces right now, put sysInfo.out in it, at
+use it as current directory for running the convert tool.
+</P
+><P
+>&#13;Once the sysInfo.out file is ready and you have a trace ready for conversion,
+you should invoke convert like the following example. This is for a uniprocessor
+computer. If you whish to get detailed explanation on the parameters, simply
+execute the convert tool without any option. You may also wish to see the
+/usr/local/LinuxTraceToolkitViewer/convert/README file.
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>/usr/local/bin/convert sample.proc 1 sample.trace sample.converted</KBD
+>
+</PRE
+><P
+>&#13;You must then copy the core event definition file to the converted trace directory :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>cp /usr/local/share/LinuxTraceToolkitViewer/convert/core.xml sample.converted/</KBD
+>
+</PRE
+><P
+>&#13;You now have a converted trace ready for visualization in LTTV. Congratulations!
+</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x54.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x81.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Installing LTT trace recording daemon</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Running the executable with basic libraries</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x78.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x78.html
new file mode 100644 (file)
index 0000000..676b4e2
--- /dev/null
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Running the executable with basic libraries</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="PREVIOUS"
+TITLE="Conversion from LTT to LTTV trace format"
+HREF="x61.html"><LINK
+REL="NEXT"
+TITLE="Using LTTV graphical interface"
+HREF="c88.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x61.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Getting started</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c88.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="running"
+>2.5. Running the executable with basic libraries</A
+></H1
+><P
+>&#13;Starting the graphical mode with the basic viewer activated is as simple as :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L /usr/local/lib/lttv/plugins -m lttvwindow\
+-m guievents -m guicontrolflow -m guistatistics -t sample.converted/</KBD
+>
+</PRE
+><P
+>&#13;Using the text mode is very simple too. Look in /usr/local/lib/lttv/plugins for
+the list of modules. You may use the --help switch to get basic help on the
+command line parameters of every loaded modules. To simply output the events of
+a trace in a text file, try the textDump module. The batchAnalysis module
+permits to do batch mode analysis (state and statistics calculation ) on a
+trace.
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L /usr/local/lib/lttv/plugins -m textDump --help</KBD
+>
+</PRE
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x61.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c88.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Conversion from LTT to LTTV trace format</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Using LTTV graphical interface</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x81.html b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/html/x81.html
new file mode 100644 (file)
index 0000000..1e26c6d
--- /dev/null
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Running the executable with basic libraries</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="Linux Trace Toolkit Viewer User Guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Getting started"
+HREF="c25.html"><LINK
+REL="PREVIOUS"
+TITLE="Conversion from LTT to LTTV trace format"
+HREF="x64.html"><LINK
+REL="NEXT"
+TITLE="Using LTTV graphical interface"
+HREF="c91.html"></HEAD
+><BODY
+CLASS="sect1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Linux Trace Toolkit Viewer User Guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x64.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Getting started</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c91.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="sect1"
+><H1
+CLASS="sect1"
+><A
+NAME="running"
+>2.5. Running the executable with basic libraries</A
+></H1
+><P
+>&#13;Starting the graphical mode with the basic viewer activated is as simple as :
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L /usr/local/lib/lttv/plugins -m lttvwindow\
+-m guievents -m guicontrolflow -m guistatistics -t sample.converted/</KBD
+>
+</PRE
+><P
+>&#13;Using the text mode is very simple too. Look in /usr/local/lib/lttv/plugins for
+the list of modules. You may use the --help switch to get basic help on the
+command line parameters of every loaded modules. To simply output the events of
+a trace in a text file, try the textDump module. The batchAnalysis module
+permits to do batch mode analysis (state and statistics calculation ) on a
+trace.
+</P
+><PRE
+CLASS="screen"
+>&#13;<SAMP
+CLASS="prompt"
+>$</SAMP
+> <KBD
+CLASS="userinput"
+>lttv -L /usr/local/lib/lttv/plugins -m textDump --help</KBD
+>
+</PRE
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x64.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c91.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Conversion from LTT to LTTV trace format</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c25.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Using LTTV graphical interface</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/user_guide.dvi b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/user_guide.dvi
new file mode 100644 (file)
index 0000000..a0fa28e
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doc/user/user_guide/user_guide.dvi differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doxyfile b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/doxyfile
new file mode 100644 (file)
index 0000000..9aa6785
--- /dev/null
@@ -0,0 +1,1219 @@
+# Doxyfile 1.4.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = Linux Trace Toolkit Viewer 
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 0.4 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = YES
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the progam writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ./ltt/ ./lttv/ ./lttd/
+#INPUT                   = ./lttv/lttv/filter.c ./lttv/lttv/filter.h ./lttv/modules/gui/filter/filter.c ./lttv/modules/text/textFilter.c
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = *.c *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = ./lttv/modules/examples/ 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES 
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 1
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES 
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = YES 
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO 
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/Makefile.am
new file mode 100644 (file)
index 0000000..af48d36
--- /dev/null
@@ -0,0 +1,27 @@
+
+EXTRA_DIST =  \
+core.xml \
+fs.xml \
+ipc.xml \
+kernel.xml \
+memory.xml \
+network.xml \
+process.xml \
+s390_kernel.xml \
+socket.xml \
+timer.xml
+
+facilities_DATA = \
+core.xml \
+fs.xml \
+ipc.xml \
+kernel.xml \
+memory.xml \
+network.xml \
+process.xml \
+s390_kernel.xml \
+socket.xml \
+timer.xml
+
+
+facilitiesdir = $(pkgdatadir)/facilities
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/core.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/core.xml
new file mode 100644 (file)
index 0000000..c9004d3
--- /dev/null
@@ -0,0 +1,53 @@
+<facility name=core>
+  <description>The core facility contains the basic tracing related events</description>
+
+  <event name=facility_load>
+    <description>Facility is loaded</description>
+    <struct>
+      <field name="name"><string/></field>
+      <field name="checksum"><uint size=4/></field>
+      <field name="id"><uint size=4/></field>
+      <field name="long_size"><uint size=4/></field>
+      <field name="pointer_size"><uint size=4/></field>
+      <field name="size_t_size"><uint size=4/></field>
+      <field name="alignment"><uint size=4/></field>
+    </struct>
+  </event>
+
+  <event name=facility_unload>
+    <description>Facility is unloaded</description>
+    <struct>
+      <field name="id"><uint size=4/></field>
+    </struct>
+  </event>
+
+  <event name=time_heartbeat per_tracefile>
+    <description>System time values sent periodically to detect cycle counter
+     rollovers. Useful when only the 32 LSB of the TSC are saved in events
+     header : we save the full 64 bits in this event.
+    </description>
+    <typeref name=timestamp/>
+  </event>
+  
+  <event name=state_dump_facility_load per_trace>
+    <description>Facility is loaded while in state dump</description>
+    <struct>
+      <field name="name"><string/></field>
+      <field name="checksum"><uint size=4/></field>
+      <field name="id"><uint size=4/></field>
+      <field name="long_size"><uint size=4/></field>
+      <field name="pointer_size"><uint size=4/></field>
+      <field name="size_t_size"><uint size=4/></field>
+      <field name="alignment"><uint size=4/></field>
+    </struct>
+  </event>
+
+  <type name=timestamp>
+    <struct>
+      <field name="seconds"><uint size=4/></field>
+      <field name="nanoseconds"><uint size=4/></field>
+      <field name="cycle_count"><uint size=8/></field>
+    </struct>
+  </type>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/fs.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/fs.xml
new file mode 100644 (file)
index 0000000..2e47502
--- /dev/null
@@ -0,0 +1,89 @@
+<facility name=fs>
+  <description>The fs facility contains events related to file system operation</description>
+
+  <event name=buf_wait_start>
+    <description>Staring to wait for a buffer</description>
+    <struct>
+      <field name="address"> <description>Address of the buffer head.</description> <pointer/> </field>
+    </struct>
+  </event>
+
+  <event name=buf_wait_end>
+    <description>Ending to wait for a buffer</description>
+    <struct>
+      <field name="address"> <description>Address of the buffer head.</description> <pointer/> </field>
+    </struct>
+  </event>
+
+  <event name=exec>
+    <description>Executing a file</description>
+    <struct>
+      <field name="filename"> <description>File name</description> <string/> </field>
+    </struct>
+  </event>
+
+  <event name=open>
+    <description>Opening a file</description>
+    <struct>
+      <field name="filename"> <description>File name</description> <string/> </field>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=close>
+    <description>Closing a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=read>
+    <description>Reading from a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+      <field name="count"> <description>Number of bytes to read</description> <size_t/> </field>
+    </struct>
+  </event>
+       
+  <event name=write>
+    <description>Write to a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+      <field name="count"> <description>Number of bytes to write</description> <size_t/> </field>
+    </struct>
+  </event>
+
+  <event name=seek>
+    <description>Seek a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+      <field name="offset"> <description>Number of bytes to write</description> <off_t/> </field>
+      <field name="origin"> <description>Number of bytes to write</description> <uint size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=ioctl>
+    <description>Do a IOCTL on a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+      <field name="cmd"> <description>Command</description> <uint size=4/> </field>
+      <field name="arg"> <description>Argument</description> <uint size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=select>
+    <description>Do a select on a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+      <field name="timeout"> <description>Time out</description> <ulong/> </field>
+    </struct>
+  </event>
+
+  <event name=poll>
+    <description>Do a poll on a file descriptor</description>
+    <struct>
+      <field name="fd"> <description>File descriptor</description> <uint size=4/> </field>
+    </struct>
+  </event>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/ipc.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/ipc.xml
new file mode 100644 (file)
index 0000000..1a0c47a
--- /dev/null
@@ -0,0 +1,37 @@
+<facility name=ipc>
+  <description>The ipc facility contains events related to Inter Process Communication</description>
+       
+  <event name=call>
+
+    <description>IPC call</description>
+    <struct>
+      <field name="call_number"> <description>Number of IPC call</description> <uint size=4/> </field>
+
+      <field name="first"> <description>First argument</description> <int size=4/> </field>
+    </struct>
+  </event>
+  <event name=msg_create>
+    <description>Get an IPC message queue identifier</description>
+    <struct>
+      <field name="id"> <description>Message queue identifier</description><long/> </field>
+      <field name="flags"> <description>Message flags</description> <int size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=sem_create>
+    <description>Get an IPC semaphore identifier</description>
+    <struct>
+      <field name="id"> <description>Semaphore identifier</description> <long/> </field>
+      <field name="flags"> <description>Semaphore flags</description> <int size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=shm_create>
+    <description>Get an IPC shared memory identifier</description>
+    <struct>
+      <field name="id"> <description>Shared memory identifier</description> <long/> </field>
+      <field name="flags"> <description>Shared memory flags</description> <int size=4/> </field>
+    </struct>
+  </event>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/kernel.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/kernel.xml
new file mode 100644 (file)
index 0000000..dd98a6c
--- /dev/null
@@ -0,0 +1,86 @@
+<facility name=kernel>
+  <description>The kernel facility has events related to kernel execution status.</description>
+
+  <event name=syscall_entry>
+    <description>System call entry</description>
+    <struct>
+      <field name="syscall_id"> <description>Syscall entry number in entry.S</description> <uint size=1/> </field>
+      <field name="address"> <description>Address from which call was made</description> <pointer/> </field>
+     </struct>
+  </event>
+       
+       <event name=syscall_exit>
+    <description>System call exit</description>
+  </event>
+       
+  <event name=trap_entry>
+    <description>Entry in a trap</description>
+    <struct>
+      <field name="trap_id"> <description>Trap number</description> <uint size=2/> </field>
+      <field name="address"> <description>Address where trap occured</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=trap_exit>
+    <description>Exit from a trap</description>
+  </event>
+
+  <event name=soft_irq_entry>
+    <description>Soft IRQ entry</description>
+    <struct>
+      <field name="softirq_id"> <description>Soft IRQ number</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=soft_irq_exit>
+    <description>Soft IRQ exit</description>
+    <struct>
+      <field name="softirq_id"> <description>Soft IRQ number</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=tasklet_entry>
+    <description>Tasklet entry</description>
+    <struct>
+      <field name="priority"> <description>Tasklet priority</description> <typeref name=tasklet_priority/> </field>
+      <field name="address"> <description>Tasklet function address</description> <pointer/> </field>
+      <field name="data"> <description>Tasklet data address</description> <ulong/> </field>
+     </struct>
+  </event>
+
+  <event name=tasklet_exit>
+    <description>Tasklet exit</description>
+    <struct>
+      <field name="priority"> <description>Tasklet priority</description> <typeref name=tasklet_priority/> </field>
+      <field name="address"> <description>Tasklet function address</description> <pointer/> </field>
+      <field name="data"> <description>Tasklet data address</description> <ulong/> </field>
+     </struct>
+  </event>
+
+  <event name=irq_entry>
+    <description>Entry in an irq</description>
+    <struct>
+      <field name="irq_id"> <description>IRQ number</description> <uint size=4/> </field>
+      <field name="mode"> <description>Are we executing kernel code</description> <typeref name=irq_mode/> </field>
+     </struct>
+  </event>
+
+  <event name=irq_exit>
+    <description>Exit from an IRQ</description>
+  </event>
+
+  <type name=tasklet_priority>
+    <enum size=1>
+      <label name=LOW value=0/> <description>Low priority tasklet</description>
+      <label name=HIGH value=1/> <description>High priority tasklet</description>
+    </enum>
+  </type>
+
+  <type name=irq_mode>
+    <enum size=1>
+      <label name=user value=0/> <description>User context</description>
+      <label name=kernel value=1/> <description>Kernel context</description>
+    </enum>
+  </type>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/memory.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/memory.xml
new file mode 100644 (file)
index 0000000..b6788f6
--- /dev/null
@@ -0,0 +1,49 @@
+<facility name=memory>
+  <description>The memory facility has memory management events.</description>
+
+  <event name=page_alloc>
+    <description>Page allocation</description>
+    <struct>
+      <field name="order"> <description>Order of the page to allocate</description> <uint size=4/> </field>
+      <field name="address"> <description>Assigned page address, or 0 if
+                       failed.</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=page_free>
+    <description>Page free</description>
+    <struct>
+      <field name="order"> <description>Order of the page to free</description> <uint size=4/> </field>
+      <field name="address"> <description>Address of the page to free.</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=swap_in>
+    <description>Page swapped into memory</description>
+    <struct>
+      <field name="address"> <description>Address of the page to swap in.</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=swap_out>
+    <description>Page swapped to disk</description>
+    <struct>
+      <field name="address"> <description>Address of the page to swap out.</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=page_wait_start>
+    <description>Staring to wait for a page</description>
+    <struct>
+      <field name="address"> <description>Address of the page we wait for.</description> <pointer/> </field>
+     </struct>
+  </event>
+
+  <event name=page_wait_end>
+    <description>Ending wait for a page</description>
+    <struct>
+      <field name="address"> <description>Address of the page we wait for.</description> <pointer/> </field>
+     </struct>
+  </event>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/network.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/network.xml
new file mode 100644 (file)
index 0000000..f80f8cb
--- /dev/null
@@ -0,0 +1,20 @@
+<facility name=network>
+  <description>The network facility contains events related to low level network operations</description>
+
+  <event name=packet_in>
+    <description>A packet is arriving</description>
+    <struct>
+      <field name="skbuff"> <description>Socket buffer pointer : identify the socket buffer</description> <pointer/> </field>
+      <field name="protocol"> <description>Protocol of the packet</description> <uint size=2/> </field>
+    </struct>
+  </event>
+
+  <event name=packet_out>
+    <description>We send a packet</description>
+    <struct>
+      <field name="skbuff"> <description>Socket buffer pointer : identify the socket buffer</description> <pointer/> </field>
+      <field name="protocol"> <description>Protocol of the packet</description> <uint size=2/> </field>
+    </struct>
+  </event>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/process.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/process.xml
new file mode 100644 (file)
index 0000000..85dbf43
--- /dev/null
@@ -0,0 +1,116 @@
+<facility name=process>
+  <description>The process facility has events related to process handling in
+       the kernel.</description>
+
+  <event name=fork>
+    <description>Process fork</description>
+    <struct>
+      <field name="parent_pid"> <description>PID of the parent process</description> <uint size=4/> </field>
+      <field name="child_pid"> <description>PID of the child process</description> <uint size=4/> </field>
+     </struct>
+  </event>
+       
+  <event name=kernel_thread>
+    <description>Just created a new kernel thread</description>
+    <struct>
+      <field name="pid"> <description>PID of the kernel thread</description> <uint size=4/> </field>
+      <field name="function"> <description>Function called</description> <pointer/> </field>
+     </struct>
+  </event>
+
+
+  <event name=exit>
+    <description>Process exit</description>
+    <struct>
+      <field name="pid"> <description>PID of the process</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=wait>
+    <description>Process wait</description>
+    <struct>
+      <field name="parent_pid"> <description>PID of the waiting process</description> <uint size=4/> </field>
+      <field name="child_pid"> <description>PID of the process waited for</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=free>
+    <description>Process kernel data structure free (end of life of a zombie)</description>
+    <struct>
+      <field name="pid"> <description>PID of the freed process</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=kill>
+    <description>Process kill system call</description>
+    <struct>
+      <field name="pid"> <description>PID of the process</description> <uint size=4/> </field>
+      <field name="target_pid"> <description>PID of the process to kill</description> <uint size=4/> </field>
+      <field name="signal"> <description>Signal number</description> <typeref name=signal_name/> </field>
+     </struct>
+  </event>
+
+  <event name=signal>
+    <description>Process signal reception</description>
+    <struct>
+      <field name="pid"> <description>PID of the receiving process</description> <uint size=4/> </field>
+      <field name="signal"> <description>Signal number</description> <typeref name=signal_name/> </field>
+     </struct>
+  </event>
+
+  <event name=wakeup>
+    <description>Process wakeup</description>
+    <struct>
+      <field name="pid"> <description>PID of the receiving process</description> <uint size=4/> </field>
+      <field name="state"> <description>State of the awakened process. -1 unrunnable, 0 runnable, >0 stopped.</description> <int size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=schedchange>
+    <description>Scheduling change</description>
+    <struct>
+      <field name="out"> <description>Outgoing process</description> <uint size=4/> </field>
+      <field name="in"> <description>Incoming process</description> <uint size=4/> </field>
+      <field name="out_state"> <description>Outgoing process' state. -1 unrunnable, 0 runnable, >0 stopped.</description> <int size=4/> </field>
+     </struct>
+  </event>
+
+  <type name=signal_name>
+    <enum size=4>
+      <label name=SIGHUP value=1/> <description>Hangup (POSIX).</description>
+      <label name=SIGINT value=2/> <description>Interrupt (ANSI).</description>
+      <label name=SIGQUIT value=3/> <description>Quit (POSIX).</description>
+      <label name=SIGILL value=4/> <description>Illegal instruction (ANSI).</description>
+      <label name=SIGTRAP value=5/> <description>Trace trap (POSIX).</description>
+      <label name=SIGABRT value=6/> <description>Abort (ANSI).</description>
+      <label name=SIGBUS value=7/> <description>BUS error (4.2 BSD).</description>
+      <label name=SIGFPE value=8/> <description>Floating-point exception (ANSI).</description>
+      <label name=SIGKILL value=9/> <description>Kill, unblockable (POSIX).</description>
+      <label name=SIGUSR1 value=10/> <description>User-defined signal 1 (POSIX).</description>
+      <label name=SIGSEGV value=11/> <description>Segmentation violation (ANSI).</description>
+      <label name=SIGUSR2 value=12/> <description>User-defined signal 2 (POSIX).</description>
+      <label name=SIGPIPE value=13/> <description>Broken pipe (POSIX).</description>
+      <label name=SIGALRM value=14/> <description>Alarm clock (POSIX).</description>
+      <label name=SIGTERM value=15/> <description>Termination (ANSI).</description>
+      <label name=SIGSTKFLT value=16/> <description>Stack fault.</description>
+  
+      <label name=SIGCHLD value=17/> <description>Child status has changed (POSIX).</description>
+      <label name=SIGCONT value=18/> <description>Continue (POSIX).</description>
+      <label name=SIGSTOP value=19/> <description>Stop, unblockable (POSIX).</description>
+      <label name=SIGTSTP value=20/> <description>Keyboard stop (POSIX).</description>
+      <label name=SIGTTIN value=21/> <description>Background read from tty (POSIX).</description>
+      <label name=SIGTTOU value=22/> <description>Background write to tty (POSIX).</description>
+      <label name=SIGURG value=23/> <description>Urgent condition on socket (4.2 BSD).</description>
+      <label name=SIGXCPU value=24/> <description>CPU limit exceeded (4.2 BSD).</description>
+      <label name=SIGXFSZ value=25/> <description>File size limit exceeded (4.2 BSD).</description>
+      <label name=SIGVTALRM value=26/> <description>Virtual alarm clock (4.2 BSD).</description>
+      <label name=SIGPROF value=27/> <description>Profiling alarm clock (4.2 BSD).</description>
+      <label name=SIGWINCH value=28/> <description>Window size change (4.3 BSD, Sun).</description>
+      <label name=SIGIO value=29/> <description>I/O now possible (4.2 BSD). (aka SIGPOLL)</description>
+      <label name=SIGPWR value=30/> <description>Power failure restart (System V).</description>
+      <label name=SIGSYS value=31/> <description>Bad system call.</description>
+    </enum>
+  </type>
+
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/s390_kernel.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/s390_kernel.xml
new file mode 100644 (file)
index 0000000..8334c9d
--- /dev/null
@@ -0,0 +1,12 @@
+<facility name=s390_kernel>
+  <description>The kernel facility has events related to kernel execution status.</description>
+
+  <event name=trap_entry>
+    <description>Entry in a trap</description>
+    <struct>
+      <field name="trap_id"> <description>Trap number</description> <uint size=8/> </field>
+      <field name="address"> <description>Address where trap occured</description> <pointer/> </field>
+     </struct>
+  </event>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/socket.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/socket.xml
new file mode 100644 (file)
index 0000000..f70761e
--- /dev/null
@@ -0,0 +1,49 @@
+<facility name=socket>
+  <description>The socket facility contains events related to sockets</description>
+
+  <event name=call>
+    <description>Generic socket call : FIXME : should be more detailed.</description>
+    <struct>
+      <field name="call_number"> <description>Number of socket call</description> <int size=4/> </field>
+      <field name="first_argument"> <description>First argument of socket call</description> <ulong/> </field>
+    </struct>
+  </event>
+
+  <event name=create>
+    <description>Create a socket</description>
+    <struct>
+      <field name="socket"> <description>Socket structure address</description> <pointer/> </field>
+      <field name="family"> <description>Socket family</description> <int size=4/> </field>
+      <field name="type"> <description>Socket type</description> <int size=4/> </field>
+      <field name="protocol"> <description>Socket protocol</description> <int size=4/> </field>
+      <field name="fd"> <description>Socket file descriptor</description> <int size=4/> </field>
+    </struct>
+  </event>
+
+  <event name=sendmsg>
+    <description>Sending a socket message</description>
+    <struct>
+      <field name="socket"> <description>Socket structure address</description> <pointer/> </field>
+      <field name="family"> <description>Socket family</description> <int size=4/> </field>
+      <field name="type"> <description>Socket type</description> <int size=4/> </field>
+      <field name="protocol"> <description>Socket protocol</description> <int size=4/> </field>
+      <field name="size"> <description>Size of the message</description> <size_t/> </field>
+    </struct>
+  </event>
+
+  <event name=recvmsg>
+    <description>Receiving a socket message</description>
+    <struct>
+      <field name="socket"> <description>Socket structure address</description> <pointer/> </field>
+      <field name="family"> <description>Socket family</description> <int size=4/> </field>
+      <field name="type"> <description>Socket type</description> <int size=4/> </field>
+      <field name="protocol"> <description>Socket protocol</description> <int size=4/> </field>
+      <field name="size"> <description>Size of the message</description> <size_t/> </field>
+    </struct>
+  </event>
+
+
+
+
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/timer.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/facilities/timer.xml
new file mode 100644 (file)
index 0000000..a6e4ec9
--- /dev/null
@@ -0,0 +1,41 @@
+<facility name=timer>
+  <description>The timer facility has events related to timer events in the kernel.</description>
+
+  <event name=expired>
+    <description>A timer or itimer has expired.</description>
+     <struct>
+      <field name="pid"> <description>PID of the process to wake up.</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=softirq>
+    <description>The timer softirq is currently runned.</description>
+  </event>
+
+  <event name=set_itimer>
+    <description>An interval timer is set.</description>
+     <struct>
+      <field name="which"> <description>kind of interval timer.</description>
+                       <typeref name=itimer_kind/></field>
+     <field name="interval_seconds"><uint size=4/></field>
+      <field name="interval_microseconds"><uint size=4/></field>
+      <field name="value_seconds"><uint size=4/></field>
+      <field name="value_microseconds"><uint size=4/></field>
+     </struct>
+  </event>
+
+  <type name=itimer_kind>
+    <enum size=4>
+      <label name=ITIMER_REAL value=0/> <description>decrements in real time,
+      and delivers SIGALRM upon expiration.</description>
+      <label name=ITIMER_VIRTUAL value=1/> <description>decrements only when the
+      process is executing, and delivers SIGVTALRM upon expiration.</description>
+      <label name=ITIMER_PROF value=2/> <description>decrements both when the
+      process executes and when the system is executing on behalf of the
+      process. Coupled with ITIMER_VIRTUAL, this timer is usually used to
+      profile the time spent by the application in user and kernel space.
+      SIGPROF is delivered upon expiration.</description>
+    </enum>
+  </type>
+
+</facility>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/Makefile.am
new file mode 100644 (file)
index 0000000..1c650f0
--- /dev/null
@@ -0,0 +1,7 @@
+
+
+lib_LTLIBRARIES = liblttctl.la
+liblttctl_la_SOURCES = liblttctl.c
+
+lttctlinclude_HEADERS = \
+       lttctl.h
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/liblttctl.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/liblttctl.c
new file mode 100644 (file)
index 0000000..d6f411b
--- /dev/null
@@ -0,0 +1,483 @@
+/* libltt
+ *
+ * Linux Trace Toolkit Netlink Control Library
+ *
+ * Controls the ltt-control kernel module through a netlink socket.
+ *
+ * Heavily inspired from libipq.c (iptables) made by 
+ * James Morris <jmorris@intercode.com.au>
+ *
+ * Copyright 2005 -
+ *     Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *     
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <liblttctl/lttctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <error.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+
+
+
+/* Private interface */
+
+enum {
+       LTTCTL_ERR_NONE = 0,
+       LTTCTL_ERR_IMPL,
+       LTTCTL_ERR_HANDLE,
+       LTTCTL_ERR_SOCKET,
+       LTTCTL_ERR_BIND,
+       LTTCTL_ERR_BUFFER,
+       LTTCTL_ERR_RECV,
+       LTTCTL_ERR_NLEOF,
+       LTTCTL_ERR_ADDRLEN,
+       LTTCTL_ERR_STRUNC,
+       LTTCTL_ERR_RTRUNC,
+       LTTCTL_ERR_NLRECV,
+       LTTCTL_ERR_SEND,
+       LTTCTL_ERR_SUPP,
+       LTTCTL_ERR_RECVBUF,
+       LTTCTL_ERR_TIMEOUT,
+        LTTCTL_ERR_PROTOCOL
+};
+#define LTTCTL_MAXERR LTTCTL_ERR_PROTOCOL
+
+
+struct lttctl_errmap_t {
+       int errcode;
+       char *message;
+} lttctl_errmap[] = {
+       { LTTCTL_ERR_NONE, "Unknown error" },
+       { LTTCTL_ERR_IMPL, "Implementation error" },
+       { LTTCTL_ERR_HANDLE, "Unable to create netlink handle" },
+       { LTTCTL_ERR_SOCKET, "Unable to create netlink socket" },
+       { LTTCTL_ERR_BIND, "Unable to bind netlink socket" },
+       { LTTCTL_ERR_BUFFER, "Unable to allocate buffer" },
+       { LTTCTL_ERR_RECV, "Failed to receive netlink message" },
+       { LTTCTL_ERR_NLEOF, "Received EOF on netlink socket" },
+       { LTTCTL_ERR_ADDRLEN, "Invalid peer address length" },
+       { LTTCTL_ERR_STRUNC, "Sent message truncated" },
+       { LTTCTL_ERR_RTRUNC, "Received message truncated" },
+       { LTTCTL_ERR_NLRECV, "Received error from netlink" },
+       { LTTCTL_ERR_SEND, "Failed to send netlink message" },
+       { LTTCTL_ERR_SUPP, "Operation not supported" },
+       { LTTCTL_ERR_RECVBUF, "Receive buffer size invalid" },
+       { LTTCTL_ERR_TIMEOUT, "Timeout"},
+       { LTTCTL_ERR_PROTOCOL, "Invalid protocol specified" }
+};
+
+static int lttctl_errno = LTTCTL_ERR_NONE;
+
+
+static ssize_t lttctl_netlink_sendto(const struct lttctl_handle *h,
+                                  const void *msg, size_t len);
+
+static ssize_t lttctl_netlink_recvfrom(const struct lttctl_handle *h,
+                                    unsigned char *buf, size_t len,
+                                    int timeout);
+
+static ssize_t lttctl_netlink_sendmsg(const struct lttctl_handle *h,
+                                   const struct msghdr *msg,
+                                   unsigned int flags);
+
+static char *lttctl_strerror(int errcode);
+
+void lttctl_perror(const char *s);
+
+static ssize_t lttctl_netlink_sendto(const struct lttctl_handle *h,
+                                  const void *msg, size_t len)
+{
+       int status = sendto(h->fd, msg, len, 0,
+                           (struct sockaddr *)&h->peer, sizeof(h->peer));
+       if (status < 0)
+               lttctl_errno = LTTCTL_ERR_SEND;
+       
+       return status;
+}
+
+static ssize_t lttctl_netlink_sendmsg(const struct lttctl_handle *h,
+                                   const struct msghdr *msg,
+                                   unsigned int flags)
+{
+       int status = sendmsg(h->fd, msg, flags);
+       if (status < 0)
+               lttctl_errno = LTTCTL_ERR_SEND;
+       return status;
+}
+
+static ssize_t lttctl_netlink_recvfrom(const struct lttctl_handle *h,
+                                    unsigned char *buf, size_t len,
+                                    int timeout)
+{
+       int addrlen, status;
+       struct nlmsghdr *nlh;
+
+       if (len < sizeof(struct nlmsghdr)) {
+               lttctl_errno = LTTCTL_ERR_RECVBUF;
+               lttctl_perror("Netlink recvfrom");
+               return -1;
+       }
+       addrlen = sizeof(h->peer);
+
+       if (timeout != 0) {
+               int ret;
+               struct timeval tv;
+               fd_set read_fds;
+               
+               if (timeout < 0) {
+                       /* non-block non-timeout */
+                       tv.tv_sec = 0;
+                       tv.tv_usec = 0;
+               } else {
+                       tv.tv_sec = timeout / 1000000;
+                       tv.tv_usec = timeout % 1000000;
+               }
+
+               FD_ZERO(&read_fds);
+               FD_SET(h->fd, &read_fds);
+               ret = select(h->fd+1, &read_fds, NULL, NULL, &tv);
+               if (ret < 0) {
+                       if (errno == EINTR) {
+                               printf("eintr\n");
+                               return 0;
+                       } else {
+                               lttctl_errno = LTTCTL_ERR_RECV;
+                               lttctl_perror("Netlink recvfrom");
+                               return -1;
+                       }
+               }
+               if (!FD_ISSET(h->fd, &read_fds)) {
+                       lttctl_errno = LTTCTL_ERR_TIMEOUT;
+                       printf("timeout\n");
+                       return 0;
+               }
+       }
+       status = recvfrom(h->fd, buf, len, 0,
+                             (struct sockaddr *)&h->peer, &addrlen);
+       
+       if (status < 0) {
+               lttctl_errno = LTTCTL_ERR_RECV;
+               lttctl_perror("Netlink recvfrom");
+               return status;
+       }
+       if (addrlen != sizeof(h->peer)) {
+               lttctl_errno = LTTCTL_ERR_RECV;
+               lttctl_perror("Netlink recvfrom");
+               return -1;
+       }
+       if (h->peer.nl_pid != 0) {
+               lttctl_errno = LTTCTL_ERR_RECV;
+               lttctl_perror("Netlink recvfrom");
+               return -1;
+       }
+       if (status == 0) {
+               lttctl_errno = LTTCTL_ERR_NLEOF;
+               lttctl_perror("Netlink recvfrom");
+               return -1;
+       }
+       nlh = (struct nlmsghdr *)buf;
+       if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status) {
+               lttctl_errno = LTTCTL_ERR_RTRUNC;
+               lttctl_perror("Netlink recvfrom");
+               return -1;
+       }
+       
+
+       return status;
+}
+
+
+static char *lttctl_strerror(int errcode)
+{
+       if (errcode < 0 || errcode > LTTCTL_MAXERR)
+               errcode = LTTCTL_ERR_IMPL;
+       return lttctl_errmap[errcode].message;
+}
+
+
+char *lttctl_errstr(void)
+{
+       return lttctl_strerror(lttctl_errno);
+}
+
+void lttctl_perror(const char *s)
+{
+       if (s)
+               fputs(s, stderr);
+       else
+               fputs("ERROR", stderr);
+       if (lttctl_errno)
+               fprintf(stderr, ": %s", lttctl_errstr());
+       if (errno)
+               fprintf(stderr, ": %s", strerror(errno));
+       fputc('\n', stderr);
+}
+
+/* public interface */
+
+/*
+ * Create and initialise an lttctl handle.
+ */
+struct lttctl_handle *lttctl_create_handle(void)
+{
+       int status;
+       struct lttctl_handle *h;
+
+       h = (struct lttctl_handle *)malloc(sizeof(struct lttctl_handle));
+       if (h == NULL) {
+               lttctl_errno = LTTCTL_ERR_HANDLE;
+               lttctl_perror("Create handle");
+               goto alloc_error;
+       }
+       
+       memset(h, 0, sizeof(struct lttctl_handle));
+       
+  h->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_LTT);
+        
+       if (h->fd == -1) {
+               lttctl_errno = LTTCTL_ERR_SOCKET;
+               lttctl_perror("Create handle");
+               goto socket_error;
+       }
+       memset(&h->local, 0, sizeof(struct sockaddr_nl));
+       h->local.nl_family = AF_NETLINK;
+       h->local.nl_pid = getpid();
+       h->local.nl_groups = 0;
+       status = bind(h->fd, (struct sockaddr *)&h->local, sizeof(h->local));
+       if (status == -1) {
+               lttctl_errno = LTTCTL_ERR_BIND;
+               lttctl_perror("Create handle");
+               goto bind_error;
+       }
+       memset(&h->peer, 0, sizeof(struct sockaddr_nl));
+       h->peer.nl_family = AF_NETLINK;
+       h->peer.nl_pid = 0;
+       h->peer.nl_groups = 0;
+       return h;
+       
+       /* Error condition */
+bind_error:
+socket_error:
+               close(h->fd);
+alloc_error:
+               free(h);
+       return NULL;
+}
+
+/*
+ * No error condition is checked here at this stage, but it may happen
+ * if/when reliable messaging is implemented.
+ */
+int lttctl_destroy_handle(struct lttctl_handle *h)
+{
+       if (h) {
+               close(h->fd);
+               free(h);
+       }
+       return 0;
+}
+
+
+int lttctl_create_trace(const struct lttctl_handle *h,
+               char *name, enum trace_mode mode, unsigned subbuf_size, unsigned n_subbufs)
+{
+       int err;
+       
+       struct {
+               struct nlmsghdr nlh;
+               lttctl_peer_msg_t       msg;
+       } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+
+       memset(&req, 0, sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
+       req.nlh.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
+       req.nlh.nlmsg_type = LTTCTLM_CONTROL;
+       req.nlh.nlmsg_pid = h->local.nl_pid;
+       req.nlh.nlmsg_seq = 0;
+
+       strncpy(req.msg.trace_name, name, NAME_MAX);
+       req.msg.op = OP_CREATE;
+       req.msg.args.new_trace.mode = mode;
+       req.msg.args.new_trace.subbuf_size = subbuf_size;
+       req.msg.args.new_trace.n_subbufs = n_subbufs;
+
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Create Trace Error");
+               return err;
+       }
+
+       return 0;
+
+senderr:
+       lttctl_perror("Create Trace Error");
+  err = EPERM;
+       return err;
+}
+
+int lttctl_destroy_trace(const struct lttctl_handle *h,
+               char *name)
+{
+       struct {
+               struct nlmsghdr nlh;
+               lttctl_peer_msg_t       msg;
+       } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+       int err;
+
+       memset(&req, 0, sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
+       req.nlh.nlmsg_flags = NLM_F_REQUEST;
+       req.nlh.nlmsg_type = LTTCTLM_CONTROL;
+       req.nlh.nlmsg_pid = h->local.nl_pid;
+
+       strncpy(req.msg.trace_name, name, NAME_MAX);
+       req.msg.op = OP_DESTROY;
+
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Destroy Trace Channels Error");
+               return err;
+       }
+
+       return 0;
+
+senderr:
+       lttctl_perror("Destroy Trace Channels Error");
+  err = EPERM;
+       return err;
+
+}
+
+int lttctl_start(const struct lttctl_handle *h,
+               char *name)
+{
+       struct {
+               struct nlmsghdr nlh;
+               lttctl_peer_msg_t       msg;
+       } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+
+       int err;
+
+       memset(&req, 0, sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
+       req.nlh.nlmsg_flags = NLM_F_REQUEST;
+       req.nlh.nlmsg_type = LTTCTLM_CONTROL;
+       req.nlh.nlmsg_pid = h->local.nl_pid;
+
+       strncpy(req.msg.trace_name, name, NAME_MAX);
+       req.msg.op = OP_START;
+
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Start Trace Error");
+               return err;
+       }
+
+       return 0;
+
+senderr:
+  err = EPERM;
+       lttctl_perror("Start Trace Error");
+       return err;
+
+}
+
+int lttctl_stop(const struct lttctl_handle *h,
+               char *name)
+{
+       struct {
+               struct nlmsghdr nlh;
+               lttctl_peer_msg_t       msg;
+       } req;
+       struct {
+               struct nlmsghdr nlh;
+               struct nlmsgerr nlerr;
+               lttctl_peer_msg_t       msg;
+       } ack;
+       int err;
+
+       memset(&req, 0, sizeof(req));
+       req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(lttctl_peer_msg_t));
+       req.nlh.nlmsg_flags = NLM_F_REQUEST;
+       req.nlh.nlmsg_type = LTTCTLM_CONTROL;
+       req.nlh.nlmsg_pid = h->local.nl_pid;
+
+       strncpy(req.msg.trace_name, name, NAME_MAX);
+       req.msg.op = OP_STOP;
+
+       err = lttctl_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
+       if(err < 0) goto senderr;
+
+       err = lttctl_netlink_recvfrom(h, (void*)&ack, sizeof(ack), 0);
+       if(err < 0) goto senderr;
+
+       err = ack.nlerr.error;
+       if(err != 0) {
+               errno = err;
+               lttctl_perror("Stop Trace Error");
+               return err;
+       }
+
+       return 0;
+
+senderr:
+  err = EPERM;
+       lttctl_perror("Stop Trace Error");
+       return err;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/lttctl.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/liblttctl/lttctl.h
new file mode 100644 (file)
index 0000000..80cebba
--- /dev/null
@@ -0,0 +1,91 @@
+/* libltt header file
+ *
+ * Copyright 2005-
+ *     Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Inspired from iptables, by James Morris <jmorris@intercode.com.au>.
+ * 
+ */
+
+#ifndef _LIBLTT_H
+#define _LIBLTT_H
+
+#include <linux/limits.h>
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#ifndef NETLINK_LTT
+#define NETLINK_LTT 12
+#endif
+
+
+enum trace_op {
+       OP_CREATE,
+       OP_DESTROY,
+       OP_START,
+       OP_STOP,
+       OP_NONE
+};
+
+enum trace_mode {
+       LTT_TRACE_NORMAL,
+       LTT_TRACE_FLIGHT
+};
+
+typedef struct lttctl_peer_msg {
+       char trace_name[NAME_MAX];
+       enum trace_op op;
+       union {
+    struct {
+      enum trace_mode mode;
+      unsigned subbuf_size;
+      unsigned n_subbufs;
+    } new_trace;
+       } args;
+} lttctl_peer_msg_t;
+
+
+struct lttctl_handle
+{
+  int fd;
+  //u_int8_t blocking;
+  struct sockaddr_nl local;
+  struct sockaddr_nl peer;
+};
+
+typedef struct lttctl_resp_msg {
+       int err;
+} lttctl_resp_msg_t;
+
+struct lttctl_handle *lttctl_create_handle(void);
+
+int lttctl_destroy_handle(struct lttctl_handle *h);
+
+
+int lttctl_create_trace(const struct lttctl_handle *h,
+               char *name, enum trace_mode mode, unsigned subbuf_size, unsigned n_subbufs);
+
+int lttctl_destroy_trace(const struct lttctl_handle *handle, char *name);
+
+int lttctl_start(const struct lttctl_handle *handle, char *name);
+
+int lttctl_stop(const struct lttctl_handle *handle, char *name);
+
+#define LTTCTLM_BASE   0x10
+#define LTTCTLM_CONTROL        (LTTCTLM_BASE + 1)      /* LTT control message */
+
+
+#endif //_LIBLTT_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/Makefile.am
new file mode 100644 (file)
index 0000000..e6d6aa1
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+#libdir = ${lttlibdir}
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+LIBS += $(GLIB_LIBS)
+
+lib_LTLIBRARIES = liblttvtraceread.la
+liblttvtraceread_la_SOURCES = event.c facility.c parser.c tracefile.c type.c
+noinst_HEADERS = parser.h ltt-private.h
+
+lttinclude_HEADERS = \
+  compiler.h\
+       event.h\
+       facility.h\
+       ltt.h\
+       time.h\
+       trace.h\
+       type.h\
+       ltt-types.h
+
+EXTRA_DIST = crc32.tab
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/compiler.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/compiler.h
new file mode 100644 (file)
index 0000000..1ab188f
--- /dev/null
@@ -0,0 +1,52 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+/* Fast prediction if likely branches */
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
+/*
+ * Check at compile time that something is of a particular type.
+ * Always evaluates to 1 so you may use it easily in comparisons.
+ */
+#define typecheck(type,x) \
+({  type __dummy; \
+  typeof(x) __dummy2; \
+  (void)(&__dummy == &__dummy2); \
+  1; \
+})
+
+/* Deal with 32 wrap correctly */
+#define guint32_after(a,b) \
+  (typecheck(guint32, a) && \
+   typecheck(guint32, b) && \
+   ((gint32)(b) - (gint32)(a) < 0))
+#define guint32_before(a,b)  guint32_after(b,a)
+
+#define guint32_after_eq(a,b) \
+  (typecheck(guint32, a) && \
+   typecheck(guint32, b) && \
+   ((gint32)(b) - (gint32)(a) <= 0))
+#define guint32_before_eq(a,b)  guint32_after_eq(b,a)
+
+
+#endif //COMPILER_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/LTTTypes.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/LTTTypes.h
new file mode 100644 (file)
index 0000000..e493f84
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * LTTTypes.h
+ *
+ * Copyright (C) 2000 Karim Yaghmour (karym@opersys.com).
+ *
+ * This is distributed under GPL.
+ *
+ * Header for LTT-secific types.
+ *
+ * History : 
+ *    K.Y.  07/09/2001, Added David Schleef's architecture independent ltt_set_bit/ltt_clear_bit/ltt_test_bit
+ *    JAL,  05/01/2001, Modified PPC bit manipulation functions for x86 compatibility.
+ *                      (andy_lowe@mvista.com)
+ *    K.Y., 31/05/2000, Initial typing.
+ */
+
+#ifndef __TRACE_TOOLKIT_TYPES_HEADER__
+#define __TRACE_TOOLKIT_TYPES_HEADER__
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#if defined(sun)
+
+typedef unsigned char          u_int8_t;
+typedef unsigned short         u_int16_t;
+typedef unsigned int           u_int32_t;
+#ifdef _LP64
+typedef unsigned long          u_int64_t;
+#else  /* _ILP32 */
+#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)
+typedef unsigned long long     u_int64_t;
+#endif /* __STDC__ - 0 == 0 && !defined(_NO_LONGLONG) */
+#endif /* _LP64 */
+
+#endif /* defined(sun) */
+
+extern __inline__ int ltt_set_bit(int nr, void * addr)
+{
+  unsigned char *p = addr;
+  unsigned char mask = 1 << (nr&7);
+  unsigned char old;
+
+  p += nr>>3;
+  old = *p;
+  *p |= mask;
+  return ((old & mask) != 0);
+}
+
+extern __inline__ int ltt_clear_bit(int nr, void * addr)
+{
+  unsigned char *p = addr;
+  unsigned char mask = 1 << (nr&7);
+  unsigned char old;
+
+  p += nr>>3;
+  old = *p;
+  *p &= ~mask;
+  return ((old & mask) != 0);
+}
+
+extern __inline__ int ltt_test_bit(int nr,void *addr)
+{
+  unsigned char *p = addr;
+  unsigned char mask = 1 << (nr&7);
+  p += nr>>3;
+  return ((*p & mask) != 0);
+}
+
+/* Big-endian/little-endian conversion macros for cross-development. */
+#if TARGET_NATIVE
+/* For native development, these conversion macros aren't needed. */
+#define BREV16(x)   (x)
+#define BREV32(x)   (x)
+#define BREV64(x)   (x)
+#define RFT8(db,x)  (x)
+#define RFT16(db,x) (x)
+#define RFT32(db,x) (x)
+#define RFT64(db,x) (x)
+
+/* Non-native development */
+#else
+        /* BREV16: byte-reverse a 16-bit integer */
+#define BREV16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
+       /* BREV32: byte-reverse a 32-bit integer */
+#define BREV32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
+                | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+       /* BREV64: byte-reverse a 64-bit integer */
+#define BREV64(x) ((((x) & 0xff00000000000000) >> 56) \
+                 | (((x) & 0x00ff000000000000) >> 40) \
+                | (((x) & 0x0000ff0000000000) >> 24) \
+                | (((x) & 0x000000ff00000000) >>  8) \
+                | (((x) & 0x00000000ff000000) <<  8) \
+                | (((x) & 0x0000000000ff0000) << 24) \
+                | (((x) & 0x000000000000ff00) << 40) \
+                | (((x) & 0x00000000000000ff) << 56))
+       /* RFTn: Read From Trace
+        *      Conditionally byte-reverse an 8-, 16-, 32-, or 64-bit integer
+        *      based on the value of the ByteRev member of the trace database
+        *      structure pointer passed as the first argument..
+        */
+#define RFT8(db,x)  (x)
+#define RFT16(db,x) ((db)->ByteRev ? BREV16(x) : (x))
+#define RFT32(db,x) ((db)->ByteRev ? BREV32(x) : (x))
+#define RFT64(db,x) ((db)->ByteRev ? BREV64(x) : (x))
+#endif /* TRACE_TARGET_NATIVE */
+
+#if !defined(sun)
+/* Some type corrections, just in case */
+#ifndef uint8_t
+#define uint8_t u_int8_t
+#endif
+#ifndef uint16_t
+#define uint16_t u_int16_t
+#endif
+#ifndef uint32_t
+#define uint32_t u_int32_t
+#endif
+#ifndef uint64_t
+#define uint64_t u_int64_t
+#endif
+#endif /* !defined(sun) */
+
+/* Structure packing */
+#if LTT_UNPACKED_STRUCTS
+#define LTT_PACKED_STRUCT
+#else
+#define LTT_PACKED_STRUCT __attribute__ ((packed))
+#endif /* UNPACKED_STRUCTS */
+
+/* Trace mask */
+typedef uint64_t trace_event_mask;
+
+/* Boolean stuff */
+//#define TRUE  1
+//#define FALSE 0
+
+#endif /* __TRACE_TOOLKIT_TYPES_HEADER__ */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/LinuxEvents.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/LinuxEvents.h
new file mode 100644 (file)
index 0000000..dfd0840
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * LinuxEvents.h
+ *
+ * Copyright (C) 2000, 2001, 2002 Karim Yaghmour (karym@opersys.com).
+ *
+ * This header is distributed under GPL.
+ *
+ * Linux events being traced.
+ *
+ * History : 
+ *    K.Y., 31/05/1999, Initial typing.
+ *
+ */
+
+#ifndef __TRACE_TOOLKIT_LINUX_HEADER__
+#define __TRACE_TOOLKIT_LINUX_HEADER__
+
+#include "LTTTypes.h"
+
+/* Traced events */
+#define TRACE_START           0    /* This is to mark the trace's start */
+#define TRACE_SYSCALL_ENTRY   1    /* Entry in a given system call */
+#define TRACE_SYSCALL_EXIT    2    /* Exit from a given system call */
+#define TRACE_TRAP_ENTRY      3    /* Entry in a trap */
+#define TRACE_TRAP_EXIT       4    /* Exit from a trap */
+#define TRACE_IRQ_ENTRY       5    /* Entry in an irq */
+#define TRACE_IRQ_EXIT        6    /* Exit from an irq */
+#define TRACE_SCHEDCHANGE     7    /* Scheduling change */
+#define TRACE_KERNEL_TIMER    8    /* The kernel timer routine has been called */
+#define TRACE_SOFT_IRQ        9    /* Hit key part of soft-irq management */
+#define TRACE_PROCESS        10    /* Hit key part of process management */
+#define TRACE_FILE_SYSTEM    11    /* Hit key part of file system */
+#define TRACE_TIMER          12    /* Hit key part of timer management */
+#define TRACE_MEMORY         13    /* Hit key part of memory management */
+#define TRACE_SOCKET         14    /* Hit key part of socket communication */
+#define TRACE_IPC            15    /* Hit key part of inter-process communication */
+#define TRACE_NETWORK        16    /* Hit key part of network communication */
+
+#define TRACE_BUFFER_START   17    /* Mark the begining of a trace buffer */
+#define TRACE_BUFFER_END     18    /* Mark the ending of a trace buffer */
+#define TRACE_NEW_EVENT      19    /* New event type */
+#define TRACE_CUSTOM         20    /* Custom event */
+
+#define TRACE_CHANGE_MASK    21    /* Change in event mask */
+#define TRACE_HEARTBEAT      22    /* Heartbeat event */
+
+/* Number of traced events */
+#define TRACE_MAX            TRACE_HEARTBEAT
+
+/* Architecture types */
+#define TRACE_ARCH_TYPE_I386                1   /* i386 system */
+#define TRACE_ARCH_TYPE_PPC                 2   /* PPC system */
+#define TRACE_ARCH_TYPE_SH                  3   /* SH system */
+#define TRACE_ARCH_TYPE_S390                4   /* S/390 system */
+#define TRACE_ARCH_TYPE_MIPS                5   /* MIPS system */
+#define TRACE_ARCH_TYPE_ARM                 6   /* ARM system */
+
+/* Standard definitions for variants */
+#define TRACE_ARCH_VARIANT_NONE             0   /* Main architecture implementation */
+
+/* PowerPC variants */
+#define TRACE_ARCH_VARIANT_PPC_4xx          1   /* 4xx systems (IBM embedded series) */
+#define TRACE_ARCH_VARIANT_PPC_6xx          2   /* 6xx/7xx/74xx/8260/POWER3 systems (desktop flavor) */
+#define TRACE_ARCH_VARIANT_PPC_8xx          3   /* 8xx system (Motoral embedded series) */
+#define TRACE_ARCH_VARIANT_PPC_ISERIES      4   /* 8xx system (iSeries) */
+
+/* System types */
+#define TRACE_SYS_TYPE_VANILLA_LINUX        1   /* Vanilla linux kernel  */
+#define TRACE_SYS_TYPE_RTAI_LINUX           2   /* RTAI patched linux kernel */
+
+/* The information logged when the tracing is started */
+#define TRACER_MAGIC_NUMBER        0x00D6B7ED     /* That day marks an important historical event ... */
+#define TRACER_SUP_VERSION_MAJOR            2     /* Major version number */
+
+/* Minimum information contained in any trace start event */
+typedef struct _trace_start_any
+{
+  uint32_t           MagicNumber;      /* Magic number to identify a trace */
+  uint32_t           ArchType;         /* Type of architecture */
+  uint32_t           ArchVariant;      /* Variant of the given type of architecture */
+  uint32_t           SystemType;       /* Operating system type */
+  uint8_t            MajorVersion;     /* Major version of trace */
+  uint8_t            MinorVersion;     /* Minor version of trace */
+
+} LTT_PACKED_STRUCT trace_start_any;
+
+typedef struct _trace_start_2_2
+{
+  uint32_t           MagicNumber;      /* Magic number to identify a trace */
+  uint32_t           ArchType;         /* Type of architecture */
+  uint32_t           ArchVariant;      /* Variant of the given type of architecture */
+  uint32_t           SystemType;       /* Operating system type */
+  uint8_t            MajorVersion;     /* Major version of trace */
+  uint8_t            MinorVersion;     /* Minor version of trace */
+
+  uint32_t           BufferSize;       /* Size of buffers */
+  trace_event_mask   EventMask;        /* The event mask */
+  trace_event_mask   DetailsMask;      /* Are the event details logged */
+  uint8_t            LogCPUID;         /* Is the CPUID logged */
+  uint8_t            UseTSC;            /* Are we using TSCs or time deltas */
+
+} LTT_PACKED_STRUCT trace_start_2_2;
+
+typedef struct _trace_start_2_3
+{
+  uint32_t           MagicNumber;      /* Magic number to identify a trace */
+  uint32_t           ArchType;         /* Type of architecture */
+  uint32_t           ArchVariant;      /* Variant of the given type of architecture */
+  uint32_t           SystemType;       /* Operating system type */
+  uint8_t            MajorVersion;     /* Major version of trace */
+  uint8_t            MinorVersion;     /* Minor version of trace */
+
+  uint32_t           BufferSize;       /* Size of buffers */
+  trace_event_mask   EventMask;        /* The event mask */
+  trace_event_mask   DetailsMask;      /* Are the event details logged */
+  uint8_t            LogCPUID;         /* Is the CPUID logged */
+  uint8_t            UseTSC;            /* Are we using TSCs or time deltas */
+  
+  uint8_t            FlightRecorder;   /* Is this a flight recorder trace ? */
+} LTT_PACKED_STRUCT trace_start_2_3;
+
+/*  TRACE_SYSCALL_ENTRY */
+typedef struct _trace_syscall_entry
+{
+  uint8_t   syscall_id;   /* Syscall entry number in entry.S */
+  uint32_t  address;      /* Address from which call was made */
+} LTT_PACKED_STRUCT trace_syscall_entry;
+#define SYSCALL_EVENT(X) ((trace_syscall_entry*)X)
+
+/*  TRACE_TRAP_ENTRY */
+typedef struct _trace_trap_entry
+{
+  uint16_t  trap_id;     /* Trap number */
+  uint32_t  address;     /* Address where trap occured */
+} LTT_PACKED_STRUCT trace_trap_entry;
+typedef struct _trace_trap_entry_s390
+{
+  uint64_t  trap_id;     /* Trap number */
+  uint32_t  address;     /* Address where trap occured */
+} LTT_PACKED_STRUCT trace_trap_entry_s390;
+#define TRAP_EVENT(X) ((trace_trap_entry*)X)
+#define TRAP_EVENT_S390(X) ((trace_trap_entry_s390*)X)
+
+/*  TRACE_IRQ_ENTRY */
+typedef struct _trace_irq_entry
+{
+  uint8_t  irq_id;      /* IRQ number */
+  uint8_t  kernel;      /* Are we executing kernel code */
+} LTT_PACKED_STRUCT trace_irq_entry;
+#define IRQ_EVENT(X) ((trace_irq_entry*)X)
+
+/*  TRACE_SCHEDCHANGE */ 
+typedef struct _trace_schedchange
+{
+  uint32_t  out;         /* Outgoing process */
+  uint32_t  in;          /* Incoming process */
+  uint32_t  out_state;   /* Outgoing process' state */
+} LTT_PACKED_STRUCT trace_schedchange;
+#define SCHED_EVENT(X) ((trace_schedchange*)X)
+
+/*  TRACE_SOFT_IRQ */
+#define TRACE_SOFT_IRQ_BOTTOM_HALF        1  /* Conventional bottom-half */
+#define TRACE_SOFT_IRQ_SOFT_IRQ           2  /* Real soft-irq */
+#define TRACE_SOFT_IRQ_TASKLET_ACTION     3  /* Tasklet action */
+#define TRACE_SOFT_IRQ_TASKLET_HI_ACTION  4  /* Tasklet hi-action */
+typedef struct _trace_soft_irq
+{
+  uint8_t   event_sub_id;     /* Soft-irq event Id */
+  uint32_t  event_data;       /* Data associated with event */
+} LTT_PACKED_STRUCT trace_soft_irq;
+#define SOFT_IRQ_EVENT(X) ((trace_soft_irq*)X)
+
+/*  TRACE_PROCESS */
+#define TRACE_PROCESS_KTHREAD     1  /* Creation of a kernel thread */
+#define TRACE_PROCESS_FORK        2  /* A fork or clone occured */
+#define TRACE_PROCESS_EXIT        3  /* An exit occured */
+#define TRACE_PROCESS_WAIT        4  /* A wait occured */
+#define TRACE_PROCESS_SIGNAL      5  /* A signal has been sent */
+#define TRACE_PROCESS_WAKEUP      6  /* Wake up a process */
+#define TRACE_PROCESS_RELEASE     7  /* A task struct has been released */
+
+typedef struct _trace_process
+{
+  uint8_t   event_sub_id;    /* Process event ID */
+  uint32_t  event_data1;     /* Data associated with event */
+  uint32_t  event_data2;    
+} LTT_PACKED_STRUCT trace_process;
+#define PROC_EVENT(X) ((trace_process*)X)
+
+/*  TRACE_FILE_SYSTEM */
+#define TRACE_FILE_SYSTEM_BUF_WAIT_START  1  /* Starting to wait for a data buffer */
+#define TRACE_FILE_SYSTEM_BUF_WAIT_END    2  /* End to wait for a data buffer */
+#define TRACE_FILE_SYSTEM_EXEC            3  /* An exec occured */
+#define TRACE_FILE_SYSTEM_OPEN            4  /* An open occured */
+#define TRACE_FILE_SYSTEM_CLOSE           5  /* A close occured */
+#define TRACE_FILE_SYSTEM_READ            6  /* A read occured */
+#define TRACE_FILE_SYSTEM_WRITE           7  /* A write occured */
+#define TRACE_FILE_SYSTEM_SEEK            8  /* A seek occured */
+#define TRACE_FILE_SYSTEM_IOCTL           9  /* An ioctl occured */
+#define TRACE_FILE_SYSTEM_SELECT         10  /* A select occured */
+#define TRACE_FILE_SYSTEM_POLL           11  /* A poll occured */
+typedef struct _trace_file_system
+{
+  uint8_t   event_sub_id;   /* File system event ID */
+  uint32_t  event_data1;    /* Event data */
+  uint32_t  event_data2;    /* Event data 2 */
+  char*     file_name;      /* Name of file operated on */
+} LTT_PACKED_STRUCT trace_file_system;
+#define FS_EVENT(X) ((trace_file_system*)X)
+#define FS_EVENT_FILENAME(X) ((char*) ((X) + sizeof(trace_file_system)))
+
+/*  TRACE_TIMER */
+#define TRACE_TIMER_EXPIRED      1  /* Timer expired */
+#define TRACE_TIMER_SETITIMER    2  /* Setting itimer occurred */
+#define TRACE_TIMER_SETTIMEOUT   3  /* Setting sched timeout occurred */
+typedef struct _trace_timer
+{
+  uint8_t   event_sub_id;    /* Timer event ID */
+  uint8_t   event_sdata;     /* Short data */
+  uint32_t  event_data1;     /* Data associated with event */
+  uint32_t  event_data2;     
+} LTT_PACKED_STRUCT trace_timer;
+#define TIMER_EVENT(X) ((trace_timer*)X)
+
+/*  TRACE_MEMORY */
+#define TRACE_MEMORY_PAGE_ALLOC        1  /* Allocating pages */
+#define TRACE_MEMORY_PAGE_FREE         2  /* Freing pages */
+#define TRACE_MEMORY_SWAP_IN           3  /* Swaping pages in */
+#define TRACE_MEMORY_SWAP_OUT          4  /* Swaping pages out */
+#define TRACE_MEMORY_PAGE_WAIT_START   5  /* Start to wait for page */
+#define TRACE_MEMORY_PAGE_WAIT_END     6  /* End to wait for page */
+typedef struct _trace_memory
+{
+  uint8_t        event_sub_id;    /* Memory event ID */
+  unsigned long  event_data;      /* Data associated with event */
+} LTT_PACKED_STRUCT trace_memory;
+#define MEM_EVENT(X) ((trace_memory*)X)
+
+/*  TRACE_SOCKET */
+#define TRACE_SOCKET_CALL     1  /* A socket call occured */
+#define TRACE_SOCKET_CREATE   2  /* A socket has been created */
+#define TRACE_SOCKET_SEND     3  /* Data was sent to a socket */
+#define TRACE_SOCKET_RECEIVE  4  /* Data was read from a socket */
+typedef struct _trace_socket
+{
+  uint8_t   event_sub_id;    /* Socket event ID */
+  uint32_t  event_data1;     /* Data associated with event */
+  uint32_t  event_data2;     /* Data associated with event */
+} LTT_PACKED_STRUCT trace_socket;
+#define SOCKET_EVENT(X) ((trace_socket*)X)
+
+/*  TRACE_IPC */
+#define TRACE_IPC_CALL            1  /* A System V IPC call occured */
+#define TRACE_IPC_MSG_CREATE      2  /* A message queue has been created */
+#define TRACE_IPC_SEM_CREATE      3  /* A semaphore was created */
+#define TRACE_IPC_SHM_CREATE      4  /* A shared memory segment has been created */
+typedef struct _trace_ipc
+{
+  uint8_t   event_sub_id;    /* IPC event ID */
+  uint32_t  event_data1;     /* Data associated with event */
+  uint32_t  event_data2;     /* Data associated with event */
+} LTT_PACKED_STRUCT trace_ipc;
+#define IPC_EVENT(X) ((trace_ipc*)X)
+
+/*  TRACE_NETWORK */
+#define TRACE_NETWORK_PACKET_IN   1  /* A packet came in */
+#define TRACE_NETWORK_PACKET_OUT  2  /* A packet was sent */
+typedef struct _trace_network
+{
+  uint8_t  event_sub_id;   /* Network event ID */
+  uint32_t event_data;     /* Event data */
+} LTT_PACKED_STRUCT trace_network;
+#define NET_EVENT(X) ((trace_network*)X)
+
+/* Start of trace buffer information */
+typedef struct _trace_buffer_start
+{
+  struct timeval     Time;    /* Time stamp of this buffer */
+  uint32_t           TSC;     /* TSC of this buffer, if applicable */
+  uint32_t           ID;      /* Unique buffer ID */
+} LTT_PACKED_STRUCT trace_buffer_start;
+
+/* End of trace buffer information */
+typedef struct _trace_buffer_end
+{
+  struct timeval     Time;    /* Time stamp of this buffer */
+  uint32_t           TSC;     /* TSC of this buffer, if applicable */
+} LTT_PACKED_STRUCT trace_buffer_end;
+
+/* Maximal size a custom event can have */
+#define CUSTOM_EVENT_MAX_SIZE        8192
+
+/* String length limits for custom events creation */
+#define CUSTOM_EVENT_TYPE_STR_LEN      20
+#define CUSTOM_EVENT_DESC_STR_LEN     100
+#define CUSTOM_EVENT_FORM_STR_LEN     256
+
+/* Type of custom event formats */
+#define CUSTOM_EVENT_FORMAT_TYPE_NONE   0
+#define CUSTOM_EVENT_FORMAT_TYPE_STR    1
+#define CUSTOM_EVENT_FORMAT_TYPE_HEX    2
+#define CUSTOM_EVENT_FORMAT_TYPE_XML    3
+#define CUSTOM_EVENT_FORMAT_TYPE_IBM    4
+
+typedef struct _trace_new_event
+{
+  /* Basics */
+  uint32_t         id;                                /* Custom event ID */
+  char             type[CUSTOM_EVENT_TYPE_STR_LEN];   /* Event type description */
+  char             desc[CUSTOM_EVENT_DESC_STR_LEN];   /* Detailed event description */
+
+  /* Custom formatting */
+  uint32_t         format_type;                       /* Type of formatting */
+  char             form[CUSTOM_EVENT_FORM_STR_LEN];   /* Data specific to format */
+} LTT_PACKED_STRUCT trace_new_event;
+#define NEW_EVENT(X) ((trace_new_event*) X)
+
+typedef struct _trace_custom
+{
+  uint32_t           id;          /* Event ID */
+  uint32_t           data_size;   /* Size of data recorded by event */
+  void*              data;        /* Data recorded by event */
+} LTT_PACKED_STRUCT trace_custom;
+#define CUSTOM_EVENT(X) ((trace_custom*) X)
+
+/* TRACE_CHANGE_MASK */
+typedef struct _trace_change_mask
+{
+  trace_event_mask          mask;       /* Event mask */
+} LTT_PACKED_STRUCT trace_change_mask;
+#define CHMASK_EVENT(X) ((trace_change_mask*) X)
+
+#endif /* __TRACE_TOOLKIT_LINUX_HEADER__ */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/Makefile.am
new file mode 100644 (file)
index 0000000..6dbec8e
--- /dev/null
@@ -0,0 +1,12 @@
+AM_CFLAGS = $(GLIB_CFLAGS) 
+LIBS += $(GLIB_LIBS) $(M_LIBS)
+
+bin_PROGRAMS = convert
+
+convert_SOURCES = convert.c
+
+noinst_HEADERS = LTTTypes.h LinuxEvents.h
+
+EXTRA_DIST = core.xml sysInfo README
+convertdir = $(pkgdatadir)/convert
+convert_DATA = core.xml sysInfo README
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/README b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/README
new file mode 100644 (file)
index 0000000..e3af7f7
--- /dev/null
@@ -0,0 +1,19 @@
+The application 'convert' is used to convert an old format tracefile into a new 
+format tracefile. It has several commandline parameters, the first is process file 
+name, the second is a number (the number of cpu in the machine), the third is
+the first tracefile name(corresponding to the first cpu), the fourth is the 
+second tracefile name(corresponding to the second cpu), the fifth is ...,   
+the last one is root directory for the new trace (this can be omitted, 
+by default it is 'foo')
+
+The command line looks like this:      
+ ./convert processfile_name the_number_of_cpu first_tracefile_name, ..., foo_dir
+
+There is also a script file 'sysInfo' which is used to get system information
+from your local machine, the information is saved in 'sysInfo.out' which will 
+be read by 'convert' later. If the old tracefile is generated by other machine,
+then the 'sysInfo.out' should be gotten from that machine.
+
+'core.xml' is a facility file, after run 'convert', it needs to be copied to
+'foo_dir/eventdefs' directory
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/convert.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/convert.c
new file mode 100644 (file)
index 0000000..55efb15
--- /dev/null
@@ -0,0 +1,761 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>  
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include "LTTTypes.h"
+#include "LinuxEvents.h"
+
+#define TRACE_HEARTBEAT_ID  19
+#define PROCESS_FORK_ID     20
+#define PROCESS_EXIT_ID     21
+
+#define INFO_ENTRY          9
+#define OVERFLOW_FIGURE     0x100000000ULL
+
+typedef struct _new_process
+{
+  uint32_t  event_data1;     /* Data associated with event */
+  uint32_t  event_data2;    
+} LTT_PACKED_STRUCT new_process;
+
+#define write_to_buffer(DEST, SRC, SIZE) \
+do\
+{\
+   memcpy(DEST, SRC, SIZE);\
+   DEST += SIZE;\
+} while(0);
+
+int readFile(int fd, void * buf, size_t size, char * mesg)
+{
+   ssize_t nbBytes = read(fd, buf, size);
+   
+   if((size_t)nbBytes != size) {
+     if(nbBytes < 0) {
+       perror("Error in readFile : ");
+     } else {
+       printf("%s\n",mesg);
+     }
+     exit(1);
+   }
+   return 0;
+}
+
+void getDataEndianType(char * size, char * endian)
+{
+  int i = 1;
+  char c = (char) i;
+  int sizeInt=sizeof(int), sizeLong=sizeof(long), sizePointer=sizeof(void *);
+
+  if(c == 1) strcpy(endian,"LITTLE_ENDIAN");
+  else strcpy(endian, "BIG_ENDIAN");
+
+  if(sizeInt == 2 && sizeLong == 4 && sizePointer == 4) 
+    strcpy(size,"LP32");
+  else if(sizeInt == 4 && sizeLong == 4 && sizePointer == 4) 
+    strcpy(size,"ILP32");
+  else if(sizeInt == 4 && sizeLong == 8 && sizePointer == 8) 
+    strcpy(size,"LP64");
+  else if(sizeInt == 8 && sizeLong == 8 && sizePointer == 8) 
+    strcpy(size,"ILP64");
+  else strcpy(size,"UNKNOWN");
+}
+
+#define BUFFER_SIZE 80
+
+typedef struct _buffer_start{
+  uint32_t seconds;
+  uint32_t nanoseconds;
+  uint64_t cycle_count;
+  uint32_t block_id;  
+} __attribute__ ((packed)) buffer_start;
+
+typedef struct _buffer_end{
+  uint32_t seconds;
+  uint32_t nanoseconds;
+  uint64_t cycle_count;
+  uint32_t block_id;  
+} __attribute__ ((packed)) buffer_end;
+
+
+typedef struct _heartbeat{
+  uint32_t seconds;
+  uint32_t nanoseconds;
+  uint64_t cycle_count;
+} __attribute__ ((packed)) heartbeat;
+
+
+int main(int argc, char ** argv){
+
+  int fd, fdCpu;
+  FILE * fp;
+  int  fdFac, fdIntr, fdProc;
+  char arch_size[BUFFER_SIZE];
+  char endian[BUFFER_SIZE];
+  char node_name[BUFFER_SIZE];
+  char domainname[BUFFER_SIZE];
+  char kernel_name[BUFFER_SIZE];
+  char kernel_release[BUFFER_SIZE];
+  char kernel_version[BUFFER_SIZE];
+  char machine[BUFFER_SIZE];
+  char processor[BUFFER_SIZE];
+  char hardware_platform[BUFFER_SIZE];
+  char operating_system[BUFFER_SIZE];
+  int  cpu;
+  int  ltt_block_size=0;
+  int  ltt_major_version=0;
+  int  ltt_minor_version=0;
+  int  ltt_log_cpu;
+  guint ltt_trace_start_size = 0;
+  char buf[BUFFER_SIZE];
+  int i, k;
+
+  uint8_t cpu_id;
+
+  char foo[4*BUFFER_SIZE];
+  char foo_eventdefs[4*BUFFER_SIZE];
+  char foo_control[4*BUFFER_SIZE];
+  char foo_cpu[4*BUFFER_SIZE];
+  char foo_info[4*BUFFER_SIZE];
+
+  char foo_control_facilities[4*BUFFER_SIZE];
+  char foo_control_processes[4*BUFFER_SIZE];
+  char foo_control_interrupts[4*BUFFER_SIZE];
+  char foo_info_system[4*BUFFER_SIZE];
+
+  struct stat      lTDFStat;   
+  off_t file_size;                  
+  int block_number, block_size;                 
+  char * buffer, *buf_out, cpuStr[4*BUFFER_SIZE];
+  char * buf_fac, * buf_intr, * buf_proc;
+  void * write_pos, *write_pos_fac, * write_pos_intr, *write_pos_proc;
+  trace_start_any *tStart;
+  trace_buffer_start *tBufStart;
+  trace_buffer_end *tBufEnd;
+  trace_file_system * tFileSys;
+  uint16_t newId, startId, tmpId;
+  uint8_t  evId;
+  uint32_t time_delta, startTimeDelta;
+  void * cur_pos, *end_pos;
+  buffer_start start, start_proc, start_intr;
+  buffer_end end, end_proc, end_intr;
+  heartbeat beat;
+  uint64_t adaptation_tsc;    // (Mathieu)
+  uint32_t size_lost;
+  int nb_para;
+
+  new_process process;
+
+  if(argc < 4){
+    printf("Usage : ./convert processfile_name number_of_cpu tracefile1 tracefile2 ... trace_creation_directory\n");
+               printf("For more details, see README.\n");
+    exit(1);
+  }
+
+  cpu = atoi(argv[2]);
+  printf("cpu number = %d\n", cpu);
+  nb_para = 3 + cpu;
+
+  if(argc != nb_para && argc != nb_para+1){
+    printf("need trace files and cpu number or root directory for the new tracefile\n");
+    exit(1);
+  }
+
+  if(argc == nb_para){
+    strcpy(foo, "foo");
+    strcpy(foo_eventdefs, "foo/eventdefs");
+    strcpy(foo_control, "foo/control");
+    strcpy(foo_cpu, "foo/cpu");
+    strcpy(foo_info, "foo/info");
+  }else{
+    strcpy(foo, argv[nb_para]);
+    strcpy(foo_eventdefs, argv[nb_para]);
+    strcat(foo_eventdefs,"/eventdefs");
+    strcpy(foo_control, argv[nb_para]);
+    strcat(foo_control,"/control");
+    strcpy(foo_cpu, argv[nb_para]);
+    strcat(foo_cpu,"/cpu");
+    strcpy(foo_info, argv[nb_para]);
+    strcat(foo_info,"/info");
+  }
+  strcpy(foo_control_facilities, foo_control);
+  strcat(foo_control_facilities,"/facilities");
+  strcpy(foo_control_processes, foo_control);
+  strcat(foo_control_processes, "/processes");
+  strcpy(foo_control_interrupts, foo_control);
+  strcat(foo_control_interrupts, "/interrupts");
+  strcpy(foo_info_system, foo_info);
+  strcat(foo_info_system, "/system.xml");
+
+
+  getDataEndianType(arch_size, endian);
+  printf("Arch_size: %s,  Endian: %s\n", arch_size, endian);
+
+  fp = fopen("sysInfo.out","r");
+  if(!fp){
+    g_error("Unable to open file sysInfo.out\n");
+  }
+
+  for(i=0;i<INFO_ENTRY;i++){
+    if(!fgets(buf,BUFFER_SIZE-1,fp))
+      g_error("The format of sysInfo.out is not right\n");
+    if(strncmp(buf,"node_name=",10)==0){
+      strcpy(node_name,&buf[10]);
+      node_name[strlen(node_name)-1] = '\0';
+    }else if(strncmp(buf,"domainname=",11)==0){
+      strcpy(domainname,&buf[11]);
+      domainname[strlen(domainname)-1] = '\0';
+    }else if(strncmp(buf,"kernel_name=",12)==0){
+      strcpy(kernel_name,&buf[12]);
+      kernel_name[strlen(kernel_name)-1] = '\0';
+    }else if(strncmp(buf,"kernel_release=",15)==0){
+      strcpy(kernel_release,&buf[15]);
+      kernel_release[strlen(kernel_release)-1] = '\0';
+    }else if(strncmp(buf,"kernel_version=",15)==0){
+      strcpy(kernel_version,&buf[15]);
+      kernel_version[strlen(kernel_version)-1] = '\0';
+    }else if(strncmp(buf,"machine=",8)==0){
+      strcpy(machine,&buf[8]);
+      machine[strlen(machine)-1] = '\0';
+    }else if(strncmp(buf,"processor=",10)==0){
+      strcpy(processor,&buf[10]);
+      processor[strlen(processor)-1] = '\0';
+    }else if(strncmp(buf,"hardware_platform=",18)==0){
+      strcpy(hardware_platform,&buf[18]);
+      hardware_platform[strlen(hardware_platform)-1] = '\0';
+    }else if(strncmp(buf,"operating_system=",17)==0){
+      strcpy(operating_system,&buf[17]);
+      operating_system[strlen(operating_system)-1] = '\0';
+    }
+  }
+  fclose(fp);
+
+  if(mkdir(foo, S_IFDIR | S_IRWXU | S_IRGRP |  S_IROTH)) 
+    g_error("can not make %s directory", foo);
+  if(mkdir(foo_info, S_IFDIR | S_IRWXU | S_IRGRP |  S_IROTH)) 
+    g_error("can not make %s directory", foo_info);
+  if(mkdir(foo_cpu, S_IFDIR | S_IRWXU | S_IRGRP |  S_IROTH)) 
+    g_error("can not make %s directory", foo_cpu);
+  if(mkdir(foo_control, S_IFDIR | S_IRWXU | S_IRGRP |  S_IROTH)) 
+    g_error("can not make %s directory", foo_control);
+  if(mkdir(foo_eventdefs, S_IFDIR | S_IRWXU | S_IRGRP |  S_IROTH)) 
+    g_error("can not make %s directory", foo_eventdefs);
+  
+  fp = fopen(foo_info_system,"w");
+  if(!fp){
+    g_error("Unable to open file system.xml\n");
+  }
+
+  fdFac = open(foo_control_facilities,O_CREAT | O_RDWR | O_TRUNC,S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH);
+  if(fdFac < 0){
+    g_error("Unable to open file facilities\n");
+  }
+  fdIntr = open(foo_control_interrupts,O_CREAT | O_RDWR | O_TRUNC,S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH);
+  if(fdIntr<0){
+    g_error("Unable to open file interrupts\n");
+  }
+  fdProc = open(foo_control_processes,O_CREAT | O_RDWR | O_TRUNC,S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH);
+  if(fdProc<0){
+    g_error("Unable to open file process\n");
+  }
+
+
+  for(k=0;k<cpu;k++){
+    fd = open(argv[nb_para-cpu+k], O_RDONLY, 0);
+    if(fd < 0){
+      g_error("Unable to open input data file %s\n", argv[nb_para-cpu+k]);
+    }
+    
+    if(fstat(fd, &lTDFStat) < 0){
+      g_error("Unable to get the status of the input data file\n");
+    }
+    file_size = lTDFStat.st_size;
+
+    buffer = g_new(char, 4000);
+    readFile(fd,(void*)buffer, 3500, "Unable to read block header");
+    
+    cur_pos= buffer;
+    evId = *(uint8_t *)cur_pos;
+    cur_pos += sizeof(uint8_t);
+    newId = evId;
+    time_delta = *(uint32_t*)cur_pos;
+    cur_pos += sizeof(uint32_t); 
+    tBufStart = (trace_buffer_start*)cur_pos;
+    cur_pos += sizeof(trace_buffer_start);
+    cur_pos += sizeof(uint16_t); //Skip event size
+
+    evId = *(uint8_t *)cur_pos;
+    g_assert(evId == TRACE_START);
+    cur_pos += sizeof(uint8_t); //skip EvId
+    cur_pos += sizeof(uint32_t); //skip time delta
+    tStart = (trace_start_any*)cur_pos;
+    if(tStart->MagicNumber != TRACER_MAGIC_NUMBER)
+      g_error("Trace magic number does not match : %x, should be %x",
+               tStart->MagicNumber, TRACER_MAGIC_NUMBER);
+    if(tStart->MajorVersion != TRACER_SUP_VERSION_MAJOR)
+      g_error("Trace Major number does match : %hu, should be %u",
+               tStart->MajorVersion, TRACER_SUP_VERSION_MAJOR);
+
+    startId = newId;
+    startTimeDelta = time_delta;
+    start.seconds = tBufStart->Time.tv_sec;
+    /* Fix (Mathieu) */
+    start.nanoseconds = tBufStart->Time.tv_usec * 1000;
+    start.cycle_count = tBufStart->TSC;
+    start.block_id = tBufStart->ID;
+    end.block_id = start.block_id;
+
+
+    g_message("Trace version %hu.%hu detected\n",
+             tStart->MajorVersion,
+             tStart->MinorVersion);
+    if(tStart->MinorVersion == 2) {
+      trace_start_2_2* tStart_2_2 = (trace_start_2_2*)tStart;
+      ltt_major_version = tStart_2_2->MajorVersion;
+      ltt_minor_version = tStart_2_2->MinorVersion;
+      ltt_block_size    = tStart_2_2->BufferSize;
+      ltt_log_cpu       = tStart_2_2->LogCPUID;
+      ltt_trace_start_size = sizeof(trace_start_2_2);
+      /* Verify if it's a broken 2.2 format */
+      if(*(uint8_t*)(cur_pos + sizeof(trace_start_2_2)) == 0) {
+        /* Cannot have two trace start events. We cannot detect the problem
+         * if the flight recording flag is set to 1, as it conflicts
+         * with TRACE_SYSCALL_ENTRY.
+         */
+        g_warning("This is a 2.3 trace format that has a 2.2 tag. Please upgrade your kernel");
+        g_message("Processing the trace as a 2.3 format\n");
+
+        tStart->MinorVersion = 3;
+      }
+    }
+    
+    if(tStart->MinorVersion == 3) {
+      trace_start_2_3* tStart_2_3 = (trace_start_2_3*)tStart;
+      ltt_major_version = tStart_2_3->MajorVersion;
+      ltt_minor_version = tStart_2_3->MinorVersion;
+      ltt_block_size    = tStart_2_3->BufferSize;
+      ltt_log_cpu       = tStart_2_3->LogCPUID;
+      ltt_trace_start_size = sizeof(trace_start_2_3);
+    /* We do not use the flight recorder information for now, because we
+     * never use the .proc file anyway */
+    }
+    
+    if(ltt_trace_start_size == 0) 
+      g_error("Minor version unknown : %hu. Supported minors : 2, 3",
+               tStart->MinorVersion);
+
+    block_size = ltt_block_size;//FIXME
+    block_number = file_size/ltt_block_size;
+
+    g_free(buffer);
+    buffer         = g_new(char, ltt_block_size);
+    buf_fac        = g_new(char, block_size);
+    write_pos_fac  = buf_fac;
+    buf_intr       = g_new(char, block_size);
+    write_pos_intr = buf_intr;
+    buf_proc       = g_new(char, block_size);
+    write_pos_proc = buf_proc;
+
+    buf_out = g_new(char, block_size);
+    write_pos = buf_out;
+    sprintf(cpuStr,"%s/%d",foo_cpu,k);
+    fdCpu = open(cpuStr, O_CREAT | O_RDWR | O_TRUNC,S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH); //for cpu k
+    if(fdCpu < 0)  g_error("Unable to open  cpu file %d\n", k);    
+    lseek(fd,0,SEEK_SET);
+    
+    for(i=0;i<block_number;i++){
+      int event_count = 0;
+
+      memset((void*)buf_out, 0, block_size);
+      write_pos = buf_out;
+      memset((void*)buf_intr, 0, block_size);    
+      memset((void*)buf_fac, 0, block_size);    
+      memset((void*)buf_proc, 0, block_size);    
+      write_pos_intr = buf_intr;
+      write_pos_fac = buf_fac;
+      write_pos_proc = buf_proc;
+      
+      memset((void*)buffer,0,ltt_block_size); 
+      readFile(fd,(void*)buffer, ltt_block_size, "Unable to read block header");
+      
+      cur_pos= buffer;
+      evId = *(uint8_t *)cur_pos;
+      cur_pos += sizeof(uint8_t);
+      newId = evId;
+      time_delta = *(uint32_t*)cur_pos;
+      cur_pos += sizeof(uint32_t); 
+      tBufStart = (trace_buffer_start*)cur_pos;
+      cur_pos += sizeof(trace_buffer_start);
+      cur_pos += sizeof(uint16_t); //Skip event size
+
+      startId = newId;
+      startTimeDelta = time_delta;
+      start.seconds = tBufStart->Time.tv_sec;
+      /* usec -> nsec (Mathieu) */
+      start.nanoseconds = tBufStart->Time.tv_usec * 1000;
+      start.block_id = tBufStart->ID;
+      end.block_id = start.block_id;
+      
+      end_pos = buffer + ltt_block_size; //end of the buffer
+      size_lost = *(uint32_t*)(end_pos - sizeof(uint32_t));
+      
+      end_pos = buffer + ltt_block_size - size_lost ; //buffer_end event
+      if(ltt_log_cpu){
+       tBufEnd = (trace_buffer_end*)(end_pos + 2 * sizeof(uint8_t)+sizeof(uint32_t));
+      }else{
+       tBufEnd = (trace_buffer_end*)(end_pos+sizeof(uint8_t)+sizeof(uint32_t));
+      }
+      end.seconds = tBufEnd->Time.tv_sec;
+      /* usec -> nsec (Mathieu) */
+      end.nanoseconds = tBufEnd->Time.tv_usec * 1000;
+      // only 32 bits :( 
+      //end.cycle_count = tBufEnd->TSC;
+    
+      //skip buffer start and trace start events
+      if(i==0) {
+        //the first block
+        adaptation_tsc = (uint64_t)tBufStart->TSC;
+             cur_pos = buffer + sizeof(trace_buffer_start) 
+                         + ltt_trace_start_size 
+                         + 2*(sizeof(uint8_t)
+                         + sizeof(uint16_t)+sizeof(uint32_t));
+      } else {
+        //other blocks
+             cur_pos = buffer + sizeof(trace_buffer_start) 
+                         + sizeof(uint8_t)
+                         + sizeof(uint16_t)+sizeof(uint32_t);
+
+        /* Fix (Mathieu) */
+        if(time_delta < (0xFFFFFFFFULL&adaptation_tsc)) {
+          /* Overflow */
+          adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) 
+                                       + 0x100000000ULL 
+                                       + (uint64_t)time_delta;
+        } else {
+          /* No overflow */
+          adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + time_delta;
+        }
+
+      }
+      start.cycle_count = adaptation_tsc;
+
+      //write start block event
+      write_to_buffer(write_pos,(void*)&startId, sizeof(uint16_t));    
+      write_to_buffer(write_pos,(void*)&startTimeDelta, sizeof(uint32_t));
+      write_to_buffer(write_pos,(void*)&start, sizeof(buffer_start));
+      
+      //write start block event into processes and interrupts files
+      write_to_buffer(write_pos_intr,(void*)&startId, sizeof(uint16_t));    
+      write_to_buffer(write_pos_intr,(void*)&startTimeDelta, sizeof(uint32_t));
+      start_intr = start;
+      start_intr.nanoseconds -= 20;
+      write_to_buffer(write_pos_intr,(void*)&start_intr, sizeof(buffer_start));
+
+      write_to_buffer(write_pos_proc,(void*)&startId, sizeof(uint16_t));    
+      write_to_buffer(write_pos_proc,(void*)&startTimeDelta, sizeof(uint32_t));
+      start_proc = start;
+      start_proc.nanoseconds -= 40;
+      write_to_buffer(write_pos_proc,(void*)&start_proc, sizeof(buffer_start));
+      
+      //parse *.proc file to get process and irq info
+      if(i == 0){
+       int        lIntID;                 /* Interrupt ID */
+       int        lPID, lPPID;            /* Process PID and Parent PID */
+       char       lName[256];             /* Process name */
+       FILE *          fProc;
+       uint16_t        defaultId;
+       trace_irq_entry irq;
+       
+       fProc = fopen(argv[1],"r");
+       if(!fProc){
+         g_error("Unable to open file %s\n", argv[1]);
+       }
+       
+       while(fscanf(fProc, "PID: %d; PPID: %d; NAME: %s\n", &lPID, &lPPID, lName) > 0){
+         defaultId = PROCESS_FORK_ID;
+         process.event_data1 = lPID;
+         process.event_data2 = lPPID;
+         write_to_buffer(write_pos_proc,(void*)&defaultId, sizeof(uint16_t));    
+         write_to_buffer(write_pos_proc,(void*)&startTimeDelta, sizeof(uint32_t));
+         write_to_buffer(write_pos_proc,(void*)&process, sizeof(new_process)); 
+       }
+       
+       while(fscanf(fProc, "IRQ: %d; NAME: ", &lIntID) > 0){
+         /* Read 'til the end of the line */
+         fgets(lName, 200, fProc);
+
+         defaultId =  TRACE_IRQ_ENTRY;
+         irq.irq_id = lIntID;
+         irq.kernel = 1;
+         write_to_buffer(write_pos_intr,(void*)&defaultId, sizeof(uint16_t));    
+         write_to_buffer(write_pos_intr,(void*)&startTimeDelta, sizeof(uint32_t));
+         write_to_buffer(write_pos_intr,(void*)&irq, sizeof(trace_irq_entry)); 
+       }
+       fclose(fProc);
+      }
+
+      while(1){
+       int event_size;
+       uint64_t timeDelta;
+       uint8_t  subId;
+       
+       if(ltt_log_cpu){
+         cpu_id = *(uint8_t*)cur_pos;
+         cur_pos += sizeof(uint8_t);
+       }
+       evId = *(uint8_t *)cur_pos;
+       newId = evId;
+       if(evId == TRACE_HEARTBEAT) {
+         newId = TRACE_HEARTBEAT_ID;
+       }
+       cur_pos += sizeof(uint8_t);
+       time_delta = *(uint32_t*)cur_pos;
+       cur_pos += sizeof(uint32_t); 
+
+
+       //write event_id and time_delta
+       write_to_buffer(write_pos,(void*)&newId,sizeof(uint16_t));
+       write_to_buffer(write_pos,(void*)&time_delta, sizeof(uint32_t));     
+
+  /* Fix (Mathieu) */
+  if(time_delta < (0xFFFFFFFFULL&adaptation_tsc)) {
+    /* Overflow */
+    adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + 0x100000000ULL 
+                                 + (uint64_t)time_delta;
+  } else {
+    /* No overflow */
+    adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + time_delta;
+  }
+
+
+       if(evId == TRACE_BUFFER_END){
+#if 0
+    /* Fix (Mathieu) */
+    if(time_delta < (0xFFFFFFFFULL&adaptation_tsc)) {
+      /* Overflow */
+     adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + 0x100000000ULL 
+                                   + (uint64_t)time_delta;
+    } else {
+      /* No overflow */
+      adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + time_delta;
+    }
+#endif //0
+    end.cycle_count = adaptation_tsc;
+         int size = (void*)buf_out + block_size - write_pos 
+                   - sizeof(buffer_end) - sizeof(uint32_t);
+
+    /* size _lost_ ? */
+    //int size = (void*)buf_out + block_size - write_pos 
+    //            + sizeof(uint16_t) + sizeof(uint32_t);
+    g_assert((void*)write_pos < (void*)buf_out + block_size);
+         write_to_buffer(write_pos,(void*)&end,sizeof(buffer_end));
+         write_pos = buf_out + block_size - sizeof(uint32_t);
+         write_to_buffer(write_pos,(void*)&size, sizeof(uint32_t));
+         write(fdCpu,(void*)buf_out, block_size);
+         
+         //write out processes and intrrupts files
+         {
+           int size_intr = block_size + (void*)buf_intr - write_pos_intr
+                         - sizeof(buffer_end) - sizeof(uint32_t);
+           int size_proc = block_size + (void*)buf_proc - write_pos_proc
+                         - sizeof(buffer_end) - sizeof(uint32_t);
+      //int size_intr = block_size - (write_pos_intr - (void*)buf_intr);
+      //int size_proc = block_size - (write_pos_proc - (void*)buf_proc);
+           write_to_buffer(write_pos_intr,(void*)&newId,sizeof(uint16_t));
+           write_to_buffer(write_pos_intr,(void*)&time_delta, sizeof(uint32_t));     
+           end_intr = end;
+           end_intr.nanoseconds -= 20;
+           write_to_buffer(write_pos_intr,(void*)&end_intr,sizeof(buffer_start));   
+           
+           write_to_buffer(write_pos_proc,(void*)&newId,sizeof(uint16_t));
+           write_to_buffer(write_pos_proc,(void*)&time_delta, sizeof(uint32_t));     
+           end_proc = end;
+           end_proc.nanoseconds -= 40;
+           write_to_buffer(write_pos_proc,(void*)&end_proc,sizeof(buffer_start));   
+
+           write_pos_intr = buf_intr + block_size - sizeof(uint32_t);
+           write_pos_proc = buf_proc + block_size - sizeof(uint32_t);
+           write_to_buffer(write_pos_intr,(void*)&size_intr, sizeof(uint32_t));
+           write_to_buffer(write_pos_proc,(void*)&size_proc, sizeof(uint32_t));
+           //for now don't output processes and interrupt information
+           //    write(fdIntr,(void*)buf_intr,block_size);       
+           //    write(fdProc,(void*)buf_proc,block_size);       
+         }
+         break;   
+       }
+
+       event_count++;
+       switch(evId){
+         case TRACE_SYSCALL_ENTRY:
+           event_size = sizeof(trace_syscall_entry);
+           break;
+         case TRACE_SYSCALL_EXIT:
+           event_size = 0;
+           break;
+         case TRACE_TRAP_ENTRY:
+           event_size = sizeof(trace_trap_entry);
+           break;
+         case TRACE_TRAP_EXIT:
+           event_size = 0;
+           break;
+         case TRACE_IRQ_ENTRY:
+           event_size = sizeof(trace_irq_entry);
+           timeDelta = time_delta;
+           write_to_buffer(write_pos_intr,(void*)&newId, sizeof(uint16_t)); 
+           write_to_buffer(write_pos_intr,(void*)&timeDelta, sizeof(uint32_t));
+           write_to_buffer(write_pos_intr,cur_pos, event_size);
+           break;
+         case TRACE_IRQ_EXIT:
+           event_size = 0;
+           timeDelta = time_delta;
+           write_to_buffer(write_pos_intr,(void*)&newId, sizeof(uint16_t));
+           write_to_buffer(write_pos_intr,(void*)&timeDelta, sizeof(uint32_t));
+           break;
+         case TRACE_SCHEDCHANGE:
+           event_size = sizeof(trace_schedchange);
+           break;
+         case TRACE_KERNEL_TIMER:
+           event_size = 0;
+           break;
+         case TRACE_SOFT_IRQ:
+           event_size = sizeof(trace_soft_irq);
+           //    timeDelta = time_delta;
+           //    write_to_buffer(write_pos_intr,(void*)&newId, sizeof(uint16_t));
+           //    write_to_buffer(write_pos_intr,(void*)&timeDelta, sizeof(uint32_t));
+           //    write_to_buffer(write_pos_intr,cur_pos, event_size);
+           break;
+         case TRACE_PROCESS:
+           event_size = sizeof(trace_process);
+           timeDelta = time_delta;
+           subId = *(uint8_t*)cur_pos;
+           if(subId == TRACE_PROCESS_FORK || subId ==TRACE_PROCESS_EXIT){
+             if( subId == TRACE_PROCESS_FORK)tmpId = PROCESS_FORK_ID;
+             else tmpId = PROCESS_EXIT_ID;
+             write_to_buffer(write_pos_proc,(void*)&tmpId, sizeof(uint16_t));
+             write_to_buffer(write_pos_proc,(void*)&timeDelta, sizeof(uint32_t));
+             
+             process = *(new_process*)(cur_pos + sizeof(uint8_t));
+             write_to_buffer(write_pos_proc,(void*)&process, sizeof(new_process));
+           } 
+           break;
+         case TRACE_FILE_SYSTEM:
+           event_size = sizeof(trace_file_system)- sizeof(char*);
+           break;
+         case TRACE_TIMER:
+           event_size = sizeof(trace_timer);
+           break;
+         case TRACE_MEMORY:
+           event_size = sizeof(trace_memory);
+           break;
+         case TRACE_SOCKET:
+           event_size = sizeof(trace_socket);
+           break;
+         case TRACE_IPC:
+           event_size = sizeof(trace_ipc);
+           break;
+         case TRACE_NETWORK:
+           event_size = sizeof(trace_network);
+           break;
+         case TRACE_HEARTBEAT:
+           beat.seconds = 0;
+           beat.nanoseconds = 0;
+           beat.cycle_count = adaptation_tsc;
+           event_size = 0;
+           
+           write_to_buffer(write_pos_intr,(void*)&newId, sizeof(uint16_t));
+           write_to_buffer(write_pos_intr,(void*)&time_delta, sizeof(uint32_t));
+           write_to_buffer(write_pos_intr,(void*)&beat, sizeof(heartbeat));              
+           write_to_buffer(write_pos_proc,(void*)&newId, sizeof(uint16_t));
+           write_to_buffer(write_pos_proc,(void*)&time_delta, sizeof(uint32_t));
+           write_to_buffer(write_pos_proc,(void*)&beat, sizeof(heartbeat));              
+           break;
+          default:
+           event_size = -1;
+           break;
+       }
+       if(evId != TRACE_FILE_SYSTEM && event_size >=0){
+         write_to_buffer(write_pos, cur_pos, event_size); 
+       
+         if(evId == TRACE_HEARTBEAT){
+           write_to_buffer(write_pos, (void*)&beat, sizeof(heartbeat));                  
+         }
+         
+         cur_pos += event_size + sizeof(uint16_t); //skip data_size
+       }else if(evId == TRACE_FILE_SYSTEM){
+         size_t nbBytes;
+         char  c = '\0';
+         tFileSys = (trace_file_system*)cur_pos;
+         subId = tFileSys->event_sub_id;       
+         if(subId == TRACE_FILE_SYSTEM_OPEN || subId == TRACE_FILE_SYSTEM_EXEC){
+           nbBytes = tFileSys->event_data2 +1;
+         }else nbBytes = 0;
+         
+         write_to_buffer(write_pos, cur_pos, event_size);
+         cur_pos += event_size + sizeof(char*);
+         if(nbBytes){
+           write_to_buffer(write_pos, cur_pos, nbBytes);       
+         }else{
+           write_to_buffer(write_pos, (void*)&c, 1);
+         }
+         cur_pos += nbBytes + sizeof(uint16_t); //skip data_size
+       }else if(event_size == -1){
+         printf("Unknown event: evId=%d, i=%d, event_count=%d\n", newId, i, event_count);
+         exit(1);
+       }
+      } //end while(1)      
+    }
+    close(fd);
+    close(fdCpu);
+    g_free(buffer);
+    buffer = NULL;
+    g_free(buf_fac);
+    g_free(buf_intr);
+    g_free(buf_proc);
+    g_free(buf_out);
+  }
+
+  
+
+
+
+  //write to system.xml
+  fprintf(fp,"<system \n");
+  fprintf(fp,"node_name=\"%s\" \n", node_name);
+  fprintf(fp,"domainname=\"%s\" \n", domainname);
+  fprintf(fp,"cpu=\"%d\" \n", cpu);
+  fprintf(fp,"arch_size=\"%s\" \n", arch_size);
+  fprintf(fp,"endian=\"%s\" \n",endian);
+  fprintf(fp,"kernel_name=\"%s\" \n",kernel_name);
+  fprintf(fp,"kernel_release=\"%s\" \n",kernel_release);
+  fprintf(fp,"kernel_version=\"%s\" \n",kernel_version);
+  fprintf(fp,"machine=\"%s\" \n",machine);
+  fprintf(fp,"processor=\"%s\" \n",processor);
+  fprintf(fp,"hardware_platform=\"%s\" \n",hardware_platform);
+  fprintf(fp,"operating_system=\"%s\" \n",operating_system);
+  fprintf(fp,"ltt_major_version=\"%d\" \n",ltt_major_version);
+  fprintf(fp,"ltt_minor_version=\"%d\" \n",ltt_minor_version);
+  fprintf(fp,"ltt_block_size=\"%d\" \n",ltt_block_size);
+  fprintf(fp,">\n");
+  fprintf(fp,"This is just a test\n");
+  fprintf(fp,"</system>\n");
+  fflush(fp);
+
+  close(fdFac);
+  close(fdIntr);
+  close(fdProc); 
+  fclose(fp);
+
+  g_message("Conversion completed. Don't forget to copy core.xml to eventdefs directory\n");
+  
+  return 0;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/core.xml b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/core.xml
new file mode 100644 (file)
index 0000000..b1b23d6
--- /dev/null
@@ -0,0 +1,263 @@
+<facility name=core>
+  <description>The core facility contains the basic events</description>
+
+  <event name=facility_load>
+    <description>Facility used in the trace</description>
+    <struct>
+      <field name="name"><string/></field>
+      <field name="checksum"><uint size=4/></field>
+      <field name="base_code"><uint size=4/></field>
+    </struct>
+  </event>
+
+  <event name=syscall_entry>
+    <description>Entry in a given system call</description>
+    <struct>
+      <field name="syscall_id"> <description>Syscall entry number in entry.S</description> <uint size=1/> </field>
+      <field name="address"> <description>Address from which call was made</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=syscall_exit>
+    <description>Exit from a given system call</description>
+  </event>
+
+  <event name=trap_entry>
+    <description>Entry in a trap</description>
+    <struct>
+      <field name="trap_id"> <description>Trap number</description> <uint size=2/> </field>
+      <field name="address"> <description>Address where trap occured</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=trap_exit>
+    <description>Exit from a trap</description>
+  </event>
+
+  <event name=irq_entry>
+    <description>Entry in an irq</description>
+    <struct>
+      <field name="irq_id"> <description>IRQ number</description> <uint size=1/> </field>
+      <field name="kernel"> <description>Are we executing kernel code</description> <uint size=1/> </field>
+     </struct>
+  </event>
+
+  <event name=irq_exit>
+    <description>Exit from an IRQ</description>
+  </event>
+
+  <event name=schedchange>
+    <description>Scheduling change</description>
+    <struct>
+      <field name="out"> <description>Outgoing process</description> <uint size=4/> </field>
+      <field name="in"> <description>Incoming process</description> <uint size=4/> </field>
+      <field name="out_state"> <description>Outgoing process' state</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=kernel_timer>
+    <description>The kernel timer routine has been called</description>
+  </event>
+
+  <event name=soft_irq>
+    <description>Hit key part of soft-irq management</description>
+    <struct>
+      <field name="event_sub_id"> <description>Soft-irq event Id</description> 
+        <enum size=1>
+          <label name=TRACE_EV_SOFT_IRQ_BOTTOM_HALF value=1/>
+          <label name=TRACE_EV_SOFT_IRQ_SOFT_IRQ/>
+          <label name=TRACE_EV_SOFT_IRQ_TASKLET_ACTION/>
+          <label name=TRACE_EV_SOFT_IRQ_TASKLET_HI_ACTION/>
+        </enum> 
+      </field>
+       
+      <field name="event_data"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=process>
+    <description>Hit key part of process management</description>
+    <struct>
+      <field name="event_sub_id"> <description>Process event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_PROCESS_KTHREAD value=1/>
+          <label name=TRACE_EV_PROCESS_FORK/>
+          <label name=TRACE_EV_PROCESS_EXIT/>
+          <label name=TRACE_EV_PROCESS_WAIT/>
+          <label name=TRACE_EV_PROCESS_SIGNAL/>
+          <label name=TRACE_EV_PROCESS_WAKEUP/>
+          <label name=TRACE_EV_PROCESS_RELEASE/>
+        </enum> 
+      </field>
+       
+      <field name="event_data1"> <description>Data associated with event</description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=file_system>
+    <description>Hit key part of file system</description>
+    <struct>
+      <field name="event_sub_id"> <description>File system event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_FILE_SYSTEM_BUF_WAIT_START value=1/>
+          <label name=TRACE_EV_FILE_SYSTEM_BUF_WAIT_END/>
+          <label name=TRACE_EV_FILE_SYSTEM_EXEC/>
+          <label name=TRACE_EV_FILE_SYSTEM_OPEN/>
+          <label name=TRACE_EV_FILE_SYSTEM_CLOSE/>
+          <label name=TRACE_EV_FILE_SYSTEM_READ/>
+          <label name=TRACE_EV_FILE_SYSTEM_WRITE/>
+          <label name=TRACE_EV_FILE_SYSTEM_SEEK/>
+          <label name=TRACE_EV_FILE_SYSTEM_IOCTL/>
+          <label name=TRACE_EV_FILE_SYSTEM_SELECT/>
+          <label name=TRACE_EV_FILE_SYSTEM_POLL/>
+        </enum> 
+      </field>
+       
+      <field name="event_data1"> <description>Event data </description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Event data 2</description> <uint size=4/> </field>
+      <field name="file_name"> <description>Name of file operated on </description> <string/> </field>
+     </struct>
+  </event>
+
+  <event name=timer>
+    <description>Hit key part of timer management</description>
+    <struct>
+      <field name="event_sub_id"> <description>Timer event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_TIMER_EXPIRED value=1/>
+          <label name=TRACE_EV_TIMER_SETITIMER/>
+          <label name=TRACE_EV_TIMER_SETTIMEOUT/>
+        </enum> 
+      </field>
+       
+      <field name="event_sdata"> <description>Short data</description> <uint size=1/> </field>
+      <field name="event_data1"> <description>Data associated with event</description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=memory>
+    <description>Hit key part of memory management</description>
+    <struct>
+      <field name="event_sub_id"> <description>Memory event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_MEMORY_PAGE_ALLOC value=1/>
+          <label name=TRACE_EV_MEMORY_PAGE_FREE/>
+          <label name=TRACE_EV_MEMORY_SWAP_IN/>
+          <label name=TRACE_EV_MEMORY_SWAP_OUT/>
+          <label name=TRACE_EV_MEMORY_PAGE_WAIT_START/>
+          <label name=TRACE_EV_MEMORY_PAGE_WAIT_END/>
+        </enum> 
+      </field>
+       
+      <field name="event_data"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=socket>
+    <description>Hit key part of socket communication</description>
+    <struct>
+      <field name="event_sub_id"> <description>Memory event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_SOCKET_CALL value=1/>
+          <label name=TRACE_EV_SOCKET_CREATE/>
+          <label name=TRACE_EV_SOCKET_SEND/>
+          <label name=TRACE_EV_SOCKET_RECEIVE/>
+        </enum> 
+      </field>
+       
+      <field name="event_data1"> <description>Data associated with event</description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=ipc>
+    <description>Hit key part of System V IPC</description>
+    <struct>
+      <field name="event_sub_id"> <description>Memory event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_IPC_CALL value=1/>
+          <label name=TRACE_EV_IPC_MSG_CREATE/>
+          <label name=TRACE_EV_IPC_SEM_CREATE/>
+          <label name=TRACE_EV_IPC_SHM_CREATE/>
+        </enum> 
+      </field>
+       
+      <field name="event_data1"> <description>Data associated with event</description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=network>
+    <description>Hit key part of network communication</description>
+    <struct>
+      <field name="event_sub_id"> <description>Memory event ID</description> 
+        <enum size=1>
+          <label name=TRACE_EV_NETWORK_PACKET_IN value=1/>
+          <label name=TRACE_EV_NETWORK_PACKET_OUT/>
+        </enum> 
+      </field>
+       
+      <field name="event_data"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=block_start>
+    <description>Block start timestamp</description>
+    <typeref name=block_timestamp/>
+  </event>
+
+  <event name=block_end>
+    <description>Block end timestamp</description>
+    <typeref name=block_timestamp/>
+  </event>
+
+  <event name=time_heartbeat>
+    <description>System time values sent periodically to minimize cycle counter
+                 drift with respect to real time clock and to detect cycle counter roolovers
+    </description>
+    <typeref name=timestamp/>
+  </event>
+
+  <type name=block_timestamp>
+    <struct>
+      <field name=timestamp><typeref name=timestamp/></field>
+      <field name=block_id><uint size=4/></field>
+    </struct>
+  </type>
+
+  <type name=timestamp>
+    <struct>
+      <field name=time><typeref name=timespec/></field>
+      <field name="cycle_count"><uint size=8/></field>
+    </struct>
+  </type>
+
+  <type name=timespec>
+    <struct>
+      <field name="seconds"><uint size=4/></field>
+      <field name="nanoseconds"><uint size=4/></field>
+    </struct>
+  </type>
+
+
+  <event name=process_fork>
+    <description>Fork a new process</description>
+    <struct>
+      <field name="child_pid"> <description>Data associated with event</description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+  <event name=process_exit>
+    <description>Exit from a process</description>
+    <struct>
+      <field name="event_data1"> <description>Data associated with event</description> <uint size=4/> </field>
+      <field name="event_data2"> <description>Data associated with event</description> <uint size=4/> </field>
+     </struct>
+  </event>
+
+</facility>
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/sysInfo b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/convert-old/sysInfo
new file mode 100755 (executable)
index 0000000..fdd7b59
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# DO NOT FORGET TO DISABLE ALL THE JAVA OPTIONS IN NETSCAPE
+# OTHERWISE IT WILL DIE ...
+
+outputFile=sysInfo.out
+
+NODE_NAME=`uname -n`
+echo "node_name="$NODE_NAME > $outputFile
+
+DOMAINNAME="`hostname --domain`"
+echo "domainname="$DOMAINNAME >> $outputFile
+
+KERNEL_NAME="`uname -s`"
+echo "kernel_name="$KERNEL_NAME >> $outputFile
+
+KERNEL_RELEASE="`uname -r`"
+echo "kernel_release="$KERNEL_RELEASE >> $outputFile
+
+KERNEL_VERSION="`uname -v`"
+echo "kernel_version="$KERNEL_VERSION >> $outputFile
+
+MACHINE="`uname -m`"
+echo "machine="$MACHINE >> $outputFile
+
+
+# not available anymore in uname version 5 and newer
+PROCESSOR="`uname -p`"
+echo "processor="$PROCESSOR >> $outputFile
+
+# not available anymore in uname version 5 and newer
+HARDWARE_PLATFORM="`uname -i`"
+echo "hardware_platform="$HARDWARE_PLATFORM >> $outputFile
+
+OPERATING_SYSTEM="`uname -o`"
+echo "operating_system="$OPERATING_SYSTEM >> $outputFile
+
+
+#export $NODE_NAME 
+#export $NODE_NAME $DOMAINNAME $KERNEL_NAME $KERNEL_RELEASE $KERNEL_VERSION $MACHINE $PROCESSOR $HARDWARE_PLATFORM $OPERATING_SYSTEM
+
+
+
+#/sbin/lilo -C "$liloConf"
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/crc32.tab b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/crc32.tab
new file mode 100644 (file)
index 0000000..d0174ad
--- /dev/null
@@ -0,0 +1,52 @@
+  0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
+  0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
+  0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
+  0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
+  0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
+  0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
+  0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
+  0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
+  0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
+  0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
+  0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
+  0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
+  0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
+  0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
+  0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
+  0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
+  0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
+  0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
+  0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
+  0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
+  0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
+  0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
+  0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
+  0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
+  0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
+  0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
+  0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
+  0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
+  0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
+  0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
+  0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
+  0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
+  0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
+  0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
+  0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
+  0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
+  0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
+  0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
+  0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
+  0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
+  0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
+  0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
+  0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
+  0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
+  0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
+  0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
+  0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
+  0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
+  0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
+  0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
+  0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
+  0x2d02ef8dU
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/event.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/event.c
new file mode 100644 (file)
index 0000000..a5b0468
--- /dev/null
@@ -0,0 +1,786 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+
+#include <asm/types.h>
+#include <byteswap.h>
+
+#include "parser.h"
+#include <ltt/ltt.h>
+#include "ltt-private.h"
+#include <ltt/event.h>
+#include <ltt/trace.h>
+#include <ltt/ltt-types.h>
+
+LttEvent *ltt_event_new()
+{
+  return g_new(LttEvent, 1);
+}
+
+void ltt_event_destroy(LttEvent *event)
+{
+  g_free(event);
+}
+
+
+#if 0
+/* Use get_field_type_size instead */
+/*****************************************************************************
+ *Function name
+ *    ltt_event_refresh_fields   : refresh fields of an event 
+ *Input params
+ *    offsetRoot      : offset from the root
+ *    offsetParent    : offset from the parent
+ *    fld             : field
+ *    evD             : event data
+ *    reverse_byte_order : 1 or 0
+ *Return value
+ *    int             : size of the field
+ ****************************************************************************/
+
+int ltt_event_refresh_fields(int offsetRoot,int offsetParent, 
+                            LttField * fld, void *evD, gboolean reverse_byte_order)
+{
+  int size, size1, element_number, i, offset1, offset2;
+  LttType * type = fld->field_type;
+
+  switch(type->type_class) {
+    case LTT_ARRAY:
+      element_number = (int) type->element_number;
+      if(fld->field_fixed == 0){// has string or sequence
+        size = 0;
+        for(i=0;i<element_number;i++){
+          size += ltt_event_refresh_fields(offsetRoot+size,size, 
+             fld->child[0], evD+size, reverse_byte_order);
+        }
+      }else size = fld->field_size;
+      break;
+
+    case LTT_SEQUENCE:
+      size1 = fld->sequ_number_size;
+      element_number = getIntNumber(reverse_byte_order,size1,evD);
+      type->element_number = element_number;
+      if(fld->element_size > 0){
+        size = element_number * fld->element_size;
+      }else{//sequence has string or sequence
+        size = 0;
+        for(i=0;i<element_number;i++){
+          size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1, 
+                   fld->child[0], evD+size+size1, reverse_byte_order);
+        }      
+        size += size1;
+      }
+      break;
+
+    case LTT_STRING:
+      size = strlen((gchar*)evD) + 1; //include end : '\0'
+      break;
+
+    case LTT_STRUCT:
+      element_number = (int) type->element_number;
+      if(fld->field_fixed == 0){
+        offset1 = offsetRoot;
+        offset2 = 0;
+        for(i=0;i<element_number;i++){
+          size=ltt_event_refresh_fields(offset1,offset2,
+                               fld->child[i],evD+offset2, reverse_byte_order);
+          offset1 += size;
+          offset2 += size;
+        }      
+        size = offset2;
+      }else size = fld->field_size;
+      break;
+      
+    case LTT_UNION:
+      size = fld->field_size;
+      break;
+
+    default:
+      size = fld->field_size;
+  }
+
+#if 0
+  if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
+     type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
+    size = fld->field_size;
+  }else if(type->type_class == LTT_ARRAY){
+    element_number = (int) type->element_number;
+    if(fld->field_fixed == 0){// has string or sequence
+      size = 0;
+      for(i=0;i<element_number;i++){
+             size += ltt_event_refresh_fields(offsetRoot+size,size, 
+                                        fld->child[0], evD+size);
+      }
+    }else size = fld->field_size;
+  }else if(type->type_class == LTT_SEQUENCE){
+    size1 = fld->sequ_number_size;
+    element_number = getIntNumber(size1,evD);
+    type->element_number = element_number;
+    if(fld->element_size > 0){
+      size = element_number * fld->element_size;
+    }else{//sequence has string or sequence
+      size = 0;
+      for(i=0;i<element_number;i++){
+             size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1, 
+                                        fld->child[0], evD+size+size1);
+      }        
+      size += size1;
+    }
+  }else if(type->type_class == LTT_STRING){
+    size = strlen((char*)evD) + 1; //include end : '\0'
+  }else if(type->type_class == LTT_STRUCT){
+    element_number = (int) type->element_number;
+    if(fld->field_fixed == 0){
+      offset1 = offsetRoot;
+      offset2 = 0;
+      for(i=0;i<element_number;i++){
+             size=ltt_event_refresh_fields(offset1,offset2,
+                                      fld->child[i],evD+offset2);
+       offset1 += size;
+       offset2 += size;
+      }      
+      size = offset2;
+    }else size = fld->field_size;
+  }
+#endif //0
+  fld->offset_root     = offsetRoot;
+  fld->offset_parent   = offsetParent;
+  fld->fixed_root      = (offsetRoot==-1)   ? 0 : 1;
+  fld->fixed_parent    = (offsetParent==-1) ? 0 : 1;
+  fld->field_size      = size;
+
+  return size;
+}
+#endif //0
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_eventtype_id: get event type id 
+ *                            (base id + position of the event)
+ *Input params
+ *    e                     : an instance of an event type   
+ *Return value
+ *    unsigned              : event type id
+ ****************************************************************************/
+
+unsigned ltt_event_eventtype_id(const LttEvent *e)
+{
+  return (unsigned) e->event_id;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_facility : get the facility of the event
+ *Input params
+ *    e                  : an instance of an event type   
+ *Return value
+ *    LttFacility *     : the facility of the event
+ ****************************************************************************/
+
+LttFacility *ltt_event_facility(const LttEvent *e)
+{
+  LttTrace * trace = e->tracefile->trace;
+  unsigned id = e->facility_id;
+  LttFacility *facility = ltt_trace_facility_by_id(trace,id);
+  
+  g_assert(facility->exists);
+
+  return facility;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_facility_id : get the facility id of the event
+ *Input params
+ *    e                  : an instance of an event type   
+ *Return value
+ *    unsigned          : the facility of the event
+ ****************************************************************************/
+
+unsigned ltt_event_facility_id(const LttEvent *e)
+{
+  return e->facility_id;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_eventtype : get the event type of the event
+ *Input params
+ *    e                   : an instance of an event type   
+ *Return value
+ *    LttEventType *     : the event type of the event
+ ****************************************************************************/
+
+LttEventType *ltt_event_eventtype(const LttEvent *e)
+{
+  LttFacility* facility = ltt_event_facility(e);
+  if(!facility) return NULL;
+  return &g_array_index(facility->events, LttEventType, e->event_id);
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_field : get the root field of the event
+ *Input params
+ *    e               : an instance of an event type   
+ *Return value
+ *    LttField *      : the root field of the event
+ ****************************************************************************/
+
+LttField *ltt_event_field(LttEvent *e)
+{
+  LttField * field;
+  LttEventType * event_type = ltt_event_eventtype(e);
+  if(unlikely(!event_type)) return NULL;
+  field = event_type->root_field;
+  if(unlikely(!field)) return NULL;
+
+  get_field_type_size(e->tracefile, event_type, 0, 0,
+      field, e->data);
+  
+  return field;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_time : get the time of the event
+ *Input params
+ *    e              : an instance of an event type   
+ *Return value
+ *    LttTime       : the time of the event
+ ****************************************************************************/
+
+LttTime ltt_event_time(const LttEvent *e)
+{
+  return e->event_time;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_time : get the cycle count of the event
+ *Input params
+ *    e              : an instance of an event type   
+ *Return value
+ *    LttCycleCount  : the cycle count of the event
+ ****************************************************************************/
+
+LttCycleCount ltt_event_cycle_count(const LttEvent *e)
+{
+  return e->tsc;
+}
+
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_position_get : get the event position data
+ *Input params
+ *    e                  : an instance of an event type   
+ *    ep                 : a pointer to event's position structure
+ *    tf                 : tracefile pointer
+ *    block              : current block
+ *    offset             : current offset
+ *    tsc                : current tsc
+ ****************************************************************************/
+void ltt_event_position_get(LttEventPosition *ep, LttTracefile **tf,
+        guint *block, guint *offset, guint64 *tsc)
+{
+  *tf = ep->tracefile;
+  *block = ep->block;
+  *offset = ep->offset;
+  *tsc = ep->tsc;
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_position : get the event's position
+ *Input params
+ *    e                  : an instance of an event type   
+ *    ep                 : a pointer to event's position structure
+ ****************************************************************************/
+
+void ltt_event_position(LttEvent *e, LttEventPosition *ep)
+{
+  ep->tracefile = e->tracefile;
+  ep->block = e->block;
+  ep->offset = e->offset;
+  ep->tsc = e->tsc;
+}
+
+LttEventPosition * ltt_event_position_new()
+{
+  return g_new(LttEventPosition, 1);
+}
+
+
+/*****************************************************************************
+ * Function name
+ *    ltt_event_position_compare : compare two positions
+ *    A NULL value is infinite.
+ * Input params
+ *    ep1                    : a pointer to event's position structure
+ *    ep2                    : a pointer to event's position structure
+ * Return
+ *    -1 is ep1 < ep2
+ *    1 if ep1 > ep2
+ *    0 if ep1 == ep2
+ ****************************************************************************/
+
+
+gint ltt_event_position_compare(const LttEventPosition *ep1,
+                                const LttEventPosition *ep2)
+{
+  if(ep1 == NULL && ep2 == NULL)
+      return 0;
+  if(ep1 != NULL && ep2 == NULL)
+      return -1;
+  if(ep1 == NULL && ep2 != NULL)
+      return 1;
+
+   if(ep1->tracefile != ep2->tracefile)
+    g_error("ltt_event_position_compare on different tracefiles makes no sense");
+   
+  if(ep1->block < ep2->block)
+    return -1;
+  if(ep1->block > ep2->block)
+    return 1;
+  if(ep1->offset < ep2->offset)
+    return -1;
+  if(ep1->offset > ep2->offset)
+    return 1;
+  return 0;
+}
+
+/*****************************************************************************
+ * Function name
+ *    ltt_event_position_copy : copy position
+ * Input params
+ *    src                    : a pointer to event's position structure source
+ *    dest                   : a pointer to event's position structure dest
+ * Return
+ *    void
+ ****************************************************************************/
+void ltt_event_position_copy(LttEventPosition *dest,
+                             const LttEventPosition *src)
+{
+  if(src == NULL)
+    dest = NULL;
+  else
+    *dest = *src;
+}
+
+
+
+LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep)
+{
+  return ep->tracefile;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_cpu_i: get the cpu id where the event happens
+ *Input params
+ *    e              : an instance of an event type   
+ *Return value
+ *    unsigned       : the cpu id
+ ****************************************************************************/
+
+unsigned ltt_event_cpu_id(LttEvent *e)
+{
+  return e->tracefile->cpu_num;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_data : get the raw data for the event
+ *Input params
+ *    e              : an instance of an event type   
+ *Return value
+ *    void *         : pointer to the raw data for the event
+ ****************************************************************************/
+
+void *ltt_event_data(LttEvent *e)
+{
+  return e->data;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_field_element_number
+ *                   : The number of elements in a sequence field is specific
+ *                     to each event. This function returns the number of 
+ *                     elements for an array or sequence field in an event.
+ *Input params
+ *    e              : an instance of an event type
+ *    f              : a field of the instance
+ *Return value
+ *    unsigned       : the number of elements for an array/sequence field
+ ****************************************************************************/
+guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
+{
+  if(f->field_type->type_class != LTT_ARRAY &&
+     f->field_type->type_class != LTT_SEQUENCE)
+    return 0;
+  
+  if(f->field_type->type_class == LTT_ARRAY)
+    return f->field_type->element_number;
+  return ltt_get_uint(LTT_GET_BO(e->tracefile), f->sequ_number_size,
+      e + f->offset_root);
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_event_field_element_select
+ *                   : Set the currently selected element for a sequence or
+ *                     array field
+ *                     O(1) if fields are of fixed size, else O(n) if fields are
+ *                     of variable size.
+ *Input params
+ *    e              : an instance of an event type
+ *    f              : a field of the instance
+ *    i              : the ith element (0, ...)
+ ****************************************************************************/
+void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
+{
+  unsigned element_number;
+  LttField *field;
+  unsigned int k;
+  size_t size;
+  LttEventType *event_type;
+  if(f->field_type->type_class != LTT_ARRAY &&
+     f->field_type->type_class != LTT_SEQUENCE)
+    return ;
+
+  element_number  = ltt_event_field_element_number(e,f);
+  event_type = ltt_event_eventtype(e);
+  /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
+   */
+  if(i >= element_number) return;
+  
+  field = f->child[0];
+  
+  if(f->field_type->type_class == LTT_SEQUENCE)
+    size = f->sequ_number_size;
+  else
+    size = 0;
+  
+  if(field->fixed_size == FIELD_FIXED) {
+      size += field->field_size * i;
+
+      get_field_type_size(e->tracefile, event_type,
+                  f->offset_root+size, size, field, e->data);
+
+  } else {
+    for(k=0;k<=i;k++){
+      size += get_field_type_size(e->tracefile, event_type,
+                  f->offset_root+size, size, field, e->data);
+    }
+  }
+  f->current_element = i;
+}
+
+/*****************************************************************************
+ * These functions extract data from an event after architecture specific
+ * conversions
+ ****************************************************************************/
+guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
+{
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
+
+  LttTypeEnum t = f->field_type->type_class;
+
+  g_assert(t == LTT_UINT || t == LTT_ENUM);
+
+  if(f->field_size == 1){
+    guint8 x = *(guint8 *)(e->data + f->offset_root);
+    return (guint32) x;    
+  }else if(f->field_size == 2){
+    return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
+  }else if(f->field_size == 4){
+    return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
+  }
+#if 0
+  else if(f->field_size == 8){
+    guint64 x = *(guint64 *)(e->data + f->offset_root);
+    if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
+      return (unsigned int) (revFlag ? GUINT64_FROM_BE(x): x);    
+    else
+      return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);    
+  }
+#endif //0
+  g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
+  return 0;
+}
+
+gint32 ltt_event_get_int(LttEvent *e, LttField *f)
+{
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
+
+  g_assert(f->field_type->type_class == LTT_INT);
+
+  if(f->field_size == 1){
+    gint8 x = *(gint8 *)(e->data + f->offset_root);
+    return (gint32) x;    
+  }else if(f->field_size == 2){
+    return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
+  }else if(f->field_size == 4){
+    return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
+  }
+#if 0
+  else if(f->field_size == 8){
+    gint64 x = *(gint64 *)(e->data + f->offset_root);
+    if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
+      return (int) (revFlag ? GINT64_FROM_BE(x): x);    
+    else
+      return (int) (revFlag ? GINT64_FROM_LE(x): x);    
+  }
+#endif //0
+  g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
+  return 0;
+}
+
+guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
+{
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
+
+  LttTypeEnum t = f->field_type->type_class;
+
+  g_assert(t == LTT_UINT || t == LTT_ENUM 
+      || t == LTT_ULONG || LTT_SIZE_T || LTT_OFF_T || LTT_POINTER);
+
+  if(f->field_size == 1){
+    guint8 x = *(guint8 *)(e->data + f->offset_root);
+    return (guint64) x;    
+  }else if(f->field_size == 2){
+    return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
+  }else if(f->field_size == 4){
+    return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
+  }else if(f->field_size == 8){
+    return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
+  }
+  g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
+  return 0;
+}
+
+gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
+{
+  //int revFlag = e->tracefile->trace->my_arch_endian == 
+  //              e->tracefile->trace->system_description->endian ? 0:1;
+  gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
+
+  g_assert( f->field_type->type_class == LTT_INT
+      || f->field_type->type_class == LTT_LONG
+      || f->field_type->type_class == LTT_SSIZE_T);
+
+  if(f->field_size == 1){
+    gint8 x = *(gint8 *)(e->data + f->offset_root);
+    return (gint64) x;    
+  }else if(f->field_size == 2){
+    return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
+  }else if(f->field_size == 4){
+    return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
+  }else if(f->field_size == 8){
+    return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
+  }
+  g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
+  return 0;
+}
+
+float ltt_event_get_float(LttEvent *e, LttField *f)
+{
+  g_assert(LTT_HAS_FLOAT(e->tracefile));
+  gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
+
+  g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 4);
+
+  if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
+  else{
+    void *ptr = e->data + f->offset_root;
+    guint32 value = bswap_32(*(guint32*)ptr);
+    return *(float*)&value;
+  }
+}
+
+double ltt_event_get_double(LttEvent *e, LttField *f)
+{
+  g_assert(LTT_HAS_FLOAT(e->tracefile));
+  gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
+
+  g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 8);
+
+  if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
+  else {
+    void *ptr = e->data + f->offset_root;
+    guint64 value = bswap_64(*(guint64*)ptr);
+    return *(double*)&value;
+  }
+}
+
+/*****************************************************************************
+ * The string obtained is only valid until the next read from
+ * the same tracefile.
+ ****************************************************************************/
+char *ltt_event_get_string(LttEvent *e, LttField *f)
+{
+  g_assert(f->field_type->type_class == LTT_STRING);
+
+  return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    get_field_type_size : set the fixed and dynamic sizes of the field type
+ *    from the data read.
+ *Input params 
+ *    tf              : tracefile
+ *    event_type      : event type
+ *    offset_root     : offset from the root
+ *    offset_parent   : offset from the parent
+ *    field           : field
+ *    data            : a pointer to the event data.
+ *Returns the field type size.
+ ****************************************************************************/
+size_t get_field_type_size(LttTracefile *tf, LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    LttField *field, void *data)
+{
+  size_t size = 0;
+  guint i;
+  LttType *type;
+  
+  g_assert(field->fixed_root != FIELD_UNKNOWN);
+  g_assert(field->fixed_parent != FIELD_UNKNOWN);
+  g_assert(field->fixed_size != FIELD_UNKNOWN);
+
+  field->offset_root = offset_root;
+  field->offset_parent = offset_parent;
+  
+  type = field->field_type;
+
+  switch(type->type_class) {
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_FLOAT:
+    case LTT_ENUM:
+    case LTT_POINTER:
+    case LTT_LONG:
+    case LTT_ULONG:
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+      g_assert(field->fixed_size == FIELD_FIXED);
+      size = field->field_size;
+      break;
+    case LTT_SEQUENCE:
+      {
+        gint seqnum = ltt_get_uint(LTT_GET_BO(tf),
+                        field->sequ_number_size,
+                        data + offset_root);
+
+        if(field->child[0]->fixed_size == FIELD_FIXED) {
+          size = field->sequ_number_size + 
+            (seqnum * get_field_type_size(tf, event_type,
+                                          offset_root, offset_parent,
+                                          field->child[0], data));
+        } else {
+          size += field->sequ_number_size;
+          for(i=0;i<seqnum;i++) {
+            size_t child_size;
+            child_size = get_field_type_size(tf, event_type,
+                                    offset_root, offset_parent,
+                                    field->child[0], data);
+            offset_root += child_size;
+            offset_parent += child_size;
+            size += child_size;
+          }
+        }
+        field->field_size = size;
+      }
+      break;
+    case LTT_STRING:
+      size = strlen((char*)(data+offset_root)) + 1;// length + \0
+      field->field_size = size;
+      break;
+    case LTT_ARRAY:
+      if(field->fixed_size == FIELD_FIXED)
+        size = field->field_size;
+      else {
+        for(i=0;i<field->field_type->element_number;i++) {
+          size_t child_size;
+          child_size = get_field_type_size(tf, event_type,
+                                  offset_root, offset_parent,
+                                  field->child[0], data);
+          offset_root += child_size;
+          offset_parent += child_size;
+          size += child_size;
+        }
+        field->field_size = size;
+      }
+      break;
+    case LTT_STRUCT:
+      if(field->fixed_size == FIELD_FIXED)
+        size = field->field_size;
+      else {
+        size_t current_root_offset = offset_root;
+        size_t current_offset = 0;
+        size_t child_size = 0;
+        for(i=0;i<type->element_number;i++) {
+          child_size = get_field_type_size(tf,
+                     event_type, current_root_offset, current_offset, 
+                     field->child[i], data);
+          current_offset += child_size;
+          current_root_offset += child_size;
+          
+        }
+        size = current_offset;
+        field->field_size = size;
+      }
+      break;
+    case LTT_UNION:
+      if(field->fixed_size == FIELD_FIXED)
+        size = field->field_size;
+      else {
+        size_t current_root_offset = field->offset_root;
+        size_t current_offset = 0;
+        for(i=0;i<type->element_number;i++) {
+          size = get_field_type_size(tf, event_type,
+                 current_root_offset, current_offset, 
+                 field->child[i], data);
+          size = max(size, field->child[i]->field_size);
+        }
+        field->field_size = size;
+      }
+      break;
+  }
+
+  return size;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/event.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/event.h
new file mode 100644 (file)
index 0000000..a7408b4
--- /dev/null
@@ -0,0 +1,141 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <glib.h>
+#include <ltt/ltt.h>
+#include <sys/types.h>
+
+LttEvent *ltt_event_new();
+
+void ltt_event_destroy(LttEvent *event);
+
+/* Events and their content, including the raw data, are only valid 
+   until reading another event from the same tracefile. 
+   Indeed, since event reading is critical to the performance, 
+   the memory associated with an event may be reused at each read. */
+
+/* Obtain the trace unique integer id associated with the type of 
+   this event */
+
+unsigned ltt_event_eventtype_id(const LttEvent *e);
+
+unsigned ltt_event_facility_id(const LttEvent *e);
+
+/* Facility and type for the event */
+
+LttFacility *ltt_event_facility(const LttEvent *e);
+
+LttEventType *ltt_event_eventtype(const LttEvent *e);
+
+
+/* Root field for the event */
+
+LttField *ltt_event_field(LttEvent *e);
+
+
+/* Time and cycle count for the event */
+
+LttTime ltt_event_time(const LttEvent *e);
+
+LttCycleCount ltt_event_cycle_count(const LttEvent *e);
+
+
+/* Obtain the position of the event within the tracefile. This
+   is used to seek back to this position later or to seek to another
+   position, computed relative to this position. The event position
+   structure is opaque and contains several fields, only two
+   of which are user accessible: block number and event index
+   within the block. */
+
+void ltt_event_position(LttEvent *e, LttEventPosition *ep);
+
+LttEventPosition * ltt_event_position_new();
+
+void ltt_event_position_get(LttEventPosition *ep, LttTracefile **tf,
+        guint *block, guint *offset, guint64 *tsc);
+
+gint ltt_event_position_compare(const LttEventPosition *ep1,
+                                const LttEventPosition *ep2);
+
+void ltt_event_position_copy(LttEventPosition *dest,
+                             const LttEventPosition *src);
+
+LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep);
+
+/* CPU id of the event */
+
+unsigned ltt_event_cpu_id(LttEvent *e);
+
+
+/* Pointer to the raw data for the event. This should not be used directly
+   unless prepared to do all the architecture specific conversions. */
+
+void *ltt_event_data(LttEvent *e);
+
+
+/* The number of elements in a sequence field is specific to each event 
+   instance. This function returns the number of elements for an array or 
+   sequence field in an event. */
+
+guint64 ltt_event_field_element_number(LttEvent *e, LttField *f);
+
+
+/* Set the currently selected element for a sequence or array field. */
+
+void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i);
+
+
+/* A union is like a structure except that only a single member at a time
+   is present depending on the specific event instance. This function tells
+   the active member for a union field in an event. */
+
+unsigned ltt_event_field_union_member(LttEvent *e, LttField *f);
+
+
+/* These functions extract data from an event after architecture specific
+   conversions. */
+
+guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f);
+
+gint32 ltt_event_get_int(LttEvent *e, LttField *f);
+
+guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f);
+
+gint64 ltt_event_get_long_int(LttEvent *e, LttField *f);
+
+float ltt_event_get_float(LttEvent *e, LttField *f);
+
+double ltt_event_get_double(LttEvent *e, LttField *f);
+
+
+/* The string obtained is only valid until the next read from
+   the same tracefile. */
+
+gchar *ltt_event_get_string(LttEvent *e, LttField *f);
+
+size_t get_field_type_size(LttTracefile *tf,
+    LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    LttField *field, void *data);
+
+
+
+#endif // EVENT_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/facility.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/facility.c
new file mode 100644 (file)
index 0000000..f4c0aca
--- /dev/null
@@ -0,0 +1,666 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *               2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h> 
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+
+#include "parser.h"
+#include <ltt/ltt.h>
+#include "ltt-private.h"
+#include <ltt/facility.h>
+
+#ifndef g_open
+#define g_open open
+#endif
+
+#define g_close close
+
+/* search for the (named) type in the table, if it does not exist
+   create a new one */
+LttType * lookup_named_type(LttFacility *fac, type_descriptor_t * td);
+
+/* construct directed acyclic graph for types, and tree for fields */
+void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td, 
+                            LttField * fld);
+
+/* generate the facility according to the events belongin to it */
+void generateFacility(LttFacility * f, facility_t  * fac, 
+                      guint32 checksum);
+
+/* functions to release the memory occupied by a facility */
+void freeFacility(LttFacility * facility);
+void freeEventtype(LttEventType * evType);
+void freeLttType(LttType ** type);
+void freeLttField(LttField * fld);
+void freeLttNamedType(LttType * type);
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_open       : open facilities
+ *Input params
+ *    t                       : the trace containing the facilities
+ *    pathname                : the path name of the facility   
+ *
+ *  Open the facility corresponding to the right checksum.
+ * 
+ *returns 0 on success, 1 on error.
+ ****************************************************************************/
+
+int ltt_facility_open(LttFacility *f, LttTrace * t, gchar * pathname)
+{
+  int ret = 0;
+  gchar *token;
+  parse_file_t in;
+  facility_t * fac;
+  unsigned long checksum;
+  gchar buffer[BUFFER_SIZE];
+  gboolean generated = FALSE;
+
+  in.buffer = &(buffer[0]);
+  in.lineno = 0;
+  in.error = error_callback;
+  in.name = pathname;
+  in.unget = 0;
+
+  in.fp = fopen(in.name, "r");
+  if(in.fp == NULL) {
+    g_warning("cannot open facility description file %s",
+        in.name);
+    ret = 1;
+    goto open_error;
+  }
+
+  while(1){
+    token = getToken(&in);
+    if(in.type == ENDFILE) break;
+    
+    if(g_ascii_strcasecmp(token, "<")) in.error(&in,"not a facility file");
+    token = getName(&in);
+
+    if(g_ascii_strcasecmp("facility",token) == 0) {
+      fac = g_new(facility_t, 1);
+      fac->name = NULL;
+      fac->description = NULL;
+      sequence_init(&(fac->events));
+      table_init(&(fac->named_types));
+      sequence_init(&(fac->unnamed_types));
+      
+      parseFacility(&in, fac);
+
+      //check if any namedType is not defined
+      checkNamedTypesImplemented(&fac->named_types);
+    
+      generateChecksum(fac->name, &checksum, &fac->events);
+  
+      if(checksum == f->checksum) {
+        generateFacility(f, fac, checksum);
+        generated = TRUE;
+      }
+
+      g_free(fac->name);
+      free(fac->capname);
+      g_free(fac->description);
+      freeEvents(&fac->events);
+      sequence_dispose(&fac->events);
+      freeNamedType(&fac->named_types);
+      table_dispose(&fac->named_types);
+      freeTypes(&fac->unnamed_types);
+      sequence_dispose(&fac->unnamed_types);      
+      g_free(fac);
+      if(generated) break; /* use the first good match */
+    }
+    else {
+      g_warning("facility token was expected in file %s", in.name);
+      ret = 1;
+      goto parse_error;
+    }
+  }
+  
+ parse_error:
+  fclose(in.fp);
+open_error:
+
+  if(!generated) {
+    g_warning("Cannot find facility %s, checksum 0x%X",
+        g_quark_to_string(f->name), f->checksum);
+    ret = 1;
+  }
+
+  return ret;
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    generateFacility    : generate facility, internal function
+ *Input params 
+ *    facility            : LttFacilty structure
+ *    fac                 : facility structure
+ *    checksum            : checksum of the facility          
+ ****************************************************************************/
+
+void generateFacility(LttFacility *f, facility_t *fac, guint32 checksum)
+{
+  char * facilityName = fac->name;
+  sequence_t * events = &fac->events;
+  int i;
+  //LttEventType * evType;
+  LttEventType * event_type;
+  LttField * field;
+  LttType * type;
+  
+  g_assert(f->name == g_quark_from_string(facilityName));
+  g_assert(f->checksum == checksum);
+
+  //f->event_number = events->position;
+  
+  //initialize inner structures
+  f->events = g_array_sized_new (FALSE, TRUE, sizeof(LttEventType),
+      events->position);
+  //f->events = g_new(LttEventType*,f->event_number);
+  f->events = g_array_set_size(f->events, events->position);
+
+  g_datalist_init(&f->events_by_name);
+  g_datalist_init(&f->named_types);
+  
+  //f->named_types_number = fac->named_types.keys.position;
+  //f->named_types = g_array_sized_new (FALSE, TRUE, sizeof(LttType),
+  //    fac->named_types.keys.position);
+  //f->named_types = g_new(LttType*, fac->named_types.keys.position);
+  //f->named_types = g_array_set_size(f->named_types, 
+  //    fac->named_types.keys.position);
+
+  //for each event, construct field tree and type graph
+  for(i=0;i<events->position;i++){
+    event_type = &g_array_index(f->events, LttEventType, i);
+    //evType = g_new(LttEventType,1);
+    //f->events[i] = evType;
+
+    event_type->name = 
+      g_quark_from_string(((event_t*)(events->array[i]))->name);
+    
+    g_datalist_id_set_data(&f->events_by_name, event_type->name,
+        event_type);
+    
+    event_type->description =
+      g_strdup(((event_t*)(events->array[i]))->description);
+    
+    field = g_new(LttField, 1);
+    event_type->root_field = field;
+    event_type->facility = f;
+    event_type->index = i;
+
+    if(((event_t*)(events->array[i]))->type != NULL){
+ //     field->field_pos = 0;
+      type = lookup_named_type(f,((event_t*)(events->array[i]))->type);
+      field->field_type = type;
+      field->offset_root = 0;
+      field->fixed_root = FIELD_UNKNOWN;
+      field->offset_parent = 0;
+      field->fixed_parent = FIELD_UNKNOWN;
+      //    field->base_address = NULL;
+      field->field_size  = 0;
+      field->fixed_size = FIELD_UNKNOWN;
+      field->parent = NULL;
+      field->child = NULL;
+      field->current_element = 0;
+
+      //construct field tree and type graph
+      construct_types_and_fields(f,((event_t*)(events->array[i]))->type,field);
+    }else{
+      event_type->root_field = NULL;
+      g_free(field);
+    }
+  }  
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    construct_types_and_fields : construct field tree and type graph,
+ *                             internal recursion function
+ *Input params 
+ *    fac                    : facility struct
+ *    td                     : type descriptor
+ *    root_field             : root field of the event
+ ****************************************************************************/
+
+
+void construct_types_and_fields(LttFacility * fac, type_descriptor_t * td, 
+                            LttField * fld)
+{
+  int i;
+  type_descriptor_t * tmpTd;
+
+  switch(td->type) {
+    case INT:
+    case UINT:
+    case FLOAT:
+      fld->field_type->size = td->size;
+      break;
+    case POINTER:
+    case LONG:
+    case ULONG:
+    case SIZE_T:
+    case SSIZE_T:
+    case OFF_T:
+      fld->field_type->size = 0;
+      break;
+    case STRING:
+      fld->field_type->size = 0;
+      break;
+    case ENUM:
+      fld->field_type->element_number = td->labels.position;
+      fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
+      for(i=0;i<td->labels.position;i++){
+        fld->field_type->enum_strings[i] 
+                       = g_quark_from_string(((char*)(td->labels.array[i])));
+      }
+      fld->field_type->size = td->size;
+      break;
+
+    case ARRAY:
+      fld->field_type->element_number = (unsigned)td->size;
+    case SEQUENCE:
+    fld->field_type->element_type = g_new(LttType*,1);
+    tmpTd = td->nested_type;
+    fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
+    fld->child = g_new(LttField*, 1);
+    fld->child[0] = g_new(LttField, 1);
+    
+    fld->child[0]->field_type = fld->field_type->element_type[0];
+    fld->child[0]->offset_root = 0;
+    fld->child[0]->fixed_root = FIELD_UNKNOWN;
+    fld->child[0]->offset_parent = 0;
+    fld->child[0]->fixed_parent = FIELD_UNKNOWN;
+    fld->child[0]->field_size  = 0;
+    fld->child[0]->fixed_size = FIELD_UNKNOWN;
+    fld->child[0]->parent = fld;
+    fld->child[0]->child = NULL;
+    fld->child[0]->current_element = 0;
+    construct_types_and_fields(fac, tmpTd, fld->child[0]);
+    break;
+
+  case STRUCT:
+  case UNION:
+    fld->field_type->element_number = td->fields.position;
+
+    g_assert(fld->field_type->element_type == NULL);
+    fld->field_type->element_type = g_new(LttType*, td->fields.position);
+
+    fld->child = g_new(LttField*, td->fields.position);      
+    for(i=0;i<td->fields.position;i++){
+      tmpTd = ((field_t*)(td->fields.array[i]))->type;
+
+       fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
+      fld->child[i] = g_new(LttField,1); 
+
+ //     fld->child[i]->field_pos = i;
+      fld->child[i]->field_type = fld->field_type->element_type[i]; 
+
+      fld->child[i]->field_type->element_name 
+                 = g_quark_from_string(((field_t*)(td->fields.array[i]))->name);
+
+      fld->child[i]->offset_root = 0;
+      fld->child[i]->fixed_root = FIELD_UNKNOWN;
+      fld->child[i]->offset_parent = 0;
+      fld->child[i]->fixed_parent = FIELD_UNKNOWN;
+      fld->child[i]->field_size  = 0;
+      fld->child[i]->fixed_size = FIELD_UNKNOWN;
+      fld->child[i]->parent = fld;
+      fld->child[i]->child = NULL;
+      fld->child[i]->current_element = 0;
+      construct_types_and_fields(fac, tmpTd, fld->child[i]);
+    }    
+    break;
+
+  default:
+    g_error("construct_types_and_fields : unknown type");
+  }
+
+
+}
+
+
+
+#if 0
+void construct_types_and_fields(LttFacility * fac, type_descriptor * td, 
+                            LttField * fld)
+{
+  int i, flag;
+  type_descriptor * tmpTd;
+
+  //  if(td->type == LTT_STRING || td->type == LTT_SEQUENCE)
+  //    fld->field_size = 0;
+  //  else fld->field_size = -1;
+
+  if(td->type == LTT_ENUM){
+    fld->field_type->element_number = td->labels.position;
+    fld->field_type->enum_strings = g_new(GQuark,td->labels.position);
+    for(i=0;i<td->labels.position;i++){
+      fld->field_type->enum_strings[i] 
+                     = g_quark_from_string(((char*)(td->labels.array[i])));
+    }
+  }else if(td->type == LTT_ARRAY || td->type == LTT_SEQUENCE){
+    if(td->type == LTT_ARRAY)
+      fld->field_type->element_number = (unsigned)td->size;
+    fld->field_type->element_type = g_new(LttType*,1);
+    tmpTd = td->nested_type;
+    fld->field_type->element_type[0] = lookup_named_type(fac, tmpTd);
+    fld->child = g_new(LttField*, 1);
+    fld->child[0] = g_new(LttField, 1);
+    
+//    fld->child[0]->field_pos = 0;
+    fld->child[0]->field_type = fld->field_type->element_type[0];
+    fld->child[0]->offset_root = fld->offset_root;
+    fld->child[0]->fixed_root = fld->fixed_root;
+    fld->child[0]->offset_parent = 0;
+    fld->child[0]->fixed_parent = 1;
+    //    fld->child[0]->base_address = NULL;
+    fld->child[0]->field_size  = 0;
+    fld->child[0]->field_fixed = -1;
+    fld->child[0]->parent = fld;
+    fld->child[0]->child = NULL;
+    fld->child[0]->current_element = 0;
+    construct_types_and_fields(fac, tmpTd, fld->child[0]);
+  }else if(td->type == LTT_STRUCT){
+    fld->field_type->element_number = td->fields.position;
+
+    if(fld->field_type->element_type == NULL){
+      fld->field_type->element_type = g_new(LttType*, td->fields.position);
+      flag = 1;
+    }else{
+      flag = 0;
+    }
+
+    fld->child = g_new(LttField*, td->fields.position);      
+    for(i=0;i<td->fields.position;i++){
+      tmpTd = ((type_fields*)(td->fields.array[i]))->type;
+
+      if(flag)
+       fld->field_type->element_type[i] = lookup_named_type(fac, tmpTd);
+      fld->child[i] = g_new(LttField,1); 
+
+      fld->child[i]->field_pos = i;
+      fld->child[i]->field_type = fld->field_type->element_type[i]; 
+
+      if(flag){
+       fld->child[i]->field_type->element_name 
+                 = g_quark_from_string(((type_fields*)(td->fields.array[i]))->name);
+      }
+
+      fld->child[i]->offset_root = -1;
+      fld->child[i]->fixed_root = -1;
+      fld->child[i]->offset_parent = -1;
+      fld->child[i]->fixed_parent = -1;
+      //      fld->child[i]->base_address = NULL;
+      fld->child[i]->field_size  = 0;
+      fld->child[i]->field_fixed = -1;
+      fld->child[i]->parent = fld;
+      fld->child[i]->child = NULL;
+      fld->child[i]->current_element = 0;
+      construct_types_and_fields(fac, tmpTd, fld->child[i]);
+    }    
+  }
+}
+#endif //0
+
+/*****************************************************************************
+ *Function name
+ *    lookup_named_type: search named type in the table
+ *                       internal function
+ *Input params 
+ *    fac              : facility struct
+ *    td               : type descriptor
+ *Return value    
+ *                     : either find the named type, or create a new LttType
+ ****************************************************************************/
+
+LttType * lookup_named_type(LttFacility *fac, type_descriptor_t * td)
+{
+  LttType *type = NULL;
+  GQuark name = 0;
+  
+  if(td->type_name != NULL) {
+    /* Named type */
+    name = g_quark_from_string(td->type_name);
+  
+    type = g_datalist_id_get_data(&fac->named_types, name);
+  }
+  
+  if(type == NULL){
+    /* Create the type */
+    type = g_new(LttType,1);
+    type->type_name = name;
+    type->type_class = td->type;
+    if(td->fmt) type->fmt = g_strdup(td->fmt);
+    else type->fmt = NULL;
+    type->size = td->size;
+    type->enum_strings = NULL;
+    type->element_type = NULL;
+    type->element_number = 0;
+    
+    if(td->type_name != NULL)
+      g_datalist_id_set_data_full(&fac->named_types, name,
+                  type, (GDestroyNotify)freeLttNamedType);
+  }
+  return type;
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_close      : close a facility, decrease its usage count,
+ *                              if usage count = 0, release the memory
+ *Input params
+ *    f                       : facility that will be closed
+ ****************************************************************************/
+
+void ltt_facility_close(LttFacility *f)
+{
+  //release the memory it occupied
+  freeFacility(f);
+}
+
+/*****************************************************************************
+ * Functions to release the memory occupied by the facility
+ ****************************************************************************/
+
+void freeFacility(LttFacility * fac)
+{
+  guint i;
+  LttEventType *et;
+
+  for(i=0; i<fac->events->len; i++) {
+    et = &g_array_index (fac->events, LttEventType, i);
+    freeEventtype(et);
+  }
+  g_array_free(fac->events, TRUE);
+
+  g_datalist_clear(&fac->named_types);
+
+}
+
+void freeEventtype(LttEventType * evType)
+{
+  LttType * root_type;
+  if(evType->description)
+    g_free(evType->description); 
+  if(evType->root_field){    
+    root_type = evType->root_field->field_type;
+    freeLttField(evType->root_field);
+    freeLttType(&root_type);
+  }
+}
+
+void freeLttNamedType(LttType * type)
+{
+  freeLttType(&type);
+}
+
+void freeLttType(LttType ** type)
+{
+  unsigned int i;
+  if(*type == NULL) return;
+  if((*type)->type_name != 0) return; //this is a named type.
+  //if((*type)->type_name){
+  //  return; //this is a named type
+  //}
+  if((*type)->fmt)
+    g_free((*type)->fmt);
+  if((*type)->enum_strings){
+    g_free((*type)->enum_strings);
+  }
+
+  if((*type)->element_type){
+    for(i=0;i<(*type)->element_number;i++)
+      freeLttType(&((*type)->element_type[i]));   
+    g_free((*type)->element_type);
+  }
+  g_free(*type);
+  *type = NULL;
+}
+
+void freeLttField(LttField * fld)
+{ 
+  int i;
+  int size = 0;
+  
+  if(fld->field_type){
+    if(fld->field_type->type_class == LTT_ARRAY ||
+       fld->field_type->type_class == LTT_SEQUENCE){
+      size = 1;
+    }else if(fld->field_type->type_class == LTT_STRUCT){
+      size = fld->field_type->element_number;
+    }
+  }
+
+  if(fld->child){
+    for(i=0; i<size; i++){
+      if(fld->child[i])freeLttField(fld->child[i]);
+    }
+    g_free(fld->child);
+  }
+  g_free(fld);
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_name       : obtain the facility's name
+ *Input params
+ *    f                       : the facility
+ *Return value
+ *    GQuark                  : the facility's name
+ ****************************************************************************/
+
+GQuark ltt_facility_name(LttFacility *f)
+{
+  return f->name;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_checksum   : obtain the facility's checksum
+ *Input params
+ *    f                       : the facility
+ *Return value
+ *                            : the checksum of the facility 
+ ****************************************************************************/
+
+guint32 ltt_facility_checksum(LttFacility *f)
+{
+  return f->checksum;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_base_id    : obtain the facility base id
+ *Input params
+ *    f                       : the facility
+ *Return value
+ *                            : the base id of the facility
+ ****************************************************************************/
+
+guint ltt_facility_id(LttFacility *f)
+{
+  return f->id;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_eventtype_number: obtain the number of the event types 
+ *Input params
+ *    f                            : the facility that will be closed
+ *Return value
+ *                                 : the number of the event types 
+ ****************************************************************************/
+
+guint8 ltt_facility_eventtype_number(LttFacility *f)
+{
+  return (f->events->len);
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_eventtype_get: obtain the event type according to event id
+ *                                from 0 to event_number - 1
+ *Input params
+ *    f                         : the facility that will be closed
+ *Return value
+ *    LttEventType *           : the event type required  
+ ****************************************************************************/
+
+LttEventType *ltt_facility_eventtype_get(LttFacility *f, guint8 i)
+{
+  if(!f->exists) return NULL;
+
+  g_assert(i < f->events->len);
+  return &g_array_index(f->events, LttEventType, i);
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_facility_eventtype_get_by_name
+ *                     : obtain the event type according to event name
+ *                       event name is unique in the facility
+ *Input params
+ *    f                : the facility
+ *    name             : the name of the event
+ *Return value
+ *    LttEventType *  : the event type required  
+ ****************************************************************************/
+
+LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, GQuark name)
+{
+  LttEventType *et = g_datalist_id_get_data(&f->events_by_name, name);
+  return et;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/facility.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/facility.h
new file mode 100644 (file)
index 0000000..173fd14
--- /dev/null
@@ -0,0 +1,51 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FACILITY_H
+#define FACILITY_H
+
+#include <ltt/ltt.h>
+
+/* Facilities are obtained from an opened trace. The structures associated 
+   with a facility are released when the trace is closed. Each facility
+   is characterized by its name and checksum. */
+
+GQuark ltt_facility_name(LttFacility *f);
+
+guint32 ltt_facility_checksum(LttFacility *f);
+
+/* open facility */
+int ltt_facility_open(LttFacility *f, LttTrace * t, gchar * pathname);
+
+/* Discover the event types within the facility. The event type integer id
+   relative to the trace is from 0 to nb_event_types - 1. The event
+   type id within the trace is the relative id + the facility base event
+   id. */
+
+unsigned ltt_facility_base_id(LttFacility *f);
+
+guint8 ltt_facility_eventtype_number(LttFacility *f);
+
+LttEventType *ltt_facility_eventtype_get(LttFacility *f, guint8 i);
+
+LttEventType *ltt_facility_eventtype_get_by_name(LttFacility *f, GQuark name);
+
+void ltt_facility_close(LttFacility *f);
+
+#endif // FACILITY_H
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt-private.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt-private.h
new file mode 100644 (file)
index 0000000..666f1f3
--- /dev/null
@@ -0,0 +1,457 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef LTT_PRIVATE_H
+#define LTT_PRIVATE_H
+
+#include <glib.h>
+#include <sys/types.h>
+#include <ltt/ltt.h>
+#include <endian.h>
+
+
+#ifndef max
+#define max(a,b) ((a)>(b)?(a):(b))
+#endif
+
+
+#define LTT_MAGIC_NUMBER 0x00D6B7ED
+#define LTT_REV_MAGIC_NUMBER 0xEDB7D600
+
+#define NSEC_PER_USEC 1000
+
+#define LTT_PACKED_STRUCT __attribute__ ((packed))
+
+/* Hardcoded facilities */
+#define LTT_FACILITY_CORE 0
+/* Byte ordering */
+#define LTT_GET_BO(t) ((t)->reverse_bo)
+
+#define LTT_HAS_FLOAT(t) ((t)->float_word_order!=0)
+#define LTT_GET_FLOAT_BO(t) \
+  (((t)->float_word_order==__BYTE_ORDER)?0:1)
+
+/* Hardcoded core events */
+enum ltt_core_events {
+    LTT_EVENT_FACILITY_LOAD,
+    LTT_EVENT_FACILITY_UNLOAD,
+    LTT_EVENT_HEARTBEAT,
+    LTT_EVENT_STATE_DUMP_FACILITY_LOAD
+};
+
+
+#if 0
+/* enumeration definition */
+
+typedef enum _BuildinEvent{
+  TRACE_FACILITY_LOAD = 0,
+  TRACE_BLOCK_START   = 17,
+  TRACE_BLOCK_END     = 18,
+  TRACE_TIME_HEARTBEAT= 19
+} BuildinEvent;
+
+
+/* structure definition */
+
+typedef struct _FacilityLoad{
+  gchar * name;
+  LttChecksum checksum;
+  guint32     base_code;
+} LTT_PACKED_STRUCT FacilityLoad;
+
+typedef struct _BlockStart {
+  LttTime       time;       //Time stamp of this block
+  LttCycleCount cycle_count; //cycle count of the event
+  guint32       block_id;    //block id 
+} LTT_PACKED_STRUCT BlockStart;
+
+typedef struct _BlockEnd {
+  LttTime       time;       //Time stamp of this block
+  LttCycleCount cycle_count; //cycle count of the event
+  guint32       block_id;    //block id 
+} LTT_PACKED_STRUCT BlockEnd;
+#endif //0
+
+
+typedef guint8 uint8_t;
+typedef guint16 uint16_t;
+typedef guint32 uint32_t;
+typedef guint64 uint64_t;
+
+/* Hardcoded facility load event : this plus an preceding "name" string */
+struct LttFacilityLoad {
+  guint32 checksum;
+  guint32 id;
+  guint32 long_size;
+  guint32 pointer_size;
+  guint32 size_t_size;
+  guint32 alignment;
+} LTT_PACKED_STRUCT;
+
+struct LttFacilityUnload {
+  guint32 id;
+} LTT_PACKED_STRUCT;
+
+struct LttStateDumpFacilityLoad {
+  guint32 checksum;
+  guint32 id;
+  guint32 long_size;
+  guint32 pointer_size;
+  guint32 size_t_size;
+  guint32 alignment;
+} LTT_PACKED_STRUCT;
+
+typedef struct _TimeHeartbeat {
+  LttTime       time;       //Time stamp of this block
+  uint64_t cycle_count; //cycle count of the event
+} LTT_PACKED_STRUCT TimeHeartbeat;
+
+struct ltt_event_header_hb {
+  uint32_t      timestamp;
+  unsigned char  facility_id;
+  unsigned char event_id;
+  uint16_t      event_size;
+} LTT_PACKED_STRUCT;
+
+struct ltt_event_header_nohb {
+  uint64_t      timestamp;
+  unsigned char  facility_id;
+  unsigned char event_id;
+  uint16_t      event_size;
+} LTT_PACKED_STRUCT;
+
+
+/* Block and trace headers */
+
+struct ltt_trace_header_any {
+  uint32_t        magic_number;
+  uint32_t        arch_type;
+  uint32_t        arch_variant;
+  uint32_t        float_word_order;
+  uint8_t         arch_size;
+  uint8_t         major_version;
+  uint8_t         minor_version;
+  uint8_t         flight_recorder;
+  uint8_t         has_heartbeat;
+  uint8_t         has_alignment;  /* Event header alignment */
+       uint8_t                     has_tsc;
+} LTT_PACKED_STRUCT;
+
+
+/* For version 0.3 */
+
+struct ltt_trace_header_0_3 {
+  uint32_t        magic_number;
+  uint32_t        arch_type;
+  uint32_t        arch_variant;
+  uint32_t        float_word_order;
+  uint8_t         arch_size;
+  uint8_t         major_version;
+  uint8_t         minor_version;
+  uint8_t         flight_recorder;
+  uint8_t         has_heartbeat;
+  uint8_t         has_alignment;  /* Event header alignment */
+       uint8_t                          has_tsc;
+} LTT_PACKED_STRUCT;
+
+/* For version 0.4 */
+
+struct ltt_trace_header_0_4 {
+  uint32_t        magic_number;
+  uint32_t        arch_type;
+  uint32_t        arch_variant;
+  uint32_t        float_word_order;
+  uint8_t         arch_size;
+  uint8_t         major_version;
+  uint8_t         minor_version;
+  uint8_t         flight_recorder;
+  uint8_t         has_heartbeat;
+  uint8_t         has_alignment;  /* Event header alignment */
+       uint8_t         has_tsc;
+  uint64_t        start_freq;
+  uint64_t        start_tsc;
+  uint64_t        start_monotonic;
+  struct timespec start_time;
+} LTT_PACKED_STRUCT;
+
+
+struct ltt_block_start_header {
+  struct { 
+    struct timeval          timestamp;
+    uint64_t                cycle_count;
+    uint64_t                freq;
+  } begin;
+  struct {
+    struct timeval          timestamp;
+    uint64_t                cycle_count;
+    uint64_t                freq;
+  } end;
+  uint32_t                lost_size;  /* Size unused at the end of the buffer */
+  uint32_t                buf_size;   /* The size of this sub-buffer */
+  struct ltt_trace_header_any trace[0];
+} LTT_PACKED_STRUCT;
+
+
+struct _LttType{
+  GQuark type_name;                //type name if it is a named type
+  GQuark element_name;             //elements name of the struct
+  gchar * fmt;
+  unsigned int size;
+  LttTypeEnum type_class;          //which type
+  GQuark * enum_strings;            //for enum labels
+  struct _LttType ** element_type; //for array, sequence and struct
+  unsigned element_number;         //the number of elements 
+                                   //for enum, array, sequence and structure
+};
+
+struct _LttEventType{
+  GQuark name;
+  gchar * description;
+  guint index;              //id of the event type within the facility
+  LttFacility * facility; //the facility that contains the event type
+  LttField * root_field;  //root field
+};
+
+/* Structure LttEvent and LttEventPosition must begin with the _exact_ same
+ * fields in the exact same order. LttEventPosition is a parent of LttEvent. */
+struct _LttEvent{
+  
+  /* Begin of LttEventPosition fields */
+  LttTracefile  *tracefile;
+  unsigned int  block;
+  unsigned int  offset;
+
+  /* Timekeeping */
+  uint64_t                tsc;       /* Current timestamp counter */
+  
+  /* End of LttEventPosition fields */
+
+       union {                                                                                 /* choice by trace has_tsc */
+         guint32  timestamp;                           /* truncated timestamp */
+       LttTime  delta;
+       } time;
+
+  unsigned char facility_id;   /* facility ID are never reused. */
+  unsigned char event_id;
+
+  LttTime event_time;
+
+  void * data;               //event data
+  guint  data_size;
+  guint  event_size;         //event_size field of the header : 
+                             //used to verify data_size from facility.
+
+  int      count;                    //the number of overflow of cycle count
+  gint64 overflow_nsec;              //precalculated nsec for overflows
+};
+
+struct _LttEventPosition{
+  LttTracefile  *tracefile;
+  unsigned int  block;
+  unsigned int  offset;
+  
+  /* Timekeeping */
+  uint64_t                tsc;       /* Current timestamp counter */
+};
+
+
+enum field_status { FIELD_UNKNOWN, FIELD_VARIABLE, FIELD_FIXED };
+
+struct _LttField{
+  //guint field_pos;           //field position within its parent
+  LttType * field_type;      //field type, if it is root field
+                             //then it must be struct type
+
+  off_t offset_root;         //offset from the root, -1:uninitialized 
+  enum field_status fixed_root;          //offset fixed according to the root
+                             //-1:uninitialized, 0:unfixed, 1:fixed
+  off_t offset_parent;       //offset from the parent,-1:uninitialized
+  enum field_status fixed_parent;        //offset fixed according to its parent
+                             //-1:uninitialized, 0:unfixed, 1:fixed
+  //  void * base_address;       //base address of the field  ????
+  
+  guint field_size;     //      //>0: size of the field, 
+                          //   //0 : uncertain
+                           //  //-1: uninitialize
+  enum field_status fixed_size;
+
+  /* for sequence */
+  gint sequ_number_size;      //the size of unsigned used to save the
+                             //number of elements in the sequence
+
+  gint element_size;          //the element size of the sequence
+  //int field_fixed;           //0: field has string or sequence
+                             //1: field has no string or sequenc
+                             //-1: uninitialize
+
+  struct _LttField * parent;
+  struct _LttField ** child; //for array, sequence, struct and union: 
+                             //list of fields, it may have only one
+                             //field if the element is not a struct or
+                             //union
+  unsigned current_element;  //which element is currently processed
+                             // Used for sequences and arrays.
+};
+
+
+struct _LttFacility{
+  LttTrace  *trace;
+  //gchar * name;               //facility name 
+  GQuark name;
+  guint32 checksum;      //checksum of the facility 
+  guint32  id;          //id of the facility
+  guint32 pointer_size;
+  guint32 long_size;
+  guint32 size_t_size;
+  guint32 alignment;
+
+
+  //LttEventType ** events;    //array of event types 
+  //unsigned int event_number;          //number of events in the facility 
+  //LttType ** named_types;
+  //unsigned int named_types_number;
+
+  GArray *events;
+  GData *events_by_name;
+ // GArray *named_types;
+  //GData *named_types_by_name;
+  GData *named_types;
+  
+  unsigned char exists; /* 0 does not exist, 1 exists */
+};
+
+typedef struct _LttBuffer {
+  void * head;
+  unsigned int index;
+
+  struct {
+    LttTime                 timestamp;
+    uint64_t                cycle_count;
+    uint64_t                freq; /* Frequency in khz */
+  } begin;
+  struct {
+    LttTime                 timestamp;
+    uint64_t                cycle_count;
+    uint64_t                freq; /* Frequency in khz */
+  } end;
+  uint32_t                lost_size; /* Size unused at the end of the buffer */
+
+  /* Timekeeping */
+  uint64_t                tsc;       /* Current timestamp counter */
+  uint64_t                freq; /* Frequency in khz */
+  //double                  nsecs_per_cycle;  /* Precalculated from freq */
+  guint32                 cyc2ns_scale;
+} LttBuffer;
+
+struct _LttTracefile{
+  gboolean cpu_online;               //is the cpu online ?
+  GQuark long_name;                  //tracefile complete filename
+  GQuark name;                       //tracefile name
+  guint cpu_num;                     //cpu number of the tracefile
+  LttTrace * trace;                  //trace containing the tracefile
+  int fd;                            //file descriptor 
+  off_t file_size;                   //file size
+  //unsigned block_size;               //block_size
+  unsigned int num_blocks;           //number of blocks in the file
+  gboolean  reverse_bo;              //must we reverse byte order ?
+  gboolean  float_word_order;        //what is the byte order of floats ?
+
+  size_t    buffer_header_size;
+
+       /* Current event */
+  LttEvent event;                    //Event currently accessible in the trace
+
+       /* Current block */
+  LttBuffer buffer;                  //current buffer
+  guint32 buf_size;                  /* The size of blocks */
+
+       /* Time flow */
+  //unsigned int      count;           //the number of overflow of cycle count
+  //double nsec_per_cycle;             //Nsec per cycle
+  //TimeHeartbeat * last_heartbeat;    //last heartbeat
+
+  //LttCycleCount cycles_per_nsec_reciprocal; // Optimisation for speed
+  //void * last_event_pos;
+
+  //LttTime prev_block_end_time;       //the end time of previous block
+  //LttTime prev_event_time;           //the time of the previous event
+  //LttCycleCount pre_cycle_count;     //previous cycle count of the event
+};
+
+struct _LttTrace{
+  GQuark pathname;                          //the pathname of the trace
+  //LttSystemDescription * system_description;//system description 
+
+  GArray *facilities_by_num;            /* fac_id as index in array */
+  GData *facilities_by_name;            /* fac name (GQuark) as index */
+                                        /* Points to array of fac_id of all the
+                                        * facilities that has this name. */
+  guint     num_cpu;
+
+  guint32   arch_type;
+  guint32   arch_variant;
+  guint8    arch_size;
+  guint8    ltt_major_version;
+  guint8    ltt_minor_version;
+  guint8    flight_recorder;
+  guint8    has_heartbeat;
+  guint8    has_alignment;
+       guint8          has_tsc;
+  uint64_t  start_freq;
+  uint64_t  start_tsc;
+  uint64_t  start_monotonic;
+  LttTime   start_time;
+  LttTime   start_time_from_tsc;
+
+  GData     *tracefiles;                    //tracefiles groups
+};
+
+/* The characteristics of the system on which the trace was obtained
+   is described in a LttSystemDescription structure. */
+
+struct _LttSystemDescription {
+  gchar *description;
+  gchar *node_name;
+  gchar *domain_name;
+  unsigned nb_cpu;
+  LttArchSize size;
+  LttArchEndian endian;
+  gchar *kernel_name;
+  gchar *kernel_release;
+  gchar *kernel_version;
+  gchar *machine;
+  gchar *processor;
+  gchar *hardware_platform;
+  gchar *operating_system;
+  LttTime trace_start;
+  LttTime trace_end;
+};
+
+/*****************************************************************************
+ macro for size of some data types
+ *****************************************************************************/
+// alignment -> dynamic!
+
+//#define TIMESTAMP_SIZE    sizeof(guint32)
+//#define EVENT_ID_SIZE     sizeof(guint16)
+//#define EVENT_HEADER_SIZE (TIMESTAMP_SIZE + EVENT_ID_SIZE)
+
+
+#endif /* LTT_PRIVATE_H */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt-types.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt-types.h
new file mode 100644 (file)
index 0000000..1076b8a
--- /dev/null
@@ -0,0 +1,91 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2004-2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef LTT_TYPES_H
+#define LTT_TYPES_H
+
+/* Set of functions to access the types portably, given the trace as parameter.
+ * */
+
+#include <ltt/ltt.h>
+//#include <ltt/ltt-private.h>
+#include <glib.h>
+#include <ltt/time.h>
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_get_int64        : get a 64 bits integer number
+ *Input params 
+ *    ptr                  : pointer to the integer
+ *Return value
+ *    gint64               : a 64 bits integer
+ *
+ * Takes care of endianness
+ *
+ ****************************************************************************/
+
+static inline gint64 ltt_get_int64(gboolean reverse_byte_order, void *ptr)
+{
+  guint64 value = *(guint64*)ptr;
+  return (gint64) (reverse_byte_order ? GUINT64_SWAP_LE_BE(value): value);
+}
+
+
+static inline guint64 ltt_get_uint64(gboolean reverse_byte_order, void *ptr)
+{
+  guint64 value = *(guint64*)ptr;
+  return (guint64) (reverse_byte_order ? GUINT64_SWAP_LE_BE(value): value);
+}
+
+static inline gint32 ltt_get_int32(gboolean reverse_byte_order, void *ptr)
+{
+  guint32 value = *(guint32*)ptr;
+  return (gint32) (reverse_byte_order ? GUINT32_SWAP_LE_BE(value): value);
+}
+
+static inline guint32 ltt_get_uint32(gboolean reverse_byte_order, void *ptr)
+{
+  guint32 value = *(guint32*)ptr;
+  return (guint32) (reverse_byte_order ? GUINT32_SWAP_LE_BE(value): value);
+}
+
+static inline gint16 ltt_get_int16(gboolean reverse_byte_order, void *ptr)
+{
+  guint16 value = *(guint16*)ptr;
+  return (gint16) (reverse_byte_order ? GUINT16_SWAP_LE_BE(value): value);
+}
+
+static inline guint16 ltt_get_uint16(gboolean reverse_byte_order, void *ptr)
+{
+  guint16 value = *(guint16*)ptr;
+  return (guint16) (reverse_byte_order ? GUINT16_SWAP_LE_BE(value): value);
+}
+
+static inline LttTime ltt_get_time(gboolean reverse_byte_order, void *ptr)
+{
+  LttTime output;
+
+  output.tv_sec = ltt_get_uint32(reverse_byte_order, ptr);
+  ptr += sizeof(guint32);
+  output.tv_nsec = ltt_get_uint32(reverse_byte_order, ptr);
+
+  return output;
+}
+
+#endif // LTT_TYPES_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/ltt.h
new file mode 100644 (file)
index 0000000..02d937c
--- /dev/null
@@ -0,0 +1,140 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LTT_H
+#define LTT_H
+
+#include <glib.h>
+#include <ltt/time.h>
+#include <ltt/compiler.h>
+
+/* A trace is associated with a tracing session run on a single, possibly
+   multi-cpu, system. It is defined as a pathname to a directory containing
+   all the relevant trace files. All the tracefiles for a trace were 
+   generated in a single system for the same time period by the same 
+   trace daemon. They simply contain different events. Typically control
+   tracefiles contain the important events (process creations and registering 
+   tracing facilities) for all CPUs, and one file for each CPU contains all 
+   the events for that CPU. All the tracefiles within the same trace directory
+   then use the exact same id numbers for event types.
+
+   A tracefile (LttTracefile) contains a list of events (LttEvent) sorted
+   by time for each CPU; events from different CPUs may be slightly out of
+   order, especially using the (possibly drifting) cycle counters as 
+   time unit.
+
+   A facility is a list of event types (LttEventType), declared in a special 
+   eventdefs file. A corresponding checksum differentiates different 
+   facilities which would have the same name but a different content 
+   (e.g., different versions). The files are stored within the trace 
+   directory and are accessed automatically upon opening a trace.
+   The list of facilities (and associated checksum) used in a trace 
+   must be known in order to properly decode the contained events. An event
+   is stored in the "facilities" control tracefile to denote each different 
+   facility used. 
+
+   Event types (LttEventType) refer to data types (LttType) describing
+   their content. The data types supported are integer and unsigned integer 
+   (of various length), enumerations (a special form of unsigned integer), 
+   floating point (of various length), fixed size arrays, sequence 
+   (variable sized arrays), structures and null terminated strings. 
+   The elements of arrays and sequences, and the data members for 
+   structures, may be of any nested data type (LttType).
+
+   An LttField is a special object to denote a specific, possibly nested,
+   field within an event type. Suppose an event type socket_connect is a 
+   structure containing two data members, source and destination, of type 
+   socket_address. Type socket_address contains two unsigned integer 
+   data members, ip and port. An LttField is different from a data type 
+   structure member since it can denote a specific nested field, like the 
+   source port, and store associated access information (byte offset within 
+   the event data). The LttField objects are trace specific since the
+   contained information (byte offsets) may vary with the architecture
+   associated to the trace. */
+   
+#define NUM_FACILITIES 256
+#define FACILITIES_BITS 8
+#define AVG_EVENTS_PER_FACILITIES 10
+
+typedef struct _LttTrace LttTrace;
+
+typedef struct _LttTracefile LttTracefile;
+
+typedef struct _LttFacility LttFacility;
+
+typedef struct _LttEventType LttEventType;
+
+typedef struct _LttType LttType;
+
+typedef struct _LttField LttField;
+
+typedef struct _LttEvent LttEvent;
+
+typedef struct _LttSystemDescription LttSystemDescription;
+
+
+/* Checksums are used to differentiate facilities which have the same name
+   but differ. */
+
+//typedef guint32 LttChecksum;
+
+
+/* Events are usually stored with the easily obtained CPU clock cycle count,
+   ltt_cycle_count. This can be converted to the real time value, LttTime,
+   using linear interpolation between regularly sampled values (e.g. a few 
+   times per second) of the real time clock with their corresponding 
+   cycle count values. */
+
+
+typedef struct _TimeInterval{
+  LttTime start_time;
+  LttTime end_time;  
+} TimeInterval;
+
+
+typedef guint64 LttCycleCount;
+
+
+/* Event positions are used to seek within a tracefile based on
+   the block number and event position within the block. */
+
+typedef struct _LttEventPosition LttEventPosition;
+
+
+/* Differences between architectures include word sizes, endianess,
+   alignment, floating point format and calling conventions. For a
+   packed binary trace, endianess and size matter, assuming that the
+   floating point format is standard (and is seldom used anyway). */
+
+typedef enum _LttArchSize 
+{ LTT_LP32, LTT_ILP32, LTT_LP64, LTT_ILP64, LTT_UNKNOWN 
+} LttArchSize;
+
+
+typedef enum _LttArchEndian
+{ LTT_LITTLE_ENDIAN, LTT_BIG_ENDIAN
+} LttArchEndian;
+
+typedef enum _LttTypeEnum 
+{ LTT_INT, LTT_UINT, LTT_POINTER, LTT_LONG, LTT_ULONG, LTT_SIZE_T, 
+  LTT_SSIZE_T, LTT_OFF_T, LTT_FLOAT, LTT_STRING, LTT_ENUM, LTT_ARRAY, 
+  LTT_SEQUENCE, LTT_STRUCT, LTT_UNION
+} LttTypeEnum;
+
+
+#endif // LTT_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/parser.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/parser.c
new file mode 100644 (file)
index 0000000..795b3f9
--- /dev/null
@@ -0,0 +1,1407 @@
+/*
+
+parser.c: Generate helper declarations and functions to trace events
+  from an event description file.
+
+Copyright (C) 2002, Xianxiu Yang
+Copyright (C) 2002, Michel Dagenais 
+This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+/* This program reads the ".xml" event definitions input files 
+   and constructs structure for each event.
+   The program uses a very simple tokenizer, called from a hand written
+   recursive descent parser to fill a data structure describing the events.
+   The result is a sequence of events definitions which refer to type
+   definitions.
+
+   A table of named types is maintained to allow refering to types by name
+   when the same type is used at several places. Finally a sequence of
+   all types is maintained to facilitate the freeing of all type 
+   information when the processing of an ".xml" file is finished. */
+
+#include <stdlib.h> 
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <linux/errno.h>  
+#include <assert.h>
+#include <ctype.h>
+
+#include "parser.h"
+
+
+static char *intOutputTypes[] = {
+  "int8_t", "int16_t", "int32_t", "int64_t", "short int", "int", "long int" };
+
+static char *uintOutputTypes[] = {
+  "uint8_t", "uint16_t", "uint32_t", "uint64_t", "unsigned short int", 
+  "unsigned int", "unsigned long int" };
+
+static char *floatOutputTypes[] = {
+  "undef", "undef", "float", "double", "undef", "float", "double" };
+
+
+
+
+/* helper function  */
+void strupper(char *string)
+{
+  char *ptr = string;
+  
+  while(*ptr != '\0') {
+    *ptr = toupper(*ptr);
+               ptr++;
+  }
+}
+
+
+int getSizeindex(int value)
+{ 
+  switch(value) {
+    case 1:
+      return 0;
+    case 2:
+      return 1;
+    case 4:
+      return 2;
+    case 8:
+      return 3;
+    default:
+      printf("Error : unknown value size %d\n", value);
+      exit(-1);
+  }
+}
+
+/*****************************************************************************
+ *Function name
+ *    getSize    : translate from string to integer
+ *Input params 
+ *    in         : input file handle
+ *Return values  
+ *    size                           
+ *****************************************************************************/
+
+int getSize(parse_file_t *in)
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type == NUMBER) {
+    if(strcmp(token,"1") == 0) return 0;
+    else if(strcmp(token,"2") == 0) return 1;
+    else if(strcmp(token,"4") == 0) return 2;
+    else if(strcmp(token,"8") == 0) return 3;
+  }
+  else if(in->type == NAME) {
+    if(strcmp(token,"short") == 0) return 4;
+    else if(strcmp(token,"medium") == 0) return 5;
+    else if(strcmp(token,"long") == 0) return 6;
+  }
+  in->error(in,"incorrect size specification");
+  return -1;
+}
+
+/*****************************************************************************
+ *Function name
+ *    error_callback  : print out error info
+ *Input params
+ *    in              : input file handle
+ *    msg             : message to be printed                  
+ ****************************************************************************/
+
+void error_callback(parse_file_t *in, char *msg)
+{
+  if(in)
+    printf("Error in file %s, line %d: %s\n", in->name, in->lineno, msg);
+  else
+    printf("%s\n",msg);
+  assert(0);
+  exit(1);
+}
+
+/*****************************************************************************
+ *Function name
+ *    memAlloc  : allocate memory                    
+ *Input params 
+ *    size      : required memory size               
+ *return value 
+ *    void *    : pointer to allocate memory or NULL 
+ ****************************************************************************/
+
+void * memAlloc(int size)
+{
+  void * addr;
+  if(size == 0) return NULL;
+  addr = malloc(size);
+  if(!addr){
+    printf("Failed to allocate memory");    
+    exit(1);
+  }
+  return addr;   
+}
+
+/*****************************************************************************
+ *Function name
+ *    allocAndCopy : allocate memory and initialize it  
+ *Input params 
+ *    str          : string to be put in memory         
+ *return value 
+ *    char *       : pointer to allocate memory or NULL
+ ****************************************************************************/
+
+char *allocAndCopy(char *str)
+{
+  char * addr;
+  if(str == NULL) return NULL;
+  addr = (char *)memAlloc(strlen(str)+1);
+  strcpy(addr,str);
+  return addr;
+}
+
+/**************************************************************************
+ * Function :
+ *    getTypeAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    t , the type descriptor to fill.
+ *
+ **************************************************************************/
+
+void getTypeAttributes(parse_file_t *in, type_descriptor_t *t)
+{
+  char * token;
+
+  t->fmt = NULL;
+  t->size = -1;
+  t->alignment = 0;
+  
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+    
+    if(!strcmp("format",token)) {
+      getEqual(in);
+      t->fmt = allocAndCopy(getQuotedString(in));
+    //} else if(!strcmp("name",token)) {
+     // getEqual(in);
+     // car = seekNextChar(in);
+     // if(car == EOF) in->error(in,"name was expected");
+     // else if(car == '\"') t->type_name = allocAndCopy(getQuotedString(in));
+     // else t->type_name = allocAndCopy(getName(in));
+    } else if(!strcmp("size",token)) {
+      getEqual(in);
+      t->size = getSize(in);
+    } else if(!strcmp("align",token)) {
+      getEqual(in);
+      t->alignment = getNumber(in);
+    }
+  }
+}
+
+/**************************************************************************
+ * Function :
+ *    getEventAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    ev , the event to fill.
+ *
+ **************************************************************************/
+
+void getEventAttributes(parse_file_t *in, event_t *ev)
+{
+  char * token;
+  char car;
+  
+  ev->name = NULL;
+  ev->per_trace = 0;
+  ev->per_tracefile = 0;
+
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') ev->name = allocAndCopy(getQuotedString(in));
+      else ev->name = allocAndCopy(getName(in));
+    } else if(!strcmp("per_trace", token)) {
+      ev->per_trace = 1;
+    } else if(!strcmp("per_tracefile", token)) {
+      ev->per_tracefile = 1;
+    }
+
+  }
+}
+
+/**************************************************************************
+ * Function :
+ *    getFacilityAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    fac , the facility to fill.
+ *
+ **************************************************************************/
+
+void getFacilityAttributes(parse_file_t *in, facility_t *fac)
+{
+  char * token;
+  char car;
+  
+  fac->name = NULL;
+
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') fac->name = allocAndCopy(getQuotedString(in));
+      else fac->name = allocAndCopy(getName(in));
+    }
+  }
+}
+
+/**************************************************************************
+ * Function :
+ *    getFieldAttributes
+ * Description :
+ *    Read the attribute from the input file.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *    f , the field to fill.
+ *
+ **************************************************************************/
+
+void getFieldAttributes(parse_file_t *in, field_t *f)
+{
+  char * token;
+  char car;
+
+  f->name = NULL;
+
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') f->name = allocAndCopy(getQuotedString(in));
+      else f->name = allocAndCopy(getName(in));
+    }
+  }
+}
+
+char *getNameAttribute(parse_file_t *in)
+{
+  char * token;
+  char *name = NULL;
+  char car;
+  
+  while(1) {
+    token = getToken(in); 
+    if(strcmp("/",token) == 0 || strcmp(">",token) == 0){
+      ungetToken(in);
+      break;
+    }
+
+    if(!strcmp("name",token)) {
+      getEqual(in);
+      car = seekNextChar(in);
+      if(car == EOF) in->error(in,"name was expected");
+      else if(car == '\"') name = allocAndCopy(getQuotedString(in));
+      else name = allocAndCopy(getName(in));
+    }
+  }
+  if(name == NULL) in->error(in, "Name was expected");
+  return name;
+  
+}
+
+
+
+//for <label name=label_name value=n format="..."/>, value is an option
+char * getValueStrAttribute(parse_file_t *in)
+{
+  char * token;
+
+  token = getToken(in); 
+  if(strcmp("/",token) == 0){
+    ungetToken(in);
+    return NULL;
+  }
+  
+  if(strcmp("value",token))in->error(in,"value was expected");
+  getEqual(in);
+  token = getToken(in);
+  if(in->type != NUMBER) in->error(in,"number was expected");
+  return token;  
+}
+
+char * getDescription(parse_file_t *in)
+{
+  long int pos;
+  char * token, car, *str;
+
+  pos = ftell(in->fp);
+
+  getLAnglebracket(in);
+  token = getName(in);
+  if(strcmp("description",token)){
+    fseek(in->fp, pos, SEEK_SET);
+    return NULL;
+  }
+  
+  getRAnglebracket(in);
+
+  pos = 0;
+  while((car = getc(in->fp)) != EOF) {
+    if(car == '<') break;
+    if(car == '\0') continue;
+    in->buffer[pos] = car;
+    pos++;
+  }
+  if(car == EOF)in->error(in,"not a valid description");
+  in->buffer[pos] = '\0';
+
+  str = allocAndCopy(in->buffer);
+
+  getForwardslash(in);
+  token = getName(in);
+  if(strcmp("description", token))in->error(in,"not a valid description");
+  getRAnglebracket(in);
+
+  return str;
+}
+
+/*****************************************************************************
+ *Function name
+ *    parseFacility : generate event list  
+ *Input params 
+ *    in            : input file handle          
+ *    fac           : empty facility
+ *Output params
+ *    fac           : facility filled with event list
+ ****************************************************************************/
+
+void parseFacility(parse_file_t *in, facility_t * fac)
+{
+  char * token;
+  event_t *ev;
+  
+  getFacilityAttributes(in, fac);
+  if(fac->name == NULL) in->error(in, "Attribute not named");
+
+  fac->capname = allocAndCopy(fac->name);
+       strupper(fac->capname);
+  getRAnglebracket(in);    
+  
+  fac->description = getDescription(in);
+  
+  while(1){
+    getLAnglebracket(in);    
+
+    token = getToken(in);
+    if(in->type == ENDFILE)
+      in->error(in,"the definition of the facility is not finished");
+
+    if(strcmp("event",token) == 0){
+      ev = (event_t*) memAlloc(sizeof(event_t));
+      sequence_push(&(fac->events),ev);
+      parseEvent(in,ev, &(fac->unnamed_types), &(fac->named_types));    
+    }else if(strcmp("type",token) == 0){
+      parseTypeDefinition(in, &(fac->unnamed_types), &(fac->named_types));
+    }else if(in->type == FORWARDSLASH){
+      break;
+    }else in->error(in,"event or type token expected\n");
+  }
+
+  token = getName(in);
+  if(strcmp("facility",token)) in->error(in,"not the end of the facility");
+  getRAnglebracket(in); //</facility>
+}
+
+/*****************************************************************************
+ *Function name
+ *    parseEvent    : generate event from event definition 
+ *Input params 
+ *    in            : input file handle          
+ *    ev            : new event                              
+ *    unnamed_types : array of unamed types
+ *    named_types   : array of named types
+ *Output params    
+ *    ev            : new event (parameters are passed to it)   
+ ****************************************************************************/
+
+void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types, 
+               table_t * named_types) 
+{
+  char *token;
+
+  //<event name=eventtype_name>
+  getEventAttributes(in, ev);
+  if(ev->name == NULL) in->error(in, "Event not named");
+  getRAnglebracket(in);  
+
+  //<description>...</descriptio>
+  ev->description = getDescription(in); 
+  
+  //event can have STRUCT, TYPEREF or NOTHING
+  getLAnglebracket(in);
+
+  token = getToken(in);
+  if(in->type == FORWARDSLASH){ //</event> NOTHING
+    ev->type = NULL;
+  }else if(in->type == NAME){
+    if(strcmp("struct",token)==0 || strcmp("typeref",token)==0){
+      ungetToken(in);
+      ev->type = parseType(in,NULL, unnamed_types, named_types);
+      if(ev->type->type != STRUCT && ev->type->type != NONE) 
+       in->error(in,"type must be a struct");     
+    }else in->error(in, "not a valid type");
+
+    getLAnglebracket(in);
+    getForwardslash(in);    
+  }else in->error(in,"not a struct type");
+
+  token = getName(in);
+  if(strcmp("event",token))in->error(in,"not an event definition");
+  getRAnglebracket(in);  //</event>
+}
+
+/*****************************************************************************
+ *Function name
+ *    parseField    : get field infomation from buffer 
+ *Input params 
+ *    in            : input file handle
+ *    t             : type descriptor
+ *    unnamed_types : array of unamed types
+ *    named_types   : array of named types
+ ****************************************************************************/
+
+void parseFields(parse_file_t *in, type_descriptor_t *t,
+    sequence_t * unnamed_types,
+               table_t * named_types) 
+{
+  char * token;
+  field_t *f;
+
+  f = (field_t *)memAlloc(sizeof(field_t));
+  sequence_push(&(t->fields),f);
+
+  //<field name=field_name> <description> <type> </field>
+  getFieldAttributes(in, f);
+  if(f->name == NULL) in->error(in, "Field not named");
+  getRAnglebracket(in);
+
+  f->description = getDescription(in);
+
+  //<int size=...>
+  getLAnglebracket(in);
+  f->type = parseType(in,NULL, unnamed_types, named_types);
+
+  getLAnglebracket(in);
+  getForwardslash(in);
+  token = getName(in);
+  if(strcmp("field",token))in->error(in,"not a valid field definition");
+  getRAnglebracket(in); //</field>
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    parseType      : get type information, type can be : 
+ *                     Primitive:
+ *                        int(size,fmt); uint(size,fmt); float(size,fmt); 
+ *                        string(fmt); enum(size,fmt,(label1,label2...))
+ *                     Compound:
+ *                        array(arraySize, type); sequence(lengthSize,type)
+ *                       struct(field(name,type,description)...)
+ *                     type name:
+ *                        type(name,type)
+ *Input params 
+ *    in               : input file handle
+ *    inType           : a type descriptor          
+ *    unnamed_types    : array of unamed types
+ *    named_types      : array of named types
+ *Return values  
+ *    type_descriptor* : a type descriptor             
+ ****************************************************************************/
+
+type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, 
+                          sequence_t * unnamed_types, table_t * named_types) 
+{
+  char *token;
+  type_descriptor_t *t;
+
+  if(inType == NULL) {
+    t = (type_descriptor_t *) memAlloc(sizeof(type_descriptor_t));
+    t->type_name = NULL;
+    t->type = NONE;
+    t->fmt = NULL;
+    sequence_push(unnamed_types,t);
+  }
+  else t = inType;
+
+  token = getName(in);
+
+  if(strcmp(token,"struct") == 0) {
+    t->type = STRUCT;
+    getTypeAttributes(in, t);
+    getRAnglebracket(in); //<struct>
+    getLAnglebracket(in); //<field name=..>
+    token = getToken(in);
+    sequence_init(&(t->fields));
+    while(strcmp("field",token) == 0){
+      parseFields(in,t, unnamed_types, named_types);
+      
+      //next field
+      getLAnglebracket(in);
+      token = getToken(in);    
+    }
+    if(strcmp("/",token))in->error(in,"not a valid structure definition");
+    token = getName(in);
+    if(strcmp("struct",token)!=0)
+      in->error(in,"not a valid structure definition");
+    getRAnglebracket(in); //</struct>
+  }
+  else if(strcmp(token,"union") == 0) {
+    t->type = UNION;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Union has empty size");
+    getRAnglebracket(in); //<union typecodesize=isize>
+
+    getLAnglebracket(in); //<field name=..>
+    token = getToken(in);
+    sequence_init(&(t->fields));
+    while(strcmp("field",token) == 0){
+      parseFields(in,t, unnamed_types, named_types);
+      
+      //next field
+      getLAnglebracket(in);
+      token = getToken(in);    
+    }
+    if(strcmp("/",token))in->error(in,"not a valid union definition");
+    token = getName(in);
+    if(strcmp("union",token)!=0)
+      in->error(in,"not a valid union definition");        
+    getRAnglebracket(in); //</union>
+  }
+  else if(strcmp(token,"array") == 0) {
+    t->type = ARRAY;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Array has empty size");
+    getRAnglebracket(in); //<array size=n>
+
+    getLAnglebracket(in); //<type struct> 
+    t->nested_type = parseType(in, NULL, unnamed_types, named_types);
+
+    getLAnglebracket(in); //</array>
+    getForwardslash(in);
+    token = getName(in);
+    if(strcmp("array",token))in->error(in,"not a valid array definition");
+    getRAnglebracket(in);  //</array>
+  }
+  else if(strcmp(token,"sequence") == 0) {
+    t->type = SEQUENCE;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Sequence has empty size");
+    getRAnglebracket(in); //<array lengthsize=isize>
+
+    getLAnglebracket(in); //<type struct> 
+    t->nested_type = parseType(in,NULL, unnamed_types, named_types);
+
+    getLAnglebracket(in); //</sequence>
+    getForwardslash(in);
+    token = getName(in);
+    if(strcmp("sequence",token))in->error(in,"not a valid sequence definition");
+    getRAnglebracket(in); //</sequence>
+  }
+  else if(strcmp(token,"enum") == 0) {
+    char * str, *str1;
+    t->type = ENUM;
+    sequence_init(&(t->labels));
+    sequence_init(&(t->labels_description));
+               t->already_printed = 0;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "Sequence has empty size");
+    getRAnglebracket(in);
+
+    //<label name=label1 value=n/>
+    getLAnglebracket(in);
+    token = getToken(in); //"label" or "/"
+    while(strcmp("label",token) == 0){
+      str   = allocAndCopy(getNameAttribute(in));      
+      token = getValueStrAttribute(in);
+      if(token){
+       str1 = appendString(str,"=");
+       free(str);
+       str = appendString(str1,token);
+       free(str1);
+       sequence_push(&(t->labels),str);
+      }
+      else
+       sequence_push(&(t->labels),str);
+
+      getForwardslash(in);
+      getRAnglebracket(in);
+      
+      //read description if any. May be NULL.
+      str = allocAndCopy(getDescription(in));
+                       sequence_push(&(t->labels_description),str);
+                             
+      //next label definition
+      getLAnglebracket(in);
+      token = getToken(in); //"label" or "/"      
+    }
+    if(strcmp("/",token))in->error(in, "not a valid enum definition");
+    token = getName(in);
+    if(strcmp("enum",token))in->error(in, "not a valid enum definition");
+      getRAnglebracket(in); //</label>
+  }
+  else if(strcmp(token,"int") == 0) {
+    t->type = INT;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "int has empty size");
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"uint") == 0) {
+    t->type = UINT;
+    getTypeAttributes(in, t);
+    if(t->size == -1) in->error(in, "uint has empty size");
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"pointer") == 0) {
+    t->type = POINTER;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"long") == 0) {
+    t->type = LONG;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"ulong") == 0) {
+    t->type = ULONG;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"size_t") == 0) {
+    t->type = SIZE_T;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"ssize_t") == 0) {
+    t->type = SSIZE_T;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"off_t") == 0) {
+    t->type = OFF_T;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"float") == 0) {
+    t->type = FLOAT;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"string") == 0) {
+    t->type = STRING;
+    getTypeAttributes(in, t);
+    getForwardslash(in);
+    getRAnglebracket(in); 
+  }
+  else if(strcmp(token,"typeref") == 0){
+    // Must be a named type
+    if(inType != NULL) 
+      in->error(in,"Named type cannot refer to a named type");
+    else {
+      free(t);
+      sequence_pop(unnamed_types);
+      token = getNameAttribute(in);
+      t = find_named_type(token, named_types);
+      getForwardslash(in);  //<typeref name=type_name/>
+      getRAnglebracket(in);
+      return t;
+    }
+  }else in->error(in,"not a valid type");
+
+  return t;
+}    
+
+/*****************************************************************************
+ *Function name
+ *    find_named_type     : find a named type from hash table 
+ *Input params 
+ *    name                : type name          
+ *    named_types         : array of named types
+ *Return values  
+ *    type_descriptor *   : a type descriptor                       
+ *****************************************************************************/
+
+type_descriptor_t * find_named_type(char *name, table_t * named_types)
+{ 
+  type_descriptor_t *t;
+
+  t = table_find(named_types,name);
+  if(t == NULL) {
+    t = (type_descriptor_t *)memAlloc(sizeof(type_descriptor_t));
+    t->type_name = allocAndCopy(name);
+    t->type = NONE;
+    t->fmt = NULL;
+    table_insert(named_types,t->type_name,t);
+    //    table_insert(named_types,allocAndCopy(name),t);
+  }
+  return t;
+}  
+
+/*****************************************************************************
+ *Function name
+ *    parseTypeDefinition : get type information from type definition 
+ *Input params 
+ *    in                  : input file handle          
+ *    unnamed_types       : array of unamed types
+ *    named_types         : array of named types
+ *****************************************************************************/
+
+void parseTypeDefinition(parse_file_t * in, sequence_t * unnamed_types,
+                        table_t * named_types)
+{
+  char *token;
+  type_descriptor_t *t;
+
+  token = getNameAttribute(in);
+  if(token == NULL) in->error(in, "Type has empty name");
+  t = find_named_type(token, named_types);
+
+  if(t->type != NONE) in->error(in,"redefinition of named type");
+  getRAnglebracket(in); //<type name=type_name>
+  getLAnglebracket(in); //<
+  token = getName(in);
+  //MD ??if(strcmp("struct",token))in->error(in,"not a valid type definition");
+  ungetToken(in);
+  parseType(in,t, unnamed_types, named_types);
+  
+  //</type>
+  getLAnglebracket(in);
+  getForwardslash(in);
+  token = getName(in);
+  if(strcmp("type",token))in->error(in,"not a valid type definition");  
+  getRAnglebracket(in); //</type>
+}
+
+/**************************************************************************
+ * Function :
+ *    getComa, getName, getNumber, getEqual
+ * Description :
+ *    Read a token from the input file, check its type, return it scontent.
+ *
+ * Parameters :
+ *    in , input file handle.
+ *
+ * Return values :
+ *    address of token content.
+ *
+ **************************************************************************/
+
+char *getName(parse_file_t * in) 
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != NAME) in->error(in,"Name token was expected");
+  return token;
+}
+
+int getNumber(parse_file_t * in) 
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != NUMBER) in->error(in, "Number token was expected");
+  return atoi(token);
+}
+
+char *getForwardslash(parse_file_t * in) 
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != FORWARDSLASH) in->error(in, "forward slash token was expected");
+  return token;
+}
+
+char *getLAnglebracket(parse_file_t * in) 
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != LANGLEBRACKET) in->error(in, "Left angle bracket was expected");
+  return token;
+}
+
+char *getRAnglebracket(parse_file_t * in) 
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != RANGLEBRACKET) in->error(in, "Right angle bracket was expected");
+  return token;
+}
+
+char *getQuotedString(parse_file_t * in) 
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != QUOTEDSTRING) in->error(in, "quoted string was expected");
+  return token;
+}
+
+char * getEqual(parse_file_t *in)
+{
+  char *token;
+
+  token = getToken(in);
+  if(in->type != EQUAL) in->error(in, "equal was expected");
+  return token;
+}
+
+char seekNextChar(parse_file_t *in)
+{
+  char car;
+  while((car = getc(in->fp)) != EOF) {
+    if(!isspace(car)){
+      ungetc(car,in->fp);
+      return car;
+    }
+  }  
+  return EOF;
+}
+
+/******************************************************************
+ * Function :
+ *    getToken, ungetToken
+ * Description :
+ *    Read a token from the input file and return its type and content.
+ *    Line numbers are accounted for and whitespace/comments are skipped.
+ *
+ * Parameters :
+ *    in, input file handle.
+ *
+ * Return values :
+ *    address of token content.
+ *
+ ******************************************************************/
+
+void ungetToken(parse_file_t * in)
+{
+  in->unget = 1;
+}
+
+char *getToken(parse_file_t * in)
+{
+  FILE *fp = in->fp;
+  char car, car1;
+  int pos = 0, escaped;
+
+  if(in->unget == 1) {
+    in->unget = 0;
+    return in->buffer;
+  }
+
+  /* skip whitespace and comments */
+
+  while((car = getc(fp)) != EOF) {
+    if(car == '/') {
+      car1 = getc(fp); 
+      if(car1 == '*') skipComment(in);
+      else if(car1 == '/') skipEOL(in);
+      else { 
+        car1 = ungetc(car1,fp);
+        break;
+      }
+    }
+    else if(car == '\n') in->lineno++;
+    else if(!isspace(car)) break;
+  }
+
+  switch(car) {
+    case EOF:
+      in->type = ENDFILE;
+      break;
+    case '/':
+      in->type = FORWARDSLASH;
+      in->buffer[pos] = car;
+      pos++;
+      break;
+    case '<':
+      in->type = LANGLEBRACKET;
+      in->buffer[pos] = car;
+      pos++;
+      break;
+    case '>':
+      in->type = RANGLEBRACKET;
+      in->buffer[pos] = car;
+      pos++;
+      break;
+    case '=':
+      in->type = EQUAL;
+      in->buffer[pos] = car;
+      pos++;
+      break;
+    case '"':
+      escaped = 0;
+      while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
+        if(car == '\\' && escaped == 0) {
+         in->buffer[pos] = car;
+         pos++;
+          escaped = 1;
+          continue;
+        }
+        if(car == '"' && escaped == 0) break;
+        if(car == '\n' && escaped == 0) {
+          in->error(in, "non escaped newline inside quoted string");
+        }
+        if(car == '\n') in->lineno++;
+        in->buffer[pos] = car;
+        pos++;
+        escaped = 0;
+      }
+      if(car == EOF) in->error(in,"no ending quotemark");
+      if(pos == BUFFER_SIZE) in->error(in, "quoted string token too large");
+      in->type = QUOTEDSTRING;
+      break;
+    default:
+      if(isdigit(car)) {
+        in->buffer[pos] = car;
+        pos++;
+        while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
+          if(!isdigit(car)) {
+            ungetc(car,fp);
+            break;
+          }
+          in->buffer[pos] = car;
+          pos++;
+        }
+       if(car == EOF) ungetc(car,fp);
+        if(pos == BUFFER_SIZE) in->error(in, "number token too large");
+        in->type = NUMBER;
+      }    
+      else if(isalpha(car)) {
+        in->buffer[0] = car;
+        pos = 1;
+        while((car = getc(fp)) != EOF && pos < BUFFER_SIZE) {
+          if(!(isalnum(car) || car == '_')) {
+            ungetc(car,fp);
+            break;
+          }
+          in->buffer[pos] = car;
+          pos++;
+        }
+       if(car == EOF) ungetc(car,fp);
+        if(pos == BUFFER_SIZE) in->error(in, "name token too large");
+        in->type = NAME;
+      }
+      else in->error(in, "invalid character, unrecognized token");
+  }
+  in->buffer[pos] = 0;
+  return in->buffer;
+}
+
+void skipComment(parse_file_t * in)
+{
+  char car;
+  while((car = getc(in->fp)) != EOF) {
+    if(car == '\n') in->lineno++;
+    else if(car == '*') {
+      car = getc(in->fp);
+      if(car ==EOF) break;
+      if(car == '/') return;
+      ungetc(car,in->fp);
+    }
+  }
+  if(car == EOF) in->error(in,"comment begining with '/*' has no ending '*/'");
+}
+
+void skipEOL(parse_file_t * in)
+{
+  char car;
+  while((car = getc(in->fp)) != EOF) {
+    if(car == '\n') {
+      ungetc(car,in->fp);
+      break;
+    }
+  }
+  if(car == EOF)ungetc(car, in->fp);
+}
+
+/*****************************************************************************
+ *Function name
+ *    checkNamedTypesImplemented : check if all named types have definition
+ ****************************************************************************/
+
+void checkNamedTypesImplemented(table_t * named_types)
+{
+  type_descriptor_t *t;
+  int pos;
+  char str[256];
+
+  for(pos = 0 ; pos < named_types->values.position; pos++) {
+    t = (type_descriptor_t *) named_types->values.array[pos];
+    if(t->type == NONE){
+      sprintf(str,"named type '%s' has no definition",
+          (char*)named_types->keys.array[pos]);
+      error_callback(NULL,str);   
+    }
+  }
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    generateChecksum  : generate checksum for the facility
+ *Input Params
+ *    facName           : name of facility
+ *Output Params
+ *    checksum          : checksum for the facility
+ ****************************************************************************/
+
+void generateChecksum(char* facName,
+    unsigned long * checksum, sequence_t * events)
+{
+  unsigned long crc ;
+  int pos;
+  event_t * ev;
+  char str[256];
+
+  crc = crc32(facName);
+  for(pos = 0; pos < events->position; pos++){
+    ev = (event_t *)(events->array[pos]);
+    crc = partial_crc32(ev->name,crc);    
+    if(!ev->type) continue; //event without type
+    if(ev->type->type != STRUCT){
+      sprintf(str,"event '%s' has a type other than STRUCT",ev->name);
+      error_callback(NULL, str);
+    }
+    crc = getTypeChecksum(crc, ev->type);
+  }
+  *checksum = crc;
+}
+
+/*****************************************************************************
+ *Function name
+ *   getTypeChecksum    : generate checksum by type info
+ *Input Params
+ *    crc               : checksum generated so far
+ *    type              : type descriptor containing type info
+ *Return value          
+ *    unsigned long     : checksum 
+ *****************************************************************************/
+
+unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type)
+{
+  unsigned long crc = aCrc;
+  char * str = NULL, buf[16];
+  int flag = 0, pos;
+  field_t * fld;
+
+  switch(type->type){
+    case INT:
+      str = intOutputTypes[type->size];
+      break;
+    case UINT:
+      str = uintOutputTypes[type->size];
+      break;
+    case POINTER:
+      str = allocAndCopy("void *");
+                       flag = 1;
+      break;
+    case LONG:
+      str = allocAndCopy("long");
+                       flag = 1;
+      break;
+    case ULONG:
+      str = allocAndCopy("unsigned long");
+                       flag = 1;
+      break;
+    case SIZE_T:
+      str = allocAndCopy("size_t");
+                       flag = 1;
+      break;
+    case SSIZE_T:
+      str = allocAndCopy("ssize_t");
+                       flag = 1;
+      break;
+    case OFF_T:
+      str = allocAndCopy("off_t");
+                       flag = 1;
+      break;
+    case FLOAT:
+      str = floatOutputTypes[type->size];
+      break;
+    case STRING:
+      str = allocAndCopy("string");
+      flag = 1;
+      break;
+    case ENUM:
+      str = appendString("enum ", uintOutputTypes[type->size]);
+      flag = 1;
+      break;
+    case ARRAY:
+      sprintf(buf,"%d",type->size);
+      str = appendString("array ",buf);
+      flag = 1;
+      break;
+    case SEQUENCE:
+      sprintf(buf,"%d",type->size);
+      str = appendString("sequence ",buf);
+      flag = 1;
+      break;
+    case STRUCT:
+      str = allocAndCopy("struct");
+      flag = 1;
+      break;
+    case UNION:
+      str = allocAndCopy("union");
+      flag = 1;
+      break;
+    default:
+      error_callback(NULL, "named type has no definition");
+      break;
+  }
+
+  crc = partial_crc32(str,crc);
+  if(flag) free(str);
+
+  if(type->fmt) crc = partial_crc32(type->fmt,crc);
+    
+  if(type->type == ARRAY || type->type == SEQUENCE){
+    crc = getTypeChecksum(crc,type->nested_type);
+  }else if(type->type == STRUCT || type->type == UNION){
+    for(pos =0; pos < type->fields.position; pos++){
+      fld = (field_t *) type->fields.array[pos];
+      crc = partial_crc32(fld->name,crc);
+      crc = getTypeChecksum(crc, fld->type);
+    }    
+  }else if(type->type == ENUM){
+    for(pos = 0; pos < type->labels.position; pos++)
+      crc = partial_crc32((char*)type->labels.array[pos],crc);
+  }
+
+  return crc;
+}
+
+
+/* Event type descriptors */
+void freeType(type_descriptor_t * tp)
+{
+  int pos2;
+  field_t *f;
+
+  if(tp->fmt != NULL) free(tp->fmt);
+  if(tp->type == ENUM) {
+    for(pos2 = 0; pos2 < tp->labels.position; pos2++) {
+      free(tp->labels.array[pos2]);
+    }
+    sequence_dispose(&(tp->labels));
+  }
+  if(tp->type == STRUCT) {
+    for(pos2 = 0; pos2 < tp->fields.position; pos2++) {
+      f = (field_t *) tp->fields.array[pos2];
+      free(f->name);
+      free(f->description);
+      free(f);
+    }
+    sequence_dispose(&(tp->fields));
+  }
+}
+
+void freeNamedType(table_t * t)
+{
+  int pos;
+  type_descriptor_t * td;
+
+  for(pos = 0 ; pos < t->keys.position; pos++) {
+    free((char *)t->keys.array[pos]);
+    td = (type_descriptor_t*)t->values.array[pos];
+    freeType(td);
+    free(td);
+  }
+}
+
+void freeTypes(sequence_t *t) 
+{
+  int pos;
+  type_descriptor_t *tp;
+
+  for(pos = 0 ; pos < t->position; pos++) {
+    tp = (type_descriptor_t *)t->array[pos];
+    freeType(tp);
+    free(tp);
+  }
+}
+
+void freeEvents(sequence_t *t) 
+{
+  int pos;
+  event_t *ev;
+
+  for(pos = 0 ; pos < t->position; pos++) {
+    ev = (event_t *) t->array[pos];
+    free(ev->name);
+    free(ev->description);
+    free(ev);
+  }
+
+}
+
+
+/* Extensible array */
+
+void sequence_init(sequence_t *t) 
+{
+  t->size = 10;
+  t->position = 0;
+  t->array = (void **)memAlloc(t->size * sizeof(void *));
+}
+
+void sequence_dispose(sequence_t *t) 
+{
+  t->size = 0;
+  free(t->array);
+  t->array = NULL;
+}
+
+void sequence_push(sequence_t *t, void *elem) 
+{
+  void **tmp;
+
+  if(t->position >= t->size) {
+    tmp = t->array;
+    t->array = (void **)memAlloc(t->size * 2 * sizeof(void *));
+    memcpy(t->array, tmp, t->size * sizeof(void *));
+    t->size = t->size * 2;
+    free(tmp);
+  }
+  t->array[t->position] = elem;
+  t->position++;
+}
+
+void *sequence_pop(sequence_t *t) 
+{
+  return t->array[t->position--];
+}
+
+
+/* Hash table API, implementation is just linear search for now */
+
+void table_init(table_t *t) 
+{
+  sequence_init(&(t->keys));
+  sequence_init(&(t->values));
+}
+
+void table_dispose(table_t *t) 
+{
+  sequence_dispose(&(t->keys));
+  sequence_dispose(&(t->values));
+}
+
+void table_insert(table_t *t, char *key, void *value) 
+{
+  sequence_push(&(t->keys),key);
+  sequence_push(&(t->values),value);
+}
+
+void *table_find(table_t *t, char *key) 
+{
+  int pos;
+  for(pos = 0 ; pos < t->keys.position; pos++) {
+    if(strcmp((char *)key,(char *)t->keys.array[pos]) == 0)
+      return(t->values.array[pos]);
+  }
+  return NULL;
+}
+
+void table_insert_int(table_t *t, int *key, void *value)
+{
+  sequence_push(&(t->keys),key);
+  sequence_push(&(t->values),value);
+}
+
+void *table_find_int(table_t *t, int *key)
+{
+  int pos;
+  for(pos = 0 ; pos < t->keys.position; pos++) {
+    if(*key == *(int *)t->keys.array[pos])
+      return(t->values.array[pos]);
+  }
+  return NULL;
+}
+
+
+/* Concatenate strings */
+
+char *appendString(char *s, char *suffix) 
+{
+  char *tmp;
+  if(suffix == NULL) return s;
+
+  tmp = (char *)memAlloc(strlen(s) + strlen(suffix) + 1);
+  strcpy(tmp,s);
+  strcat(tmp,suffix);  
+  return tmp;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/parser.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/parser.h
new file mode 100644 (file)
index 0000000..c846697
--- /dev/null
@@ -0,0 +1,209 @@
+#ifndef PARSER_H
+#define PARSER_H
+
+/* Extensible array container */
+
+typedef struct _sequence {
+  int size;
+  int position;
+  void **array;
+} sequence_t;
+
+void sequence_init(sequence_t *t);
+void sequence_dispose(sequence_t *t);
+void sequence_push(sequence_t *t, void *elem);
+void *sequence_pop(sequence_t *t);
+
+
+/* Hash table */
+
+typedef struct _table {
+  sequence_t keys;
+  sequence_t values;
+} table_t;
+
+void table_init(table_t *t);
+void table_dispose(table_t *t);
+void table_insert(table_t *t, char *key, void *value);
+void *table_find(table_t *t, char *key);
+void table_insert_int(table_t *t, int *key, void *value);
+void *table_find_int(table_t *t, int *key);
+
+
+/* Token types */
+
+typedef enum _token_type {
+  ENDFILE,
+  FORWARDSLASH,
+  LANGLEBRACKET,
+  RANGLEBRACKET,
+  EQUAL,
+  QUOTEDSTRING,
+  NUMBER,
+  NAME
+} token_type_t;
+
+
+/* State associated with a file being parsed */
+typedef struct _parse_file {
+  char *name;
+  FILE * fp;
+  int lineno;
+  char *buffer;
+  token_type_t type; 
+  int unget;
+  void (*error) (struct _parse_file *, char *);
+} parse_file_t;
+
+void ungetToken(parse_file_t * in);
+char *getToken(parse_file_t *in);
+char *getForwardslash(parse_file_t *in);
+char *getLAnglebracket(parse_file_t *in);
+char *getRAnglebracket(parse_file_t *in);
+char *getQuotedString(parse_file_t *in);
+char *getName(parse_file_t *in);
+int   getNumber(parse_file_t *in);
+char *getEqual(parse_file_t *in);
+char  seekNextChar(parse_file_t *in);
+
+void skipComment(parse_file_t * in);
+void skipEOL(parse_file_t * in);
+
+/* Some constants */
+
+static const int BUFFER_SIZE = 1024;
+
+
+/* Events data types */
+
+typedef enum _data_type {
+  INT,
+  UINT,
+       POINTER,
+       LONG,
+       ULONG,
+       SIZE_T,
+       SSIZE_T,
+       OFF_T,
+  FLOAT,
+  STRING,
+  ENUM,
+  ARRAY,
+  SEQUENCE,
+  STRUCT,
+  UNION,
+  NONE
+} data_type_t;
+
+/* Event type descriptors */
+
+typedef struct _type_descriptor {
+  char * type_name; //used for named type
+  data_type_t type;
+  char *fmt;
+  int size;
+  sequence_t labels; // for enumeration
+       sequence_t labels_description;
+       int     already_printed;
+  sequence_t fields; // for structure
+  struct _type_descriptor *nested_type; // for array and sequence 
+  int alignment;
+} type_descriptor_t;
+
+
+/* Fields within types */
+
+typedef struct _field{
+  char *name;
+  char *description;
+  type_descriptor_t *type;
+} field_t;
+
+
+/* Events definitions */
+
+typedef struct _event {  
+  char *name;
+  char *description;
+  type_descriptor_t *type; 
+  int  per_trace;   /* Is the event able to be logged to a specific trace ? */
+  int  per_tracefile;  /* Must we log this event in a specific tracefile ? */
+} event_t;
+
+typedef struct _facility {
+  char * name;
+       char * capname;
+  char * description;
+  sequence_t events;
+  sequence_t unnamed_types;
+  table_t named_types;
+} facility_t;
+
+int getSize(parse_file_t *in);
+unsigned long getTypeChecksum(unsigned long aCrc, type_descriptor_t * type);
+
+void parseFacility(parse_file_t *in, facility_t * fac);
+void parseEvent(parse_file_t *in, event_t *ev, sequence_t * unnamed_types,
+    table_t * named_types);
+void parseTypeDefinition(parse_file_t *in,
+    sequence_t * unnamed_types, table_t * named_types);
+type_descriptor_t *parseType(parse_file_t *in,
+    type_descriptor_t *t, sequence_t * unnamed_types, table_t * named_types);
+void parseFields(parse_file_t *in, type_descriptor_t *t,
+    sequence_t * unnamed_types, table_t * named_types);
+void checkNamedTypesImplemented(table_t * namedTypes);
+type_descriptor_t * find_named_type(char *name, table_t * named_types);
+void generateChecksum(char * facName,
+    unsigned long * checksum, sequence_t * events);
+
+
+/* get attributes */
+char * getNameAttribute(parse_file_t *in);
+char * getFormatAttribute(parse_file_t *in);
+int    getSizeAttribute(parse_file_t *in);
+int    getValueAttribute(parse_file_t *in);
+char * getValueStrAttribute(parse_file_t *in);
+
+char * getDescription(parse_file_t *in);
+
+
+/* Dynamic memory allocation and freeing */
+
+void * memAlloc(int size);
+char *allocAndCopy(char * str);
+char *appendString(char *s, char *suffix);
+void freeTypes(sequence_t *t);
+void freeType(type_descriptor_t * td);
+void freeEvents(sequence_t *t);
+void freeNamedType(table_t * t);
+void error_callback(parse_file_t *in, char *msg);
+
+
+//checksum part
+static const unsigned int crctab32[] =
+{
+#include "crc32.tab"
+};
+
+static inline unsigned long
+partial_crc32_one(unsigned char c, unsigned long crc)
+{
+  return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
+}
+
+static inline unsigned long
+partial_crc32(const char *s, unsigned long crc)
+{
+  while (*s)
+    crc = partial_crc32_one(*s++, crc);
+  return crc;
+}
+
+static inline unsigned long
+crc32(const char *s)
+{
+  return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
+}
+
+
+#endif // PARSER_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/time.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/time.h
new file mode 100644 (file)
index 0000000..d826e4a
--- /dev/null
@@ -0,0 +1,249 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LTT_TIME_H
+#define LTT_TIME_H
+
+#include <glib.h>
+#include <ltt/compiler.h>
+#include <math.h>
+
+typedef struct _LttTime {
+  unsigned long tv_sec;
+  unsigned long tv_nsec;
+} LttTime;
+
+
+#define NANOSECONDS_PER_SECOND 1000000000
+
+/* We give the DIV and MUL constants so we can always multiply, for a
+ * division as well as a multiplication of NANOSECONDS_PER_SECOND */
+/* 2^30/1.07374182400631629848 = 1000000000.0 */ 
+#define DOUBLE_SHIFT_CONST_DIV 1.07374182400631629848
+#define DOUBLE_SHIFT 30
+
+/* 2^30*0.93132257461547851562 = 1000000000.0000000000 */ 
+#define DOUBLE_SHIFT_CONST_MUL 0.93132257461547851562
+
+
+/* 1953125 * 2^9 = NANOSECONDS_PER_SECOND */
+#define LTT_TIME_UINT_SHIFT_CONST 1953125
+#define LTT_TIME_UINT_SHIFT 9
+
+
+static const LttTime ltt_time_zero = { 0, 0 };
+
+static const LttTime ltt_time_one = { 0, 1 };
+
+static const LttTime ltt_time_infinite = { G_MAXUINT, NANOSECONDS_PER_SECOND };
+
+static inline LttTime ltt_time_sub(LttTime t1, LttTime t2) 
+{
+  LttTime res;
+  res.tv_sec  = t1.tv_sec  - t2.tv_sec;
+  res.tv_nsec = t1.tv_nsec - t2.tv_nsec;
+  /* unlikely : given equal chance to be anywhere in t1.tv_nsec, and
+   * higher probability of low value for t2.tv_sec, we will habitually
+   * not wrap.
+   */
+  if(unlikely(t1.tv_nsec < t2.tv_nsec)) {
+    res.tv_sec--;
+    res.tv_nsec += NANOSECONDS_PER_SECOND;
+  }
+  return res;
+}
+
+
+static inline LttTime ltt_time_add(LttTime t1, LttTime t2) 
+{
+  LttTime res;
+  res.tv_nsec = t1.tv_nsec + t2.tv_nsec;
+  res.tv_sec = t1.tv_sec + t2.tv_sec;
+  /* unlikely : given equal chance to be anywhere in t1.tv_nsec, and
+   * higher probability of low value for t2.tv_sec, we will habitually
+   * not wrap.
+   */
+  if(unlikely(res.tv_nsec >= NANOSECONDS_PER_SECOND)) {
+    res.tv_sec++;
+    res.tv_nsec -= NANOSECONDS_PER_SECOND;
+  }
+  return res;
+}
+
+/* Fastest comparison : t1 > t2 */
+static inline int ltt_time_compare(LttTime t1, LttTime t2)
+{
+  int ret=0;
+  if(likely(t1.tv_sec > t2.tv_sec)) ret = 1;
+  else if(unlikely(t1.tv_sec < t2.tv_sec)) ret = -1;
+  else if(likely(t1.tv_nsec > t2.tv_nsec)) ret = 1;
+  else if(unlikely(t1.tv_nsec < t2.tv_nsec)) ret = -1;
+  
+  return ret;
+}
+
+#define LTT_TIME_MIN(a,b) ((ltt_time_compare((a),(b)) < 0) ? (a) : (b))
+#define LTT_TIME_MAX(a,b) ((ltt_time_compare((a),(b)) > 0) ? (a) : (b))
+
+#define MAX_TV_SEC_TO_DOUBLE 0x7FFFFF
+static inline double ltt_time_to_double(LttTime t1)
+{
+  /* We lose precision if tv_sec is > than (2^23)-1
+   * 
+   * Max values that fits in a double (53 bits precision on normalised 
+   * mantissa):
+   * tv_nsec : NANOSECONDS_PER_SECONDS : 2^30
+   *
+   * So we have 53-30 = 23 bits left for tv_sec.
+   * */
+#ifdef EXTRA_CHECK
+  g_assert(t1.tv_sec <= MAX_TV_SEC_TO_DOUBLE);
+  if(t1.tv_sec > MAX_TV_SEC_TO_DOUBLE)
+    g_warning("Precision loss in conversion LttTime to double");
+#endif //EXTRA_CHECK
+  return ((double)((guint64)t1.tv_sec<<DOUBLE_SHIFT)
+                  * (double)DOUBLE_SHIFT_CONST_MUL)
+                  + (double)t1.tv_nsec;
+}
+
+
+static inline LttTime ltt_time_from_double(double t1)
+{
+  /* We lose precision if tv_sec is > than (2^23)-1
+   * 
+   * Max values that fits in a double (53 bits precision on normalised 
+   * mantissa):
+   * tv_nsec : NANOSECONDS_PER_SECONDS : 2^30
+   *
+   * So we have 53-30 = 23 bits left for tv_sec.
+   * */
+#ifdef EXTRA_CHECK
+  g_assert(t1 <= MAX_TV_SEC_TO_DOUBLE);
+  if(t1 > MAX_TV_SEC_TO_DOUBLE)
+    g_warning("Conversion from non precise double to LttTime");
+#endif //EXTRA_CHECK
+  LttTime res;
+  //res.tv_sec = t1/(double)NANOSECONDS_PER_SECOND;
+  res.tv_sec = (guint64)(t1 * DOUBLE_SHIFT_CONST_DIV) >> DOUBLE_SHIFT;
+  res.tv_nsec = (t1 - (((guint64)res.tv_sec<<LTT_TIME_UINT_SHIFT))
+                               * LTT_TIME_UINT_SHIFT_CONST);
+  return res;
+}
+
+/* Use ltt_time_to_double and ltt_time_from_double to check for lack
+ * of precision.
+ */
+static inline LttTime ltt_time_mul(LttTime t1, double d)
+{
+  LttTime res;
+
+  double time_double = ltt_time_to_double(t1);
+
+  time_double = time_double * d;
+
+  res = ltt_time_from_double(time_double);
+
+  return res;
+
+#if 0
+  /* What is that ? (Mathieu) */
+  if(f == 0.0){
+    res.tv_sec = 0;
+    res.tv_nsec = 0;
+  }else{
+  double d;
+    d = 1.0/f;
+    sec = t1.tv_sec / (double)d;
+    res.tv_sec = sec;
+    res.tv_nsec = t1.tv_nsec / (double)d + (sec - res.tv_sec) *
+                  NANOSECONDS_PER_SECOND;
+    res.tv_sec += res.tv_nsec / NANOSECONDS_PER_SECOND;
+    res.tv_nsec %= NANOSECONDS_PER_SECOND;
+  }
+  return res;
+#endif //0
+}
+
+
+/* Use ltt_time_to_double and ltt_time_from_double to check for lack
+ * of precision.
+ */
+static inline LttTime ltt_time_div(LttTime t1, double d)
+{
+  LttTime res;
+
+  double time_double = ltt_time_to_double(t1);
+
+  time_double = time_double / d;
+
+  res = ltt_time_from_double(time_double);
+
+  return res;
+
+
+#if 0
+  double sec;
+  LttTime res;
+
+  sec = t1.tv_sec / (double)f;
+  res.tv_sec = sec;
+  res.tv_nsec = t1.tv_nsec / (double)f + (sec - res.tv_sec) *
+      NANOSECONDS_PER_SECOND;
+  res.tv_sec += res.tv_nsec / NANOSECONDS_PER_SECOND;
+  res.tv_nsec %= NANOSECONDS_PER_SECOND;
+  return res;
+#endif //0
+}
+
+
+static inline guint64 ltt_time_to_uint64(LttTime t1)
+{
+  return (((guint64)t1.tv_sec*LTT_TIME_UINT_SHIFT_CONST) << LTT_TIME_UINT_SHIFT)
+                       + (guint64)t1.tv_nsec;
+}
+
+
+#define MAX_TV_SEC_TO_UINT64 0x3FFFFFFFFFFFFFFFULL
+
+/* The likely branch is with sec != 0, because most events in a bloc
+ * will be over 1s from the block start. (see tracefile.c)
+ */
+static inline LttTime ltt_time_from_uint64(guint64 t1)
+{
+  /* We lose precision if tv_sec is > than (2^62)-1
+   * */
+#ifdef EXTRA_CHECK
+  g_assert(t1 <= MAX_TV_SEC_TO_UINT64);
+  if(t1 > MAX_TV_SEC_TO_UINT64)
+    g_warning("Conversion from uint64 to non precise LttTime");
+#endif //EXTRA_CHECK
+  LttTime res;
+  //if(unlikely(t1 >= NANOSECONDS_PER_SECOND)) {
+  if(likely(t1>>LTT_TIME_UINT_SHIFT >= LTT_TIME_UINT_SHIFT_CONST)) {
+    //res.tv_sec = t1/NANOSECONDS_PER_SECOND;
+    res.tv_sec = (t1>>LTT_TIME_UINT_SHIFT)
+                         /LTT_TIME_UINT_SHIFT_CONST; // acceleration
+    res.tv_nsec = (t1 - res.tv_sec*NANOSECONDS_PER_SECOND);
+  } else {
+    res.tv_sec = 0;
+    res.tv_nsec = (guint32)t1;
+  }
+  return res;
+}
+
+#endif // LTT_TIME_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/trace.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/trace.h
new file mode 100644 (file)
index 0000000..2e8ec3a
--- /dev/null
@@ -0,0 +1,185 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TRACE_H
+#define TRACE_H
+
+#include <ltt/ltt.h>
+
+extern GQuark LTT_FACILITY_NAME_HEARTBEAT,
+              LTT_EVENT_NAME_HEARTBEAT;
+
+/* A trace is specified as a pathname to the directory containing all the
+   associated data (control tracefiles, per cpu tracefiles, event 
+   descriptions...).
+
+   When a trace is closed, all the associated facilities, types and fields
+   are released as well. 
+   
+   return value is NULL if there is an error when opening the trace.
+   
+   */
+
+LttTrace *ltt_trace_open(const gchar *pathname);
+
+/* copy reopens a trace 
+ *
+ * return value NULL if error while opening the trace 
+ */
+LttTrace *ltt_trace_copy(LttTrace *self);
+
+GQuark ltt_trace_name(const LttTrace *t);
+
+void ltt_trace_close(LttTrace *t); 
+
+guint ltt_trace_get_num_cpu(LttTrace *t);
+
+LttSystemDescription *ltt_trace_system_description(LttTrace *t);
+
+
+/* Functions to discover the facilities in the trace. Once the number
+   of facilities is known, they may be accessed by position. Multiple
+   versions of a facility (same name, different checksum) have consecutive
+   positions. */
+
+unsigned ltt_trace_facility_number(LttTrace *t);
+
+LttFacility *ltt_trace_facility_get(LttTrace *t, unsigned i);
+
+LttFacility * ltt_trace_facility_by_id(LttTrace * trace, guint8 id);
+
+/* Returns an array of indexes (guint) that matches the facility name */
+GArray *ltt_trace_facility_get_by_name(LttTrace *t, GQuark name);
+
+/* Functions to discover all the event types in the trace */
+
+unsigned ltt_trace_eventtype_number(LttTrace *t);
+
+LttEventType *ltt_trace_eventtype_get(LttTrace *t, unsigned i);
+
+
+/* Get the start time and end time of the trace */
+
+void ltt_trace_time_span_get(LttTrace *t, LttTime *start, LttTime *end);
+
+
+/* Get the name of a tracefile */
+
+GQuark ltt_tracefile_name(const LttTracefile *tf);
+GQuark ltt_tracefile_long_name(const LttTracefile *tf);
+
+/* get the cpu number of the tracefile */
+
+guint ltt_tracefile_num(LttTracefile *tf);
+
+LttTrace *ltt_tracefile_get_trace(LttTracefile *tf);
+
+/* Get the number of blocks in the tracefile */
+
+unsigned ltt_tracefile_block_number(LttTracefile *tf);
+
+
+/* Seek to the first event of the trace with time larger or equal to time */
+
+int ltt_tracefile_seek_time(LttTracefile *t, LttTime time);
+
+/* Seek to the first event with position equal or larger to ep */
+
+int ltt_tracefile_seek_position(LttTracefile *t,
+    const LttEventPosition *ep);
+
+/* Read the next event */
+
+int ltt_tracefile_read(LttTracefile *t);
+
+/* ltt_tracefile_read cut down in pieces */
+int ltt_tracefile_read_seek(LttTracefile *t);
+int ltt_tracefile_read_update_event(LttTracefile *t);
+int ltt_tracefile_read_op(LttTracefile *t);
+
+/* Get the current event of the tracefile : valid until the next read */
+LttEvent *ltt_tracefile_get_event(LttTracefile *tf);
+
+/* open tracefile */
+
+gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf);
+
+/* get the data type size and endian type of the local machine */
+
+void getDataEndianType(LttArchSize * size, LttArchEndian * endian);
+
+/* get an integer number */
+gint64 get_int(gboolean reverse_byte_order, gint size, void *data);
+
+/* get the node name of the system */
+
+gchar * ltt_trace_system_description_node_name (LttSystemDescription * s);
+
+
+/* get the domain name of the system */
+
+gchar * ltt_trace_system_description_domain_name (LttSystemDescription * s);
+
+
+/* get the description of the system */
+
+gchar * ltt_trace_system_description_description (LttSystemDescription * s);
+
+
+/* get the NTP start time of the trace */
+
+LttTime ltt_trace_start_time(LttTrace *t);
+
+/* get the monotonic start time of the trace */
+
+LttTime ltt_trace_start_time_monotonic(LttTrace *t);
+
+/* copy tracefile info over another. Used for sync. */
+LttTracefile *ltt_tracefile_new();
+void ltt_tracefile_destroy(LttTracefile *tf);
+void ltt_tracefile_copy(LttTracefile *dest, const LttTracefile *src);
+
+void get_absolute_pathname(const gchar *pathname, gchar * abs_pathname);
+
+/* May return a NULL tracefile group */
+GData **ltt_trace_get_tracefiles_groups(LttTrace *trace);
+
+typedef void (*ForEachTraceFileFunc)(LttTracefile *tf, gpointer func_args);
+
+struct compute_tracefile_group_args {
+  ForEachTraceFileFunc func;
+  gpointer func_args;
+};
+
+
+void compute_tracefile_group(GQuark key_id,
+                             GArray *group,
+                             struct compute_tracefile_group_args *args);
+
+LttFacility *ltt_trace_get_facility_by_num(LttTrace *t, guint num);
+
+
+gint check_fields_compatibility(LttEventType *event_type1,
+    LttEventType *event_type2,
+    LttField *field1, LttField *field2);
+
+gint64 ltt_get_int(gboolean reverse_byte_order, gint size, void *data);
+
+guint64 ltt_get_uint(gboolean reverse_byte_order, gint size, void *data);
+
+#endif // TRACE_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/tracefile.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/tracefile.c
new file mode 100644 (file)
index 0000000..7f76f01
--- /dev/null
@@ -0,0 +1,2599 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2005 Mathieu Desnoyers
+ *
+ * Complete rewrite from the original version made by XangXiu Yang.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <math.h>
+#include <glib.h>
+#include <malloc.h>
+#include <sys/mman.h>
+
+// For realpath
+#include <limits.h>
+#include <stdlib.h>
+
+
+#include "parser.h"
+#include <ltt/ltt.h>
+#include "ltt-private.h"
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/ltt-types.h>
+
+
+/* Facility names used in this file */
+
+GQuark LTT_FACILITY_NAME_HEARTBEAT,
+       LTT_EVENT_NAME_HEARTBEAT;
+GQuark LTT_TRACEFILE_NAME_FACILITIES;
+
+#ifndef g_open
+#define g_open open
+#endif
+
+
+#define __UNUSED__ __attribute__((__unused__))
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+
+#ifndef g_debug
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+#endif
+
+#define g_close close
+
+/* Those macros must be called from within a function where page_size is a known
+ * variable */
+#define PAGE_MASK (~(page_size-1))
+#define PAGE_ALIGN(addr)  (((addr)+page_size-1)&PAGE_MASK)
+
+/* set the offset of the fields belonging to the event,
+   need the information of the archecture */
+void set_fields_offsets(LttTracefile *tf, LttEventType *event_type);
+//size_t get_fields_offsets(LttTracefile *tf, LttEventType *event_type, void *data);
+
+/* get the size of the field type according to 
+ * The facility size information. */
+static inline void preset_field_type_size(LttTracefile *tf,
+    LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    enum field_status *fixed_root, enum field_status *fixed_parent,
+    LttField *field);
+
+/* map a fixed size or a block information from the file (fd) */
+static gint map_block(LttTracefile * tf, guint block_num);
+
+/* calculate nsec per cycles for current block */
+#if 0
+static guint32 calc_nsecs_per_cycle(LttTracefile * t);
+static guint64 cycles_2_ns(LttTracefile *tf, guint64 cycles);
+#endif //0
+
+/* go to the next event */
+static int ltt_seek_next_event(LttTracefile *tf);
+
+void ltt_update_event_size(LttTracefile *tf);
+
+#if 0
+/* Functions to parse system.xml file (using glib xml parser) */
+static void parser_start_element (GMarkupParseContext  __UNUSED__ *context,
+                                 const gchar          *element_name,
+                                 const gchar         **attribute_names,
+                                 const gchar         **attribute_values,
+                                 gpointer              user_data,
+                                 GError              **error)
+{
+  int i=0;
+  LttSystemDescription* des = (LttSystemDescription* )user_data;
+  if(strcmp("system", element_name)){
+    *error = g_error_new(G_MARKUP_ERROR,
+                         G_LOG_LEVEL_WARNING,
+                         "This is not system.xml file");
+    return;
+  }
+  
+  while(attribute_names[i]){
+    if(strcmp("node_name", attribute_names[i])==0){
+       des->node_name = g_strdup(attribute_values[i]);      
+    }else if(strcmp("domainname", attribute_names[i])==0){
+       des->domain_name = g_strdup(attribute_values[i]);      
+    }else if(strcmp("cpu", attribute_names[i])==0){
+       des->nb_cpu = atoi(attribute_values[i]);      
+    }else if(strcmp("arch_size", attribute_names[i])==0){
+       if(strcmp(attribute_values[i],"LP32") == 0) des->size = LTT_LP32;
+       else if(strcmp(attribute_values[i],"ILP32") == 0) des->size = LTT_ILP32;
+       else if(strcmp(attribute_values[i],"LP64") == 0) des->size = LTT_LP64;
+       else if(strcmp(attribute_values[i],"ILP64") == 0) des->size = LTT_ILP64;
+       else if(strcmp(attribute_values[i],"UNKNOWN") == 0) des->size = LTT_UNKNOWN;
+    }else if(strcmp("endian", attribute_names[i])==0){
+       if(strcmp(attribute_values[i],"LITTLE_ENDIAN") == 0)
+         des->endian = LTT_LITTLE_ENDIAN;
+       else if(strcmp(attribute_values[i],"BIG_ENDIAN") == 0) 
+         des->endian = LTT_BIG_ENDIAN;
+    }else if(strcmp("kernel_name", attribute_names[i])==0){
+       des->kernel_name = g_strdup(attribute_values[i]);      
+    }else if(strcmp("kernel_release", attribute_names[i])==0){
+       des->kernel_release = g_strdup(attribute_values[i]);      
+    }else if(strcmp("kernel_version", attribute_names[i])==0){
+       des->kernel_version = g_strdup(attribute_values[i]);      
+    }else if(strcmp("machine", attribute_names[i])==0){
+       des->machine = g_strdup(attribute_values[i]);      
+    }else if(strcmp("processor", attribute_names[i])==0){
+       des->processor = g_strdup(attribute_values[i]);      
+    }else if(strcmp("hardware_platform", attribute_names[i])==0){
+       des->hardware_platform = g_strdup(attribute_values[i]);      
+    }else if(strcmp("operating_system", attribute_names[i])==0){
+       des->operating_system = g_strdup(attribute_values[i]);      
+    }else if(strcmp("ltt_major_version", attribute_names[i])==0){
+       des->ltt_major_version = atoi(attribute_values[i]);      
+    }else if(strcmp("ltt_minor_version", attribute_names[i])==0){
+       des->ltt_minor_version = atoi(attribute_values[i]);      
+    }else if(strcmp("ltt_block_size", attribute_names[i])==0){
+       des->ltt_block_size = atoi(attribute_values[i]);      
+    }else{
+      *error = g_error_new(G_MARKUP_ERROR,
+                           G_LOG_LEVEL_WARNING,
+                           "Not a valid attribute");
+      return;      
+    }
+    i++;
+  }
+}
+
+static void  parser_characters   (GMarkupParseContext __UNUSED__ *context,
+                                 const gchar          *text,
+                                 gsize __UNUSED__      text_len,
+                                 gpointer              user_data,
+                                 GError __UNUSED__     **error)
+{
+  LttSystemDescription* des = (LttSystemDescription* )user_data;
+  des->description = g_strdup(text);
+}
+#endif //0
+LttFacility *ltt_trace_get_facility_by_num(LttTrace *t,
+    guint num)
+{
+  g_assert(num < t->facilities_by_num->len);
+  
+  return &g_array_index(t->facilities_by_num, LttFacility, num);
+
+}
+
+guint ltt_trace_get_num_cpu(LttTrace *t)
+{
+  return t->num_cpu;
+}
+
+
+/* trace can be NULL
+ *
+ * Return value : 0 success, 1 bad tracefile
+ */
+int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
+{
+  guint32 *magic_number = (guint32*)header;
+  struct ltt_trace_header_any *any = (struct ltt_trace_header_any *)header;
+
+  if(*magic_number == LTT_MAGIC_NUMBER)
+    tf->reverse_bo = 0;
+  else if(*magic_number == LTT_REV_MAGIC_NUMBER)
+    tf->reverse_bo = 1;
+  else  /* invalid magic number, bad tracefile ! */
+    return 1;
+    
+  /* Get float byte order : might be different from int byte order
+   * (or is set to 0 if the trace has no float (kernel trace)) */
+  tf->float_word_order = any->float_word_order;
+
+  if(t) {
+    t->arch_type = ltt_get_uint32(LTT_GET_BO(tf),
+                          &any->arch_type);
+    t->arch_variant = ltt_get_uint32(LTT_GET_BO(tf),
+        &any->arch_variant);
+    t->arch_size = any->arch_size;
+    t->ltt_major_version = any->major_version;
+    t->ltt_minor_version = any->minor_version;
+    t->flight_recorder = any->flight_recorder;
+    t->has_heartbeat = any->has_heartbeat;
+    t->has_alignment = any->has_alignment;
+    t->has_tsc = any->has_tsc;
+  }
+
+  switch(any->major_version) {
+
+  case 0:
+    switch(any->minor_version) {
+    case 3:
+      {
+        tf->buffer_header_size =
+         sizeof(struct ltt_block_start_header) 
+            + sizeof(struct ltt_trace_header_0_3);
+        g_warning("Unsupported trace version : %hhu.%hhu",
+              any->major_version, any->minor_version);
+        return 1;
+      }
+      break;
+    case 4:
+      {
+        struct ltt_trace_header_0_4 *vheader =
+          (struct ltt_trace_header_0_4 *)header;
+        tf->buffer_header_size =
+         sizeof(struct ltt_block_start_header) 
+            + sizeof(struct ltt_trace_header_0_4);
+        if(t) {
+          t->start_freq = ltt_get_uint64(LTT_GET_BO(tf),
+                                         &vheader->start_freq);
+          t->start_tsc = ltt_get_uint64(LTT_GET_BO(tf),
+                                        &vheader->start_tsc);
+          t->start_monotonic = ltt_get_uint64(LTT_GET_BO(tf),
+                                              &vheader->start_monotonic);
+          t->start_time = ltt_get_time(LTT_GET_BO(tf),
+                                       &vheader->start_time);
+          t->start_time.tv_nsec *= 1000; /* microsec to nanosec */
+
+          t->start_time_from_tsc = ltt_time_from_uint64(
+              (double)t->start_tsc * 1000000.0 / (double)t->start_freq);
+        }
+      }
+      break;
+    default:
+      g_warning("Unsupported trace version : %hhu.%hhu",
+            any->major_version, any->minor_version);
+      return 1;
+    }
+    break;
+
+  default:
+    g_warning("Unsupported trace version : %hhu.%hhu",
+            any->major_version, any->minor_version);
+    return 1;
+  }
+
+
+  return 0;
+}
+
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_tracefile_open : open a trace file, construct a LttTracefile
+ *Input params
+ *    t                  : the trace containing the tracefile
+ *    fileName           : path name of the trace file
+ *    tf                 : the tracefile structure
+ *Return value
+ *                       : 0 for success, -1 otherwise.
+ ****************************************************************************/ 
+
+gint ltt_tracefile_open(LttTrace *t, gchar * fileName, LttTracefile *tf)
+{
+  struct stat    lTDFStat;    /* Trace data file status */
+  struct ltt_block_start_header *header;
+  int page_size = getpagesize();
+
+  //open the file
+  tf->long_name = g_quark_from_string(fileName);
+  tf->trace = t;
+  tf->fd = open(fileName, O_RDONLY);
+  if(tf->fd < 0){
+    g_warning("Unable to open input data file %s\n", fileName);
+    goto end;
+  }
+  // Get the file's status 
+  if(fstat(tf->fd, &lTDFStat) < 0){
+    g_warning("Unable to get the status of the input data file %s\n", fileName);
+    goto close_file;
+  }
+
+  // Is the file large enough to contain a trace 
+  if(lTDFStat.st_size <
+      (off_t)(sizeof(struct ltt_block_start_header) 
+                     + sizeof(struct ltt_trace_header_any))){
+    g_print("The input data file %s does not contain a trace\n", fileName);
+    goto close_file;
+  }
+  
+  /* Temporarily map the buffer start header to get trace information */
+  /* Multiple of pages aligned head */
+  tf->buffer.head = mmap(0,
+      PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+          + sizeof(struct ltt_trace_header_any)), PROT_READ, 
+      MAP_PRIVATE, tf->fd, 0);
+  if(tf->buffer.head == MAP_FAILED) {
+    perror("Error in allocating memory for buffer of tracefile");
+    goto close_file;
+  }
+  g_assert( ( (guint)tf->buffer.head&(8-1) ) == 0); // make sure it's aligned.
+  
+  header = (struct ltt_block_start_header*)tf->buffer.head;
+  
+  if(parse_trace_header(header->trace, tf, NULL)) {
+    g_warning("parse_trace_header error");
+    goto unmap_file;
+  }
+    
+  //store the size of the file
+  tf->file_size = lTDFStat.st_size;
+  tf->buf_size = ltt_get_uint32(LTT_GET_BO(tf), &header->buf_size);
+  tf->num_blocks = tf->file_size / tf->buf_size;
+
+  if(munmap(tf->buffer.head,
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)))) {
+    g_warning("unmap size : %u\n",
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)));
+    perror("munmap error");
+    g_assert(0);
+  }
+  tf->buffer.head = NULL;
+
+  //read the first block
+  if(map_block(tf,0)) {
+    perror("Cannot map block for tracefile");
+    goto close_file;
+  }
+  
+  return 0;
+
+  /* Error */
+unmap_file:
+  if(munmap(tf->buffer.head,
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)))) {
+    g_warning("unmap size : %u\n",
+        PAGE_ALIGN(sizeof(struct ltt_block_start_header)
+            + sizeof(struct ltt_trace_header_any)));
+    perror("munmap error");
+    g_assert(0);
+  }
+close_file:
+  close(tf->fd);
+end:
+  return -1;
+}
+
+LttTrace *ltt_tracefile_get_trace(LttTracefile *tf)
+{
+  return tf->trace;
+}
+
+#if 0
+/*****************************************************************************
+ *Open control and per cpu tracefiles
+ ****************************************************************************/
+
+void ltt_tracefile_open_cpu(LttTrace *t, gchar * tracefile_name)
+{
+  LttTracefile * tf;
+  tf = ltt_tracefile_open(t,tracefile_name);
+  if(!tf) return;
+  t->per_cpu_tracefile_number++;
+  g_ptr_array_add(t->per_cpu_tracefiles, tf);
+}
+
+gint ltt_tracefile_open_control(LttTrace *t, gchar * control_name)
+{
+  LttTracefile * tf;
+  LttEvent ev;
+  LttFacility * f;
+  void * pos;
+  FacilityLoad fLoad;
+  unsigned int i;
+
+  tf = ltt_tracefile_open(t,control_name);
+  if(!tf) {
+         g_warning("ltt_tracefile_open_control : bad file descriptor");
+    return -1;
+  }
+  t->control_tracefile_number++;
+  g_ptr_array_add(t->control_tracefiles,tf);
+
+  //parse facilities tracefile to get base_id
+  if(strcmp(&control_name[strlen(control_name)-10],"facilities") ==0){
+    while(1){
+      if(!ltt_tracefile_read(tf,&ev)) return 0; // end of file
+
+      if(ev.event_id == TRACE_FACILITY_LOAD){
+       pos = ev.data;
+       fLoad.name = (gchar*)pos;
+       fLoad.checksum = *(LttChecksum*)(pos + strlen(fLoad.name));
+       fLoad.base_code = *(guint32 *)(pos + strlen(fLoad.name) + sizeof(LttChecksum));
+
+       for(i=0;i<t->facility_number;i++){
+         f = (LttFacility*)g_ptr_array_index(t->facilities,i);
+         if(strcmp(f->name,fLoad.name)==0 && fLoad.checksum==f->checksum){
+           f->base_id = fLoad.base_code;
+           break;
+         }
+       }
+       if(i==t->facility_number) {
+         g_warning("Facility: %s, checksum: %u is not found",
+                 fLoad.name,(unsigned int)fLoad.checksum);
+    return -1;
+  }
+      }else if(ev.event_id == TRACE_BLOCK_START){
+       continue;
+      }else if(ev.event_id == TRACE_BLOCK_END){
+       break;
+      }else {
+        g_warning("Not valid facilities trace file");
+        return -1;
+      }
+    }
+  }
+  return 0;
+}
+#endif //0
+
+/*****************************************************************************
+ *Function name
+ *    ltt_tracefile_close: close a trace file, 
+ *Input params
+ *    t                  : tracefile which will be closed
+ ****************************************************************************/
+
+void ltt_tracefile_close(LttTracefile *t)
+{
+  int page_size = getpagesize();
+
+  if(t->buffer.head != NULL)
+    if(munmap(t->buffer.head, PAGE_ALIGN(t->buf_size))) {
+    g_warning("unmap size : %u\n",
+        PAGE_ALIGN(t->buf_size));
+    perror("munmap error");
+    g_assert(0);
+  }
+
+  close(t->fd);
+}
+
+
+/*****************************************************************************
+ *Get system information
+ ****************************************************************************/
+#if 0
+gint getSystemInfo(LttSystemDescription* des, gchar * pathname)
+{
+  int fd;
+  GIOChannel *iochan;
+  gchar *buf = NULL;
+  gsize length;
+
+  GMarkupParseContext * context;
+  GError * error = NULL;
+  GMarkupParser markup_parser =
+    {
+      parser_start_element,
+      NULL,
+      parser_characters,
+      NULL,  /*  passthrough  */
+      NULL   /*  error        */
+    };
+
+  fd = g_open(pathname, O_RDONLY, 0);
+  if(fd == -1){
+    g_warning("Can not open file : %s\n", pathname);
+    return -1;
+  }
+  
+  iochan = g_io_channel_unix_new(fd);
+  
+  context = g_markup_parse_context_new(&markup_parser, 0, des,NULL);
+  
+  //while(fgets(buf,DIR_NAME_SIZE, fp) != NULL){
+  while(g_io_channel_read_line(iochan, &buf, &length, NULL, &error)
+      != G_IO_STATUS_EOF) {
+
+    if(error != NULL) {
+      g_warning("Can not read xml file: \n%s\n", error->message);
+      g_error_free(error);
+    }
+    if(!g_markup_parse_context_parse(context, buf, length, &error)){
+      if(error != NULL) {
+        g_warning("Can not parse xml file: \n%s\n", error->message);
+        g_error_free(error);
+      }
+      g_markup_parse_context_free(context);
+
+      g_io_channel_shutdown(iochan, FALSE, &error); /* No flush */
+      if(error != NULL) {
+        g_warning("Can not close file: \n%s\n", error->message);
+        g_error_free(error);
+      }
+
+      close(fd);
+      return -1;
+    }
+  }
+  g_markup_parse_context_free(context);
+
+  g_io_channel_shutdown(iochan, FALSE, &error); /* No flush */
+  if(error != NULL) {
+    g_warning("Can not close file: \n%s\n", error->message);
+    g_error_free(error);
+  }
+
+  g_close(fd);
+
+  g_free(buf);
+  return 0;
+}
+#endif //0
+
+/*****************************************************************************
+ *The following functions get facility/tracefile information
+ ****************************************************************************/
+#if 0
+gint getFacilityInfo(LttTrace *t, gchar* eventdefs)
+{
+  GDir * dir;
+  const gchar * name;
+  unsigned int i,j;
+  LttFacility * f;
+  LttEventType * et;
+  gchar fullname[DIR_NAME_SIZE];
+  GError * error = NULL;
+
+  dir = g_dir_open(eventdefs, 0, &error);
+
+  if(error != NULL) {
+    g_warning("Can not open directory: %s, %s\n", eventdefs, error->message);
+    g_error_free(error);
+    return -1;
+  }
+
+  while((name = g_dir_read_name(dir)) != NULL){
+    if(!g_pattern_match_simple("*.xml", name)) continue;
+    strcpy(fullname,eventdefs);
+    strcat(fullname,name);
+    ltt_facility_open(t,fullname);
+  }
+  g_dir_close(dir);
+  
+  for(j=0;j<t->facility_number;j++){
+    f = (LttFacility*)g_ptr_array_index(t->facilities, j);
+    for(i=0; i<f->event_number; i++){
+      et = f->events[i];
+      setFieldsOffset(NULL, et, NULL, t);
+    }    
+  }
+  return 0;
+}
+#endif //0
+
+/*****************************************************************************
+ *A trace is specified as a pathname to the directory containing all the
+ *associated data (control tracefiles, per cpu tracefiles, event 
+ *descriptions...).
+ *
+ *When a trace is closed, all the associated facilities, types and fields
+ *are released as well.
+ */
+
+
+/****************************************************************************
+ * get_absolute_pathname
+ *
+ * return the unique pathname in the system
+ * 
+ * MD : Fixed this function so it uses realpath, dealing well with
+ * forgotten cases (.. were not used correctly before).
+ *
+ ****************************************************************************/
+void get_absolute_pathname(const gchar *pathname, gchar * abs_pathname)
+{
+  abs_pathname[0] = '\0';
+
+  if ( realpath (pathname, abs_pathname) != NULL)
+    return;
+  else
+  {
+    /* error, return the original path unmodified */
+    strcpy(abs_pathname, pathname);
+    return;
+  }
+  return;
+}
+
+/* Search for something like : .*_.*
+ *
+ * The left side is the name, the right side is the number.
+ */
+
+int get_tracefile_name_number(const gchar *raw_name,
+                              GQuark *name,
+                              guint *num)
+{
+  guint raw_name_len = strlen(raw_name);
+  gchar char_name[PATH_MAX];
+  int i;
+  int underscore_pos;
+  long int cpu_num;
+  gchar *endptr;
+
+  for(i=raw_name_len-1;i>=0;i--) {
+    if(raw_name[i] == '_') break;
+  }
+  if(i==0)  /* Either not found or name length is 0 */
+    return -1;
+  underscore_pos = i;
+
+  cpu_num = strtol(raw_name+underscore_pos+1, &endptr, 10);
+
+  if(endptr == raw_name+underscore_pos+1)
+    return -1; /* No digit */
+  if(cpu_num == LONG_MIN || cpu_num == LONG_MAX)
+    return -1; /* underflow / overflow */
+  
+  strncpy(char_name, raw_name, underscore_pos);
+  
+  char_name[underscore_pos] = '\0';
+  
+  *name = g_quark_from_string(char_name);
+  *num = cpu_num;
+  
+  return 0;
+}
+
+
+GData **ltt_trace_get_tracefiles_groups(LttTrace *trace)
+{
+  return &trace->tracefiles;
+}
+
+
+void compute_tracefile_group(GQuark key_id,
+                             GArray *group,
+                             struct compute_tracefile_group_args *args)
+{
+  int i;
+  LttTracefile *tf;
+
+  for(i=0; i<group->len; i++) {
+    tf = &g_array_index (group, LttTracefile, i);
+    if(tf->cpu_online)
+      args->func(tf, args->func_args);
+  }
+}
+
+
+void ltt_tracefile_group_destroy(gpointer data)
+{
+  GArray *group = (GArray *)data;
+  int i;
+  LttTracefile *tf;
+
+  for(i=0; i<group->len; i++) {
+    tf = &g_array_index (group, LttTracefile, i);
+    if(tf->cpu_online)
+      ltt_tracefile_close(tf);
+  }
+  g_array_free(group, TRUE);
+}
+
+gboolean ltt_tracefile_group_has_cpu_online(gpointer data)
+{
+  GArray *group = (GArray *)data;
+  int i;
+  LttTracefile *tf;
+
+  for(i=0; i<group->len; i++) {
+    tf = &g_array_index (group, LttTracefile, i);
+    if(tf->cpu_online) return 1;
+  }
+  return 0;
+}
+
+
+/* Open each tracefile under a specific directory. Put them in a
+ * GData : permits to access them using their tracefile group pathname.
+ * i.e. access control/modules tracefile group by index :
+ * "control/module".
+ * 
+ * relative path is the path relative to the trace root
+ * root path is the full path
+ *
+ * A tracefile group is simply an array where all the per cpu tracefiles sits.
+ */
+
+static int open_tracefiles(LttTrace *trace, gchar *root_path,
+    gchar *relative_path)
+{
+       DIR *dir = opendir(root_path);
+       struct dirent *entry;
+       struct stat stat_buf;
+       int ret;
+  
+       gchar path[PATH_MAX];
+       int path_len;
+       gchar *path_ptr;
+
+  int rel_path_len;
+  gchar rel_path[PATH_MAX];
+  gchar *rel_path_ptr;
+  LttTracefile tmp_tf;
+
+       if(dir == NULL) {
+               perror(root_path);
+               return ENOENT;
+       }
+
+       strncpy(path, root_path, PATH_MAX-1);
+       path_len = strlen(path);
+       path[path_len] = '/';
+       path_len++;
+       path_ptr = path + path_len;
+
+  strncpy(rel_path, relative_path, PATH_MAX-1);
+  rel_path_len = strlen(rel_path);
+  rel_path[rel_path_len] = '/';
+  rel_path_len++;
+  rel_path_ptr = rel_path + rel_path_len;
+  
+       while((entry = readdir(dir)) != NULL) {
+
+               if(entry->d_name[0] == '.') continue;
+               
+               strncpy(path_ptr, entry->d_name, PATH_MAX - path_len);
+               strncpy(rel_path_ptr, entry->d_name, PATH_MAX - rel_path_len);
+               
+               ret = stat(path, &stat_buf);
+               if(ret == -1) {
+                       perror(path);
+                       continue;
+               }
+               
+               g_debug("Tracefile file or directory : %s\n", path);
+               
+    if(strcmp(rel_path, "/eventdefs") == 0) continue;
+    
+               if(S_ISDIR(stat_buf.st_mode)) {
+
+                       g_debug("Entering subdirectory...\n");
+                       ret = open_tracefiles(trace, path, rel_path);
+                       if(ret < 0) continue;
+               } else if(S_ISREG(stat_buf.st_mode)) {
+                       GQuark name;
+      guint num;
+      GArray *group;
+      
+      if(get_tracefile_name_number(rel_path, &name, &num))
+        continue; /* invalid name */
+      
+                       g_debug("Opening file.\n");
+      if(ltt_tracefile_open(trace, path, &tmp_tf)) {
+        g_info("Error opening tracefile %s", path);
+
+        continue; /* error opening the tracefile : bad magic number ? */
+      }
+
+      g_debug("Tracefile name is %s and number is %u", 
+          g_quark_to_string(name), num);
+      
+      tmp_tf.cpu_online = 1;
+      tmp_tf.cpu_num = num;
+      tmp_tf.name = name;
+
+      group = g_datalist_id_get_data(&trace->tracefiles, name);
+      if(group == NULL) {
+        /* Elements are automatically cleared when the array is allocated.
+         * It makes the cpu_online variable set to 0 : cpu offline, by default.
+         */
+        group = g_array_sized_new (FALSE, TRUE, sizeof(LttTracefile), 10);
+        g_datalist_id_set_data_full(&trace->tracefiles, name,
+                                 group, ltt_tracefile_group_destroy);
+      }
+
+      /* Add the per cpu tracefile to the named group */
+      unsigned int old_len = group->len;
+      if(num+1 > old_len)
+        group = g_array_set_size(group, num+1);
+      g_array_index (group, LttTracefile, num) = tmp_tf;
+
+               }
+       }
+       
+       closedir(dir);
+
+       return 0;
+}
+
+/* ltt_get_facility_description
+ *
+ * Opens the file corresponding to the requested facility (identified by fac_id
+ * and checksum).
+ *
+ * The name searched is : %trace root%/eventdefs/facname_checksum.xml
+ *
+ * Returns 0 on success, or 1 on failure.
+ */
+
+static int ltt_get_facility_description(LttFacility *f, 
+                                        LttTrace *t,
+                                        LttTracefile *fac_tf)
+{
+  char desc_file_name[PATH_MAX];
+  const gchar *text;
+  guint textlen;
+  gint err;
+
+  text = g_quark_to_string(t->pathname);
+  textlen = strlen(text);
+  
+  if(textlen >= PATH_MAX) goto name_error;
+  strcpy(desc_file_name, text);
+
+  text = "/eventdefs/";
+  textlen+=strlen(text);
+  if(textlen >= PATH_MAX) goto name_error;
+  strcat(desc_file_name, text);
+  
+  text = g_quark_to_string(f->name);
+  textlen+=strlen(text);
+  if(textlen >= PATH_MAX) goto name_error;
+  strcat(desc_file_name, text);
+#if 0
+  text = "_";
+  textlen+=strlen(text);
+  if(textlen >= PATH_MAX) goto name_error;
+  strcat(desc_file_name, text);
+
+  err = snprintf(desc_file_name+textlen, PATH_MAX-textlen-1,
+      "%u", f->checksum);
+  if(err < 0) goto name_error;
+
+  textlen=strlen(desc_file_name);
+  
+#endif //0
+  text = ".xml";
+  textlen+=strlen(text);
+  if(textlen >= PATH_MAX) goto name_error;
+  strcat(desc_file_name, text);
+
+  err = ltt_facility_open(f, t, desc_file_name);
+  if(err) goto facility_error;
+
+  return 0;
+
+facility_error:
+name_error:
+  return 1;
+}
+
+static void ltt_fac_ids_destroy(gpointer data)
+{
+  GArray *fac_ids = (GArray *)data;
+
+  g_array_free(fac_ids, TRUE);
+}
+
+
+/* Presumes the tracefile is already seeked at the beginning. It makes sense,
+ * because it must be done just after the opening */
+static int ltt_process_facility_tracefile(LttTracefile *tf)
+{
+  int err;
+  LttFacility *fac;
+  GArray *fac_ids;
+  guint i;
+  LttEventType *et;
+  
+  while(1) {
+    err = ltt_tracefile_read_seek(tf);
+    if(err == EPERM) goto seek_error;
+    else if(err == ERANGE) break; /* End of tracefile */
+
+    err = ltt_tracefile_read_update_event(tf);
+    if(err) goto update_error;
+
+    /* We are on a facility load/or facility unload/ or heartbeat event */
+    /* The rules are :
+     * * facility 0 is hardcoded : this is the core facility. It will be shown
+     *   in the facility array though, and is shown as "loaded builtin" in the
+     *   trace.
+     * It contains event :
+     *  0 : facility load
+     *  1 : facility unload
+     *  2 : state dump facility load
+     *  3 : heartbeat
+     */
+    if(tf->event.facility_id != LTT_FACILITY_CORE) {
+      /* Should only contain core facility */
+      g_warning("Error in processing facility file %s, "
+          "should not contain facility id  %u.", g_quark_to_string(tf->name),
+          tf->event.facility_id);
+      err = EPERM;
+      goto fac_id_error;
+    } else {
+    
+      struct LttFacilityLoad *fac_load_data;
+      struct LttStateDumpFacilityLoad *fac_state_dump_load_data;
+      char *fac_name;
+
+      // FIXME align
+      switch((enum ltt_core_events)tf->event.event_id) {
+        case LTT_EVENT_FACILITY_LOAD:
+          fac_name = (char*)(tf->event.data);
+          g_debug("Doing LTT_EVENT_FACILITY_LOAD of facility %s",
+              fac_name);
+          fac_load_data =
+            (struct LttFacilityLoad *)
+                (tf->event.data + strlen(fac_name) + 1);
+          fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
+              ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id));
+          /* facility may already exist if trace is paused/unpaused */
+          if(fac->exists) continue;
+          fac->name = g_quark_from_string(fac_name);
+          fac->checksum = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_load_data->checksum);
+          fac->id = ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id);
+          fac->pointer_size = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_load_data->pointer_size);
+          fac->long_size = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_load_data->long_size);
+          fac->size_t_size = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_load_data->size_t_size);
+          fac->alignment = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_load_data->alignment);
+
+          if(ltt_get_facility_description(fac, tf->trace, tf))
+            continue; /* error opening description */
+          
+          fac->trace = tf->trace;
+
+          /* Preset the field offsets */
+          for(i=0; i<fac->events->len; i++){
+            et = &g_array_index(fac->events, LttEventType, i);
+            set_fields_offsets(tf, et);
+          }
+
+          fac->exists = 1;
+
+          fac_ids = g_datalist_id_get_data(&tf->trace->facilities_by_name,
+                                fac->name);
+          if(fac_ids == NULL) {
+            fac_ids = g_array_sized_new (FALSE, TRUE, sizeof(guint), 1);
+            g_datalist_id_set_data_full(&tf->trace->facilities_by_name,
+                                     fac->name,
+                                     fac_ids, ltt_fac_ids_destroy);
+          }
+          g_array_append_val(fac_ids, fac->id);
+
+          break;
+        case LTT_EVENT_FACILITY_UNLOAD:
+          g_debug("Doing LTT_EVENT_FACILITY_UNLOAD");
+          /* We don't care about unload : facilities ID are valid for the whole
+           * trace. They simply won't be used after the unload. */
+          break;
+        case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
+          fac_name = (char*)(tf->event.data);
+          g_debug("Doing LTT_EVENT_STATE_DUMP_FACILITY_LOAD of facility %s",
+              fac_name);
+          fac_state_dump_load_data =
+            (struct LttStateDumpFacilityLoad *)
+                (tf->event.data + strlen(fac_name) + 1);
+          fac = &g_array_index (tf->trace->facilities_by_num, LttFacility,
+              ltt_get_uint32(LTT_GET_BO(tf), &fac_state_dump_load_data->id));
+          /* facility may already exist if trace is paused/unpaused */
+          if(fac->exists) continue;
+          fac->name = g_quark_from_string(fac_name);
+          fac->checksum = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_state_dump_load_data->checksum);
+          fac->id = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_state_dump_load_data->id);
+          fac->pointer_size = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_state_dump_load_data->pointer_size);
+          fac->long_size = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_state_dump_load_data->long_size);
+          fac->size_t_size = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_state_dump_load_data->size_t_size);
+          fac->alignment = ltt_get_uint32(LTT_GET_BO(tf),
+                          &fac_state_dump_load_data->alignment);
+          if(ltt_get_facility_description(fac, tf->trace, tf))
+            continue; /* error opening description */
+          
+          fac->trace = tf->trace;
+
+          /* Preset the field offsets */
+          for(i=0; i<fac->events->len; i++){
+            et = &g_array_index(fac->events, LttEventType, i);
+            set_fields_offsets(tf, et);
+          }
+
+          fac->exists = 1;
+          
+          fac_ids = g_datalist_id_get_data(&tf->trace->facilities_by_name,
+              fac->name);
+          if(fac_ids == NULL) {
+            fac_ids = g_array_sized_new (FALSE, TRUE, sizeof(guint), 1);
+            g_datalist_id_set_data_full(&tf->trace->facilities_by_name,
+                                     fac->name,
+                                     fac_ids, ltt_fac_ids_destroy);
+          }
+          g_array_append_val(fac_ids, fac->id);
+
+          break;
+        case LTT_EVENT_HEARTBEAT:
+          break;
+        default:
+          g_warning("Error in processing facility file %s, "
+              "unknown event id %hhu in core facility.",
+              g_quark_to_string(tf->name),
+              tf->event.event_id);
+          err = EPERM;
+          goto event_id_error;
+      }
+    }
+  }
+  return 0;
+
+  /* Error handling */
+event_id_error:
+fac_id_error:
+update_error:
+seek_error:
+  g_warning("An error occured in facility tracefile parsing");
+  return err;
+}
+
+
+LttTrace *ltt_trace_open(const gchar *pathname)
+{
+  gchar abs_path[PATH_MAX];
+  LttTrace  * t;
+  LttTracefile *tf;
+  GArray *group;
+  int i, ret;
+  struct ltt_block_start_header *header;
+       DIR *dir;
+       struct dirent *entry;
+  guint control_found = 0;
+  guint eventdefs_found = 0;
+       struct stat stat_buf;
+  gchar path[PATH_MAX];
+  
+  t = g_new(LttTrace, 1);
+  if(!t) goto alloc_error;
+
+  get_absolute_pathname(pathname, abs_path);
+  t->pathname = g_quark_from_string(abs_path);
+
+  g_datalist_init(&t->tracefiles);
+
+  /* Test to see if it looks like a trace */
+       dir = opendir(abs_path);
+       if(dir == NULL) {
+               perror(abs_path);
+               goto open_error;
+       }
+       while((entry = readdir(dir)) != NULL) {
+    strcpy(path, abs_path);
+    strcat(path, "/");
+    strcat(path, entry->d_name);
+               ret = stat(path, &stat_buf);
+               if(ret == -1) {
+                       perror(path);
+                       continue;
+               }
+               if(S_ISDIR(stat_buf.st_mode)) {
+      if(strcmp(entry->d_name, "control") == 0) {
+        control_found = 1;
+      }
+      if(strcmp(entry->d_name, "eventdefs") == 0) {
+        eventdefs_found = 1;
+      }
+    }
+  }
+  closedir(dir);
+  
+  if(!control_found || !eventdefs_found) goto find_error;
+  
+  /* Open all the tracefiles */
+  if(open_tracefiles(t, abs_path, "")) {
+    g_warning("Error opening tracefile %s", abs_path);
+    goto find_error;
+  }
+  
+  /* Prepare the facilities containers : array and mapping */
+  /* Array is zeroed : the "exists" field is set to false by default */
+  t->facilities_by_num = g_array_sized_new (FALSE, 
+                                            TRUE, sizeof(LttFacility),
+                                            NUM_FACILITIES);
+  t->facilities_by_num = g_array_set_size(t->facilities_by_num, NUM_FACILITIES);
+
+  g_datalist_init(&t->facilities_by_name);
+  
+  /* Parse each trace control/facilitiesN files : get runtime fac. info */
+  group = g_datalist_id_get_data(&t->tracefiles, LTT_TRACEFILE_NAME_FACILITIES);
+  if(group == NULL) {
+    g_error("Trace %s has no facility tracefile", abs_path);
+    g_assert(0);
+    goto facilities_error;
+  }
+
+  /* Get the trace information for the control/facility 0 tracefile */
+  g_assert(group->len > 0);
+  tf = &g_array_index (group, LttTracefile, 0);
+  header = (struct ltt_block_start_header*)tf->buffer.head;
+  g_assert(parse_trace_header(header->trace,
+                                  tf, t) == 0);
+
+  t->num_cpu = group->len;
+  
+  for(i=0; i<group->len; i++) {
+    tf = &g_array_index (group, LttTracefile, i);
+    if(ltt_process_facility_tracefile(tf))
+      goto facilities_error;
+  }
+  
+  return t;
+
+  /* Error handling */
+facilities_error:
+  g_datalist_clear(&t->facilities_by_name);
+  g_array_free(t->facilities_by_num, TRUE);
+find_error:
+  g_datalist_clear(&t->tracefiles);
+open_error:
+  g_free(t);
+alloc_error:
+  return NULL;
+
+}
+
+GQuark ltt_trace_name(const LttTrace *t)
+{
+  return t->pathname;
+}
+
+
+/******************************************************************************
+ * When we copy a trace, we want all the opening actions to happen again :
+ * the trace will be reopened and totally independant from the original.
+ * That's why we call ltt_trace_open.
+ *****************************************************************************/
+LttTrace *ltt_trace_copy(LttTrace *self)
+{
+  return ltt_trace_open(g_quark_to_string(self->pathname));
+}
+
+void ltt_trace_close(LttTrace *t)
+{
+  guint i;
+  LttFacility *fac;
+
+  for(i=0; i<t->facilities_by_num->len; i++) {
+    fac = &g_array_index (t->facilities_by_num, LttFacility, i);
+    if(fac->exists)
+      ltt_facility_close(fac);
+  }
+
+  g_datalist_clear(&t->facilities_by_name);
+  g_array_free(t->facilities_by_num, TRUE);
+  g_datalist_clear(&t->tracefiles);
+  g_free(t);
+}
+
+
+/*****************************************************************************
+ *Get the system description of the trace
+ ****************************************************************************/
+
+LttFacility *ltt_trace_facility_by_id(LttTrace *t, guint8 id)
+{
+  g_assert(id < t->facilities_by_num->len);
+  return &g_array_index(t->facilities_by_num, LttFacility, id);
+}
+
+/* ltt_trace_facility_get_by_name
+ *
+ * Returns the GArray of facility indexes. All the fac_ids that matches the
+ * requested facility name.
+ *
+ * If name is not found, returns NULL.
+ */
+GArray *ltt_trace_facility_get_by_name(LttTrace *t, GQuark name)
+{
+  return g_datalist_id_get_data(&t->facilities_by_name, name);
+}
+
+/*****************************************************************************
+ * Functions to discover all the event types in the trace 
+ ****************************************************************************/
+
+#if 0
+unsigned ltt_trace_eventtype_number(LttTrace *t)
+{
+  unsigned int i;
+  unsigned count = 0;
+  unsigned int num = t->facility_number;
+  LttFacility * f;
+  
+  for(i=0;i<num;i++){
+    f = (LttFacility*)g_ptr_array_index(t->facilities, i);
+    count += f->event_number;
+  }
+  return count;
+}
+#endif //0
+
+#if 0
+//use an iteration on all the trace facilities, and inside iteration on all the
+//event types in each facilities instead.
+LttEventType *ltt_trace_eventtype_get(LttTrace *t, unsigned evId)
+{
+  LttEventType *event_type;
+  
+  LttFacility * f;
+  f = ltt_trace_facility_by_id(t,evId);
+
+  if(unlikely(!f)) event_type = NULL;
+  else event_type = f->events[evId - f->base_id];
+
+  return event_type;
+}
+#endif //0
+
+#if 0
+/*****************************************************************************
+ * ltt_trace_find_tracefile
+ *
+ * Find a tracefile by name and index in the group.
+ *
+ * Returns a pointer to the tracefiles, else NULL.
+ ****************************************************************************/
+
+LttTracefile *ltt_trace_find_tracefile(LttTrace *t, const gchar *name)
+{
+}
+#endif //0
+
+/*****************************************************************************
+ * Get the start time and end time of the trace 
+ ****************************************************************************/
+
+static void ltt_tracefile_time_span_get(LttTracefile *tf,
+                                        LttTime *start, LttTime *end)
+{
+  int err;
+
+  err = map_block(tf, 0);
+  if(unlikely(err)) {
+    g_error("Can not map block");
+    *start = ltt_time_infinite;
+  } else
+    *start = tf->buffer.begin.timestamp;
+
+  err = map_block(tf, tf->num_blocks - 1);  /* Last block */
+  if(unlikely(err)) {
+    g_error("Can not map block");
+    *end = ltt_time_zero;
+  } else
+    *end = tf->buffer.end.timestamp;
+}
+
+struct tracefile_time_span_get_args {
+  LttTrace *t;
+  LttTime *start;
+  LttTime *end;
+};
+
+static void group_time_span_get(GQuark name, gpointer data, gpointer user_data)
+{
+  struct tracefile_time_span_get_args *args =
+          (struct tracefile_time_span_get_args*)user_data;
+
+  GArray *group = (GArray *)data;
+  int i;
+  LttTracefile *tf;
+  LttTime tmp_start;
+  LttTime tmp_end;
+
+  for(i=0; i<group->len; i++) {
+    tf = &g_array_index (group, LttTracefile, i);
+    if(tf->cpu_online) {
+      ltt_tracefile_time_span_get(tf, &tmp_start, &tmp_end);
+      if(ltt_time_compare(*args->start, tmp_start)>0) *args->start = tmp_start;
+      if(ltt_time_compare(*args->end, tmp_end)<0) *args->end = tmp_end;
+    }
+  }
+}
+
+void ltt_trace_time_span_get(LttTrace *t, LttTime *start, LttTime *end)
+{
+  LttTime min_start = ltt_time_infinite;
+  LttTime max_end = ltt_time_zero;
+  struct tracefile_time_span_get_args args = { t, &min_start, &max_end };
+
+  g_datalist_foreach(&t->tracefiles, &group_time_span_get, &args);
+  
+  if(start != NULL) *start = min_start;
+  if(end != NULL) *end = max_end;
+  
+}
+
+
+/*****************************************************************************
+ *Get the name of a tracefile
+ ****************************************************************************/
+
+GQuark ltt_tracefile_name(const LttTracefile *tf)
+{
+  return tf->name;
+}
+
+GQuark ltt_tracefile_long_name(const LttTracefile *tf)
+{
+  return tf->long_name;
+}
+
+
+
+guint ltt_tracefile_num(LttTracefile *tf)
+{
+  return tf->cpu_num;
+}
+
+/*****************************************************************************
+ * Get the number of blocks in the tracefile 
+ ****************************************************************************/
+
+guint ltt_tracefile_block_number(LttTracefile *tf)
+{
+  return tf->num_blocks; 
+}
+
+
+/* Seek to the first event in a tracefile that has a time equal or greater than
+ * the time passed in parameter.
+ *
+ * If the time parameter is outside the tracefile time span, seek to the first
+ * event or if after, return ERANGE.
+ *
+ * If the time parameter is before the first event, we have to seek specially to
+ * there.
+ *
+ * If the time is after the end of the trace, return ERANGE.
+ *
+ * Do a binary search to find the right block, then a sequential search in the
+ * block to find the event. 
+ *
+ * In the special case where the time requested fits inside a block that has no
+ * event corresponding to the requested time, the first event of the next block
+ * will be seeked.
+ *
+ * IMPORTANT NOTE : // FIXME everywhere...
+ *
+ * You MUST NOT do a ltt_tracefile_read right after a ltt_tracefile_seek_time :
+ * you will jump over an event if you do.
+ *
+ * Return value : 0 : no error, the tf->event can be used
+ *                ERANGE : time if after the last event of the trace
+ *                otherwise : this is an error.
+ *
+ * */
+
+int ltt_tracefile_seek_time(LttTracefile *tf, LttTime time)
+{
+  int ret = 0;
+  int err;
+  unsigned int block_num, high, low;
+
+  /* seek at the beginning of trace */
+  err = map_block(tf, 0);  /* First block */
+  if(unlikely(err)) {
+    g_error("Can not map block");
+    goto fail;
+  }
+
+ /* If the time is lower or equal the beginning of the trace,
+  * go to the first event. */
+  if(ltt_time_compare(time, tf->buffer.begin.timestamp) <= 0) {
+    ret = ltt_tracefile_read(tf);
+    if(ret == ERANGE) goto range;
+    else if (ret) goto fail;
+    goto found; /* There is either no event in the trace or the event points
+                   to the first event in the trace */
+  }
+
+  err = map_block(tf, tf->num_blocks - 1);  /* Last block */
+  if(unlikely(err)) {
+    g_error("Can not map block");
+    goto fail;
+  }
+
+ /* If the time is after the end of the trace, return ERANGE. */
+  if(ltt_time_compare(time, tf->buffer.end.timestamp) > 0) {
+    goto range;
+  }
+
+  /* Binary search the block */
+  high = tf->num_blocks - 1;
+  low = 0;
+  
+  while(1) {
+    block_num = ((high-low) / 2) + low;
+
+    err = map_block(tf, block_num);
+    if(unlikely(err)) {
+      g_error("Can not map block");
+      goto fail;
+    }
+    if(high == low) {
+      /* We cannot divide anymore : this is what would happen if the time
+       * requested was exactly between two consecutive buffers'end and start 
+       * timestamps. This is also what would happend if we didn't deal with out
+       * of span cases prior in this function. */
+      /* The event is right in the buffer!
+       * (or in the next buffer first event) */
+      while(1) {
+        ret = ltt_tracefile_read(tf);
+        if(ret == ERANGE) goto range; /* ERANGE or EPERM */
+        else if(ret) goto fail;
+
+        if(ltt_time_compare(time, tf->event.event_time) <= 0)
+          goto found;
+      }
+
+    } else if(ltt_time_compare(time, tf->buffer.begin.timestamp) < 0) {
+      /* go to lower part */
+      high = block_num - 1;
+    } else if(ltt_time_compare(time, tf->buffer.end.timestamp) > 0) {
+      /* go to higher part */
+      low = block_num + 1;
+    } else {/* The event is right in the buffer!
+               (or in the next buffer first event) */
+      while(1) {
+        ret = ltt_tracefile_read(tf);
+        if(ret == ERANGE) goto range; /* ERANGE or EPERM */
+        else if(ret) goto fail;
+
+        if(ltt_time_compare(time, tf->event.event_time) <= 0)
+          break;
+      }
+      goto found;
+    }
+  }
+
+found:
+  return 0;
+range:
+  return ERANGE;
+
+  /* Error handling */
+fail:
+  g_error("ltt_tracefile_seek_time failed on tracefile %s", 
+      g_quark_to_string(tf->name));
+  return EPERM;
+}
+
+
+int ltt_tracefile_seek_position(LttTracefile *tf, const LttEventPosition *ep) {
+  
+  int err;
+  
+  if(ep->tracefile != tf) {
+    goto fail;
+  }
+
+  err = map_block(tf, ep->block);
+  if(unlikely(err)) {
+    g_error("Can not map block");
+    goto fail;
+  }
+
+  tf->event.offset = ep->offset;
+
+  err = ltt_tracefile_read_update_event(tf);
+  if(err) goto fail;
+  err = ltt_tracefile_read_op(tf);
+  if(err) goto fail;
+
+  return 0;
+
+fail:
+  g_error("ltt_tracefile_seek_time failed on tracefile %s", 
+      g_quark_to_string(tf->name));
+  return 1;
+}
+
+/* Calculate the real event time based on the buffer boundaries */
+LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event)
+{
+  LttTime time;
+
+  g_assert(tf->trace->has_tsc);
+
+//  time = ltt_time_from_uint64(
+//      cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count)));
+  time = ltt_time_from_uint64(
+      (double)(tf->buffer.tsc - tf->trace->start_tsc) * 1000000.0
+                                  / (double)tf->trace->start_freq);
+  //time = ltt_time_add(tf->buffer.begin.timestamp, time);
+  time = ltt_time_add(tf->trace->start_time_from_tsc, time);
+
+  return time;
+}
+
+
+/* Get the current event of the tracefile : valid until the next read */
+LttEvent *ltt_tracefile_get_event(LttTracefile *tf)
+{
+  return &tf->event;
+}
+
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_tracefile_read : Read the next event in the tracefile
+ *Input params
+ *    t                  : tracefile
+ *Return value
+ *
+ *    Returns 0 if an event can be used in tf->event.
+ *    Returns ERANGE on end of trace. The event in tf->event still can be used
+ *    (if the last block was not empty).
+ *    Returns EPERM on error.
+ *
+ *    This function does make the tracefile event structure point to the event
+ *    currently pointed to by the tf->event.
+ *
+ *    Note : you must call a ltt_tracefile_seek to the beginning of the trace to
+ *    reinitialize it after an error if you want results to be coherent.
+ *    It would be the case if a end of trace last buffer has no event : the end
+ *    of trace wouldn't be returned, but an error.
+ *    We make the assumption there is at least one event per buffer.
+ ****************************************************************************/
+
+int ltt_tracefile_read(LttTracefile *tf)
+{
+  int err;
+
+  err = ltt_tracefile_read_seek(tf);
+  if(err) return err;
+  err = ltt_tracefile_read_update_event(tf);
+  if(err) return err;
+  err = ltt_tracefile_read_op(tf);
+  if(err) return err;
+
+  return 0;
+}
+
+int ltt_tracefile_read_seek(LttTracefile *tf)
+{
+  int err;
+
+  /* Get next buffer until we finally have an event, or end of trace */
+  while(1) {
+    err = ltt_seek_next_event(tf);
+    if(unlikely(err == ENOPROTOOPT)) {
+      return EPERM;
+    }
+
+    /* Are we at the end of the buffer ? */
+    if(err == ERANGE) {
+      if(unlikely(tf->buffer.index == tf->num_blocks-1)){ /* end of trace ? */
+        return ERANGE;
+      } else {
+        /* get next block */
+        err = map_block(tf, tf->buffer.index + 1);
+        if(unlikely(err)) {
+          g_error("Can not map block");
+          return EPERM;
+        }
+      }
+    } else break; /* We found an event ! */
+  }
+  
+  return 0;
+}
+
+
+/* do specific operation on events */
+int ltt_tracefile_read_op(LttTracefile *tf)
+{
+  LttEvent *event;
+
+  event = &tf->event;
+
+   /* do event specific operation */
+
+  /* do something if its an heartbeat event : increment the heartbeat count */
+  //if(event->facility_id == LTT_FACILITY_CORE)
+  //  if(event->event_id == LTT_EVENT_HEARTBEAT)
+  //    tf->cur_heart_beat_number++;
+  
+  return 0;
+}
+
+
+/* same as ltt_tracefile_read, but does not seek to the next event nor call
+ * event specific operation. */
+int ltt_tracefile_read_update_event(LttTracefile *tf)
+{
+  void * pos;
+  LttEvent *event;
+  event = &tf->event;
+  pos = tf->buffer.head + event->offset;
+
+  /* Read event header */
+  
+  //TODO align
+  
+  if(tf->trace->has_tsc) {
+    if(tf->trace->has_heartbeat) {
+      event->time.timestamp = ltt_get_uint32(LTT_GET_BO(tf),
+                                            pos);
+      /* 32 bits -> 64 bits tsc */
+      /* note : still works for seek and non seek cases. */
+      if(event->time.timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
+        tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+                            + 0x100000000ULL)
+                                | (guint64)event->time.timestamp;
+        event->tsc = tf->buffer.tsc;
+      } else {
+        /* no overflow */
+        tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) 
+                                | (guint64)event->time.timestamp;
+        event->tsc = tf->buffer.tsc;
+      }
+      pos += sizeof(guint32);
+    } else {
+      event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
+      tf->buffer.tsc = event->tsc;
+      pos += sizeof(guint64);
+    }
+    
+    event->event_time = ltt_interpolate_time(tf, event);
+  } else {
+    event->time.delta.tv_sec = 0;
+    event->time.delta.tv_nsec = ltt_get_uint32(LTT_GET_BO(tf),
+                                          pos) * NSEC_PER_USEC;
+    tf->buffer.tsc = 0;
+    event->tsc = tf->buffer.tsc;
+
+    event->event_time = ltt_time_add(tf->buffer.begin.timestamp,
+                                     event->time.delta);
+    pos += sizeof(guint32);
+  }
+
+  event->facility_id = *(guint8*)pos;
+  pos += sizeof(guint8);
+
+  event->event_id = *(guint8*)pos;
+  pos += sizeof(guint8);
+
+  event->event_size = ltt_get_uint16(LTT_GET_BO(tf), pos);
+  pos += sizeof(guint16);
+  
+  event->data = pos;
+
+  /* get the data size and update the event fields with the current
+   * information */
+  ltt_update_event_size(tf);
+
+  return 0;
+}
+
+
+/****************************************************************************
+ *Function name
+ *    map_block       : map a block from the file
+ *Input Params
+ *    lttdes          : ltt trace file 
+ *    whichBlock      : the block which will be read
+ *return value 
+ *    0               : success
+ *    EINVAL          : lseek fail
+ *    EIO             : can not read from the file
+ ****************************************************************************/
+
+static gint map_block(LttTracefile * tf, guint block_num)
+{
+  int page_size = getpagesize();
+  struct ltt_block_start_header *header;
+
+  g_assert(block_num < tf->num_blocks);
+
+  if(tf->buffer.head != NULL) {
+    if(munmap(tf->buffer.head, PAGE_ALIGN(tf->buf_size))) {
+    g_warning("unmap size : %u\n",
+        PAGE_ALIGN(tf->buf_size));
+      perror("munmap error");
+      g_assert(0);
+    }
+  }
+    
+  
+  /* Multiple of pages aligned head */
+  tf->buffer.head = mmap(0,
+      PAGE_ALIGN(tf->buf_size),
+      PROT_READ, MAP_PRIVATE, tf->fd,
+      PAGE_ALIGN((off_t)tf->buf_size * (off_t)block_num));
+
+  if(tf->buffer.head == MAP_FAILED) {
+    perror("Error in allocating memory for buffer of tracefile");
+    g_assert(0);
+    goto map_error;
+  }
+  g_assert( ( (guint)tf->buffer.head&(8-1) ) == 0); // make sure it's aligned.
+  
+
+  tf->buffer.index = block_num;
+
+  header = (struct ltt_block_start_header*)tf->buffer.head;
+
+#if 0
+  tf->buffer.begin.timestamp = ltt_time_add(
+                                ltt_time_from_uint64(
+                                 ltt_get_uint64(LTT_GET_BO(tf),
+                                  &header->begin.timestamp)
+                                    - tf->trace->start_monotonic),
+                                  tf->trace->start_time);
+#endif //0
+  //g_debug("block %u begin : %lu.%lu", block_num,
+  //    tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec);
+  tf->buffer.begin.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
+                                              &header->begin.cycle_count);
+  tf->buffer.begin.freq = ltt_get_uint64(LTT_GET_BO(tf),
+                                         &header->begin.freq);
+  tf->buffer.begin.timestamp = ltt_time_add(
+                                ltt_time_from_uint64(
+                                  (double)(tf->buffer.begin.cycle_count
+                                  - tf->trace->start_tsc) * 1000000.0
+                                    / (double)tf->trace->start_freq),
+                                tf->trace->start_time_from_tsc);
+#if 0
+
+  tf->buffer.end.timestamp = ltt_time_add(
+                                ltt_time_from_uint64(
+                                 ltt_get_uint64(LTT_GET_BO(tf),
+                                  &header->end.timestamp)
+                                    - tf->trace->start_monotonic),
+                                  tf->trace->start_time);
+#endif //0
+  //g_debug("block %u end : %lu.%lu", block_num,
+  //    tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec);
+  tf->buffer.end.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
+                                              &header->end.cycle_count);
+  tf->buffer.end.freq = ltt_get_uint64(LTT_GET_BO(tf),
+                                       &header->end.freq);
+  tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf),
+                                        &header->lost_size);
+  tf->buffer.end.timestamp = ltt_time_add(
+                                ltt_time_from_uint64(
+                                  (double)(tf->buffer.end.cycle_count
+                                  - tf->trace->start_tsc) * 1000000.0
+                                    / (double)tf->trace->start_freq),
+                                tf->trace->start_time_from_tsc);
+  tf->buffer.tsc =  tf->buffer.begin.cycle_count;
+  tf->event.tsc = tf->buffer.tsc;
+  tf->buffer.freq = tf->buffer.begin.freq;
+
+  /* FIXME
+   * eventually support variable buffer size : will need a partial pre-read of
+   * the headers to create an index when we open the trace... eventually. */
+  g_assert(tf->buf_size  == ltt_get_uint32(LTT_GET_BO(tf), 
+                                             &header->buf_size));
+  
+  /* Now that the buffer is mapped, calculate the time interpolation for the
+   * block. */
+  
+//  tf->buffer.nsecs_per_cycle = calc_nsecs_per_cycle(tf);
+  //tf->buffer.cyc2ns_scale = calc_nsecs_per_cycle(tf);
+  /* Make the current event point to the beginning of the buffer :
+   * it means that the event read must get the first event. */
+  tf->event.tracefile = tf;
+  tf->event.block = block_num;
+  tf->event.offset = 0;
+  
+  return 0;
+
+map_error:
+  return -errno;
+
+}
+
+/* It will update the fields offsets too */
+void ltt_update_event_size(LttTracefile *tf)
+{
+  ssize_t size = 0;
+
+  /* Specific handling of core events : necessary to read the facility control
+   * tracefile. */
+  LttFacility *f = ltt_trace_get_facility_by_num(tf->trace, 
+                                          tf->event.facility_id);
+
+  if(likely(tf->event.facility_id == LTT_FACILITY_CORE)) {
+    switch((enum ltt_core_events)tf->event.event_id) {
+  case LTT_EVENT_FACILITY_LOAD:
+    size = strlen((char*)tf->event.data) + 1;
+    //g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
+    size += sizeof(struct LttFacilityLoad);
+    break;
+  case LTT_EVENT_FACILITY_UNLOAD:
+    //g_debug("Update Event facility unload");
+    size = sizeof(struct LttFacilityUnload);
+    break;
+  case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
+    size = strlen((char*)tf->event.data) + 1;
+    //g_debug("Update Event facility load state dump of facility %s",
+    //    (char*)tf->event.data);
+    size += sizeof(struct LttStateDumpFacilityLoad);
+    break;
+  case LTT_EVENT_HEARTBEAT:
+    //g_debug("Update Event heartbeat");
+    size = sizeof(TimeHeartbeat);
+    break;
+  default:
+    g_warning("Error in getting event size : tracefile %s, "
+        "unknown event id %hhu in core facility.",
+        g_quark_to_string(tf->name),
+        tf->event.event_id);
+    goto event_id_error;
+
+    }
+  } else {
+    if(!f->exists) {
+      g_error("Unknown facility %hhu (0x%hhx) in tracefile %s",
+          tf->event.facility_id,
+          tf->event.facility_id,
+          g_quark_to_string(tf->name));
+      goto facility_error;
+    }
+
+    LttEventType *event_type = 
+      ltt_facility_eventtype_get(f, tf->event.event_id);
+
+    if(!event_type) {
+      g_error("Unknown event id %hhu in facility %s in tracefile %s",
+          tf->event.event_id,
+          g_quark_to_string(f->name),
+          g_quark_to_string(tf->name));
+      goto event_type_error;
+    }
+    if(event_type->root_field)
+      size = get_field_type_size(tf, event_type,
+          0, 0, event_type->root_field, tf->event.data);
+    else
+      size = 0;
+
+    //g_debug("Event root field : f.e %hhu.%hhu size %zd",
+    //    tf->event.facility_id,
+    //    tf->event.event_id, size);
+  }
+  
+  tf->event.data_size = size;
+  
+  /* Check consistency between kernel and LTTV structure sizes */
+  g_assert(tf->event.data_size == tf->event.event_size);
+
+  return;
+
+facility_error:
+event_type_error:
+event_id_error:
+  tf->event.data_size = 0;
+}
+
+
+/* Take the tf current event offset and use the event facility id and event id
+ * to figure out where is the next event offset.
+ *
+ * This is an internal function not aiming at being used elsewhere : it will
+ * not jump over the current block limits. Please consider using
+ * ltt_tracefile_read to do this.
+ *
+ * Returns 0 on success
+ *         ERANGE if we are at the end of the buffer.
+ *         ENOPROTOOPT if an error occured when getting the current event size.
+ */
+static int ltt_seek_next_event(LttTracefile *tf)
+{
+  int ret = 0;
+  void *pos;
+  
+  /* seek over the buffer header if we are at the buffer start */
+  if(tf->event.offset == 0) {
+    tf->event.offset += tf->buffer_header_size;
+
+    if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) {
+      ret = ERANGE;
+    }
+    goto found;
+  }
+
+  
+  pos = tf->event.data;
+
+  if(tf->event.data_size < 0) goto error;
+
+  pos += (size_t)tf->event.data_size;
+  
+  tf->event.offset = pos - tf->buffer.head;
+  
+  if(tf->event.offset == tf->buf_size - tf->buffer.lost_size) {
+    ret = ERANGE;
+    goto found;
+  }
+  g_assert(tf->event.offset < tf->buf_size - tf->buffer.lost_size);
+
+found:
+  return ret;
+
+error:
+  g_error("Error in ltt_seek_next_event for tracefile %s",
+      g_quark_to_string(tf->name));
+  return ENOPROTOOPT;
+}
+
+#if 0
+/*****************************************************************************
+ *Function name
+ *    calc_nsecs_per_cycle : calculate nsecs per cycle for current block
+ *
+ *    1.0 / (freq(khz) *1000)  * 1000000000
+ *Input Params
+ *    t               : tracefile
+ ****************************************************************************/
+/* from timer_tsc.c */
+#define CYC2NS_SCALE_FACTOR 10
+static guint32 calc_nsecs_per_cycle(LttTracefile * tf)
+{
+  //return 1e6 / (double)tf->buffer.freq;
+  guint32 cpu_mhz = tf->buffer.freq / 1000;
+  guint32 cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+  
+  return cyc2ns_scale;
+ // return 1e6 / (double)tf->buffer.freq;
+}
+
+static guint64 cycles_2_ns(LttTracefile *tf, guint64 cycles)
+{
+  return (cycles * tf->buffer.cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+}
+#endif //0
+
+#if 0
+void setFieldsOffset(LttTracefile *tf, LttEventType *evT,void *evD)
+{
+  LttField * rootFld = evT->root_field;
+  //  rootFld->base_address = evD;
+
+  if(likely(rootFld))
+    rootFld->field_size = getFieldtypeSize(tf, evT->facility,
+        evT, 0,0,rootFld, evD);  
+}
+#endif //0
+
+/*****************************************************************************
+ *Function name
+ *    set_fields_offsets : set the precomputable offset of the fields
+ *Input params 
+ *    tracefile       : opened trace file  
+ *    event_type      : the event type
+ ****************************************************************************/
+
+void set_fields_offsets(LttTracefile *tf, LttEventType *event_type)
+{
+  LttField *field = event_type->root_field;
+  enum field_status fixed_root = FIELD_FIXED, fixed_parent = FIELD_FIXED;
+
+  if(likely(field))
+    preset_field_type_size(tf, event_type, 0, 0, 
+        &fixed_root, &fixed_parent,
+        field);
+
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    preset_field_type_size : set the fixed sizes of the field type
+ *Input params 
+ *    tf              : tracefile
+ *    event_type      : event type
+ *    offset_root     : offset from the root
+ *    offset_parent   : offset from the parent
+ *    fixed_root      : Do we know a fixed offset to the root ?
+ *    fixed_parent    : Do we know a fixed offset to the parent ?
+ *    field           : field
+ ****************************************************************************/
+void preset_field_type_size(LttTracefile *tf, LttEventType *event_type,
+    off_t offset_root, off_t offset_parent,
+    enum field_status *fixed_root, enum field_status *fixed_parent,
+    LttField *field)
+{
+  enum field_status local_fixed_root, local_fixed_parent;
+  guint i;
+  LttType *type;
+  
+  g_assert(field->fixed_root == FIELD_UNKNOWN);
+  g_assert(field->fixed_parent == FIELD_UNKNOWN);
+  g_assert(field->fixed_size == FIELD_UNKNOWN);
+
+  type = field->field_type;
+
+  field->fixed_root = *fixed_root;
+  if(field->fixed_root == FIELD_FIXED)
+    field->offset_root = offset_root;
+  else
+    field->offset_root = 0;
+
+  field->fixed_parent = *fixed_parent;
+  if(field->fixed_parent == FIELD_FIXED)
+    field->offset_parent = offset_parent;
+  else
+    field->offset_parent = 0;
+
+  size_t current_root_offset;
+  size_t current_offset;
+  enum field_status current_child_status, final_child_status;
+  size_t max_size;
+
+  switch(type->type_class) {
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_FLOAT:
+    case LTT_ENUM:
+      field->field_size = ltt_type_size(tf->trace, type);
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_POINTER:
+      field->field_size = (off_t)event_type->facility->pointer_size; 
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_LONG:
+    case LTT_ULONG:
+      field->field_size = (off_t)event_type->facility->long_size; 
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+      field->field_size = (off_t)event_type->facility->size_t_size; 
+      field->fixed_size = FIELD_FIXED;
+      break;
+    case LTT_SEQUENCE:
+      local_fixed_root = FIELD_VARIABLE;
+      local_fixed_parent = FIELD_VARIABLE;
+      preset_field_type_size(tf, event_type,
+        0, 0, 
+        &local_fixed_root, &local_fixed_parent,
+        field->child[0]);
+      field->fixed_size = FIELD_VARIABLE;
+      field->field_size = 0;
+      *fixed_root = FIELD_VARIABLE;
+      *fixed_parent = FIELD_VARIABLE;
+      break;
+    case LTT_STRING:
+      field->fixed_size = FIELD_VARIABLE;
+      field->field_size = 0;
+      *fixed_root = FIELD_VARIABLE;
+      *fixed_parent = FIELD_VARIABLE;
+      break;
+    case LTT_ARRAY:
+      local_fixed_root = FIELD_VARIABLE;
+      local_fixed_parent = FIELD_VARIABLE;
+      preset_field_type_size(tf, event_type,
+        0, 0, 
+        &local_fixed_root, &local_fixed_parent,
+        field->child[0]);
+      field->fixed_size = field->child[0]->fixed_size;
+      if(field->fixed_size == FIELD_FIXED) {
+        field->field_size = type->element_number * field->child[0]->field_size;
+      } else {
+        field->field_size = 0;
+        *fixed_root = FIELD_VARIABLE;
+        *fixed_parent = FIELD_VARIABLE;
+      }
+      break;
+    case LTT_STRUCT:
+      current_root_offset = field->offset_root;
+      current_offset = 0;
+      current_child_status = FIELD_FIXED;
+      for(i=0;i<type->element_number;i++) {
+        preset_field_type_size(tf, event_type,
+          current_root_offset, current_offset, 
+          fixed_root, &current_child_status,
+          field->child[i]);
+        if(current_child_status == FIELD_FIXED) {
+          current_root_offset += field->child[i]->field_size;
+          current_offset += field->child[i]->field_size;
+        } else {
+          current_root_offset = 0;
+          current_offset = 0;
+        }
+      }
+      if(current_child_status != FIELD_FIXED) {
+        *fixed_parent = current_child_status;
+        field->field_size = 0;
+        field->fixed_size = current_child_status;
+      } else {
+        field->field_size = current_offset;
+        field->fixed_size = FIELD_FIXED;
+      }
+      break;
+    case LTT_UNION:
+      current_root_offset = field->offset_root;
+      current_offset = 0;
+      max_size = 0;
+      final_child_status = FIELD_FIXED;
+      for(i=0;i<type->element_number;i++) {
+        enum field_status current_root_child_status = FIELD_FIXED;
+        enum field_status current_child_status = FIELD_FIXED;
+        preset_field_type_size(tf, event_type,
+          current_root_offset, current_offset, 
+          &current_root_child_status, &current_child_status,
+          field->child[i]);
+        if(current_child_status != FIELD_FIXED)
+          final_child_status = current_child_status;
+        else
+          max_size = max(max_size, field->child[i]->field_size);
+      }
+      if(final_child_status != FIELD_FIXED) {
+        *fixed_root = final_child_status;
+        *fixed_parent = final_child_status;
+        field->field_size = 0;
+        field->fixed_size = current_child_status;
+      } else {
+        field->field_size = max_size;
+        field->fixed_size = FIELD_FIXED;
+      }
+      break;
+  }
+
+}
+
+
+/*****************************************************************************
+ *Function name
+ *    check_fields_compatibility : Check for compatibility between two fields :
+ *    do they use the same inner structure ?
+ *Input params 
+ *    event_type1     : event type
+ *    event_type2     : event type
+ *    field1          : field
+ *    field2          : field
+ *Returns : 0 if identical
+ *          1 if not.
+ ****************************************************************************/
+gint check_fields_compatibility(LttEventType *event_type1,
+    LttEventType *event_type2,
+    LttField *field1, LttField *field2)
+{
+  guint different = 0;
+  guint i;
+  LttType *type1;
+  LttType *type2;
+  
+  if(field1 == NULL) {
+    if(field2 == NULL) goto end;
+    else {
+      different = 1;
+      goto end;
+    }
+  } else if(field2 == NULL) {
+    different = 1;
+    goto end;
+  }
+  
+  g_assert(field1->fixed_root != FIELD_UNKNOWN);
+  g_assert(field2->fixed_root != FIELD_UNKNOWN);
+  g_assert(field1->fixed_parent != FIELD_UNKNOWN);
+  g_assert(field2->fixed_parent != FIELD_UNKNOWN);
+  g_assert(field1->fixed_size != FIELD_UNKNOWN);
+  g_assert(field2->fixed_size != FIELD_UNKNOWN);
+
+  type1 = field1->field_type;
+  type2 = field2->field_type;
+
+  if(type1->type_class != type2->type_class) {
+    different = 1;
+    goto end;
+  }
+  if(type1->element_name != type2->element_name) {
+    different = 1;
+    goto end;
+  }
+    
+  switch(type1->type_class) {
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_FLOAT:
+    case LTT_POINTER:
+    case LTT_LONG:
+    case LTT_ULONG:
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+      if(field1->field_size != field2->field_size) {
+        different = 1;
+        goto end;
+      }
+      break;
+    case LTT_ENUM:
+      if(type1->element_number != type2->element_number) {
+        different = 1;
+        goto end;
+      }
+      for(i=0;i<type1->element_number;i++) {
+        if(type1->enum_strings[i] != type2->enum_strings[i]) {
+          different = 1;
+          goto end;
+        }
+      }
+      break;
+    case LTT_SEQUENCE:
+      /* Two elements : size and child */
+      g_assert(type1->element_number != type2->element_number);
+      for(i=0;i<type1->element_number;i++) {
+        if(check_fields_compatibility(event_type1, event_type2,
+          field1->child[0], field2->child[0])) {
+          different = 1;
+          goto end;
+        }
+      }
+      break;
+    case LTT_STRING:
+      break;
+    case LTT_ARRAY:
+      if(field1->field_size != field2->field_size) {
+        different = 1;
+        goto end;
+      }
+      /* Two elements : size and child */
+      g_assert(type1->element_number != type2->element_number);
+      for(i=0;i<type1->element_number;i++) {
+        if(check_fields_compatibility(event_type1, event_type2,
+          field1->child[0], field2->child[0])) {
+          different = 1;
+          goto end;
+        }
+      }
+      break;
+    case LTT_STRUCT:
+    case LTT_UNION:
+      if(type1->element_number != type2->element_number) {
+        different = 1;
+        break;
+      }
+      for(i=0;i<type1->element_number;i++) {
+        if(check_fields_compatibility(event_type1, event_type2,
+          field1->child[0], field2->child[0])) {
+          different = 1;
+          goto end;
+        }
+      }
+      break;
+  }
+end:
+  return different;
+}
+
+
+
+
+#if 0
+/*****************************************************************************
+ *Function name
+ *    getFieldtypeSize: get the size of the field type (primitive type)
+ *Input params 
+ *    evT             : event type
+ *    offsetRoot      : offset from the root
+ *    offsetParent    : offset from the parrent
+ *    fld             : field
+ *    evD             : event data, it may be NULL
+ *Return value
+ *    int             : size of the field
+ ****************************************************************************/
+
+static inline gint getFieldtypeSize(LttTracefile *tf,
+       LttEventType * evT, gint offsetRoot,
+            gint offsetParent, LttField * fld, void *evD)
+{
+  gint size, size1, element_number, i, offset1, offset2;
+  LttType * type = fld->field_type;
+
+  /* This likely has been tested with gcov : half of them.. */
+  if(unlikely(fld->field_fixed == 1)){
+    /* tested : none */
+    if(unlikely(fld == evT->root_field)) {
+      size = fld->field_size;
+      goto end_getFieldtypeSize;
+    }
+  }
+
+  /* From gcov profiling : half string, half struct, can we gain something
+   * from that ? (Mathieu) */
+  switch(type->type_class) {
+    case LTT_ARRAY:
+      element_number = (int) type->element_number;
+      if(fld->field_fixed == -1){
+        size = getFieldtypeSize(tf, evT, offsetRoot,
+                                0,fld->child[0], NULL);
+        if(size == 0){ //has string or sequence
+          fld->field_fixed = 0;
+        }else{
+          fld->field_fixed = 1;
+          size *= element_number; 
+        }
+      }else if(fld->field_fixed == 0){// has string or sequence
+        size = 0;
+        for(i=0;i<element_number;i++){
+          size += getFieldtypeSize(tf, evT, offsetRoot+size,size, 
+          fld->child[0], evD+size);
+        }
+      }else size = fld->field_size;
+      if(unlikely(!evD)){
+        fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+        fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      }
+
+      break;
+
+    case LTT_SEQUENCE:
+      size1 = (int) ltt_type_size(fac, type);
+      if(fld->field_fixed == -1){
+        fld->sequ_number_size = size1;
+        fld->field_fixed = 0;
+        size = getFieldtypeSize(evT, offsetRoot,
+                                0,fld->child[0], NULL);      
+        fld->element_size = size;
+      }else{//0: sequence
+        element_number = getIntNumber(tf,size1,evD);
+        type->element_number = element_number;
+        if(fld->element_size > 0){
+          size = element_number * fld->element_size;
+        }else{//sequence has string or sequence
+          size = 0;
+          for(i=0;i<element_number;i++){
+            size += getFieldtypeSize(tf, evT,
+                                     offsetRoot+size+size1,size+size1, 
+                                     fld->child[0], evD+size+size1);
+          }
+        }
+        size += size1;
+      }
+      if(unlikely(!evD)){
+        fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+        fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      }
+
+      break;
+      
+    case LTT_STRING:
+      size = 0;
+      if(fld->field_fixed == -1){
+        fld->field_fixed = 0;
+      }else{//0: string
+        /* Hope my implementation is faster than strlen (Mathieu) */
+        char *ptr=(char*)evD;
+        size = 1;
+        /* from gcov : many many strings are empty, make it the common case.*/
+        while(unlikely(*ptr != '\0')) { size++; ptr++; }
+        //size = ptr - (char*)evD + 1; //include end : '\0'
+      }
+      fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+      fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+
+      break;
+      
+    case LTT_STRUCT:
+      element_number = (int) type->element_number;
+      size = 0;
+      /* tested with gcov */
+      if(unlikely(fld->field_fixed == -1)){
+        offset1 = offsetRoot;
+        offset2 = 0;
+        for(i=0;i<element_number;i++){
+          size1=getFieldtypeSize(tf, evT,offset1,offset2,
+                                 fld->child[i], NULL);
+          if(likely(size1 > 0 && size >= 0)){
+            size += size1;
+            if(likely(offset1 >= 0)) offset1 += size1;
+              offset2 += size1;
+          }else{
+            size = -1;
+            offset1 = -1;
+            offset2 = -1;
+          }
+        }
+        if(unlikely(size == -1)){
+           fld->field_fixed = 0;
+           size = 0;
+        }else fld->field_fixed = 1;
+      }else if(likely(fld->field_fixed == 0)){
+        offset1 = offsetRoot;
+        offset2 = 0;
+        for(i=0;unlikely(i<element_number);i++){
+          size=getFieldtypeSize(tf, evT, offset1, offset2,
+                                fld->child[i], evD+offset2);
+          offset1 += size;
+          offset2 += size;
+        }      
+        size = offset2;
+      }else size = fld->field_size;
+      fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+      fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      break;
+
+    default:
+      if(unlikely(fld->field_fixed == -1)){
+        size = (int) ltt_type_size(LTT_GET_BO(tf), type);
+        fld->field_fixed = 1;
+      }else size = fld->field_size;
+      if(unlikely(!evD)){
+        fld->fixed_root    = (offsetRoot==-1)   ? 0 : 1;
+        fld->fixed_parent  = (offsetParent==-1) ? 0 : 1;
+      }
+      break;
+  }
+
+  fld->offset_root     = offsetRoot;
+  fld->offset_parent   = offsetParent;
+  fld->field_size      = size;
+
+end_getFieldtypeSize:
+
+  return size;
+}
+#endif //0
+
+/*****************************************************************************
+ *Function name
+ *    ltt_get_int    : get an integer number
+ *Input params 
+ *    reverse_byte_order: must we reverse the byte order ?
+ *    size            : the size of the integer
+ *    ptr             : the data pointer
+ *Return value
+ *    gint64          : a 64 bits integer
+ ****************************************************************************/
+
+gint64 ltt_get_int(gboolean reverse_byte_order, gint size, void *data)
+{
+  gint64 val;
+
+  switch(size) {
+    case 1: val = *((gint8*)data); break;
+    case 2: val = ltt_get_int16(reverse_byte_order, data); break;
+    case 4: val = ltt_get_int32(reverse_byte_order, data); break;
+    case 8: val = ltt_get_int64(reverse_byte_order, data); break;
+    default: val = ltt_get_int64(reverse_byte_order, data);
+             g_critical("get_int : integer size %d unknown", size);
+             break;
+  }
+
+  return val;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_get_uint    : get an unsigned integer number
+ *Input params 
+ *    reverse_byte_order: must we reverse the byte order ?
+ *    size            : the size of the integer
+ *    ptr             : the data pointer
+ *Return value
+ *    guint64         : a 64 bits unsigned integer
+ ****************************************************************************/
+
+guint64 ltt_get_uint(gboolean reverse_byte_order, gint size, void *data)
+{
+  guint64 val;
+
+  switch(size) {
+    case 1: val = *((gint8*)data); break;
+    case 2: val = ltt_get_uint16(reverse_byte_order, data); break;
+    case 4: val = ltt_get_uint32(reverse_byte_order, data); break;
+    case 8: val = ltt_get_uint64(reverse_byte_order, data); break;
+    default: val = ltt_get_uint64(reverse_byte_order, data);
+             g_critical("get_uint : unsigned integer size %d unknown",
+                 size);
+             break;
+  }
+
+  return val;
+}
+
+
+/* get the node name of the system */
+
+char * ltt_trace_system_description_node_name (LttSystemDescription * s)
+{
+  return s->node_name;
+}
+
+
+/* get the domain name of the system */
+
+char * ltt_trace_system_description_domain_name (LttSystemDescription * s)
+{
+  return s->domain_name;
+}
+
+
+/* get the description of the system */
+
+char * ltt_trace_system_description_description (LttSystemDescription * s)
+{
+  return s->description;
+}
+
+
+/* get the NTP corrected start time of the trace */
+LttTime ltt_trace_start_time(LttTrace *t)
+{
+  return t->start_time;
+}
+
+/* get the monotonic start time of the trace */
+LttTime ltt_trace_start_time_monotonic(LttTrace *t)
+{
+  return t->start_time_from_tsc;
+}
+
+LttTracefile *ltt_tracefile_new()
+{
+  return g_new(LttTracefile, 1);
+}
+
+void ltt_tracefile_destroy(LttTracefile *tf)
+{
+  g_free(tf);
+}
+
+void ltt_tracefile_copy(LttTracefile *dest, const LttTracefile *src)
+{
+  *dest = *src;
+}
+
+/* Before library loading... */
+
+static void __attribute__((constructor)) init(void)
+{
+  LTT_FACILITY_NAME_HEARTBEAT = g_quark_from_string("heartbeat");
+  LTT_EVENT_NAME_HEARTBEAT = g_quark_from_string("heartbeat");
+  
+  LTT_TRACEFILE_NAME_FACILITIES = g_quark_from_string("/control/facilities");
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/type.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/type.c
new file mode 100644 (file)
index 0000000..4b09e3f
--- /dev/null
@@ -0,0 +1,394 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang, Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <glib.h>
+
+#include "parser.h"
+#include <ltt/ltt.h>
+#include "ltt-private.h"
+#include <ltt/type.h>
+
+static unsigned intSizes[] = {
+  sizeof(int8_t), sizeof(int16_t), sizeof(int32_t), sizeof(int64_t), 
+  sizeof(short) };
+
+typedef enum _intSizesNames { SIZE_INT8, SIZE_INT16, SIZE_INT32,
+                              SIZE_INT64, SIZE_SHORT, INT_SIZES_NUMBER }
+                   intSizesNames;
+
+
+static unsigned floatSizes[] = {
+  0, 0, sizeof(float), sizeof(double), 0, sizeof(float), sizeof(double) };
+
+#define FLOAT_SIZES_NUMBER 7
+
+
+/*****************************************************************************
+ *Function name
+ *    ltt_eventtype_name : get the name of the event type
+ *Input params
+ *    et                 : an  event type   
+ *Return value
+ *    GQuark             : the name of the event type
+ ****************************************************************************/
+
+GQuark ltt_eventtype_name(LttEventType *et)
+{
+  return et->name;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_eventtype_description : get the description of the event type
+ *Input params
+ *    et                 : an  event type   
+ *Return value
+ *    char *             : the description of the event type
+ ****************************************************************************/
+
+gchar *ltt_eventtype_description(LttEventType *et)
+{
+  return et->description;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_eventtype_facility : get the facility which contains the event type
+ *Input params
+ *    et                     : an  event type   
+ *Return value
+ *    LttFacility *          : the facility
+ ****************************************************************************/
+
+LttFacility *ltt_eventtype_facility(LttEventType *et)
+{
+  return et->facility;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_eventtype_id : get the id of the event type
+ *Input params
+ *    et               : an  event type   
+ *Return value
+ *    unsigned         : the id
+ ****************************************************************************/
+
+guint8 ltt_eventtype_id(LttEventType *et)
+{
+  return et->index;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_eventtype_type : get the type of the event type
+ *Input params
+ *    et                 : an  event type   
+ *Return value
+ *    LttType *         : the type of the event type
+ ****************************************************************************/
+
+LttType *ltt_eventtype_type(LttEventType *et)
+{
+  if(unlikely(!et->root_field)) return NULL;
+  else return et->root_field->field_type;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_eventtype_field : get the root filed of the event type
+ *Input params
+ *    et                  : an  event type   
+ *Return value
+ *    LttField *          : the root filed of the event type
+ ****************************************************************************/
+
+LttField *ltt_eventtype_field(LttEventType *et)
+{
+  return et->root_field;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_name  : get the name of the type
+ *Input params
+ *    t              : a type   
+ *Return value
+ *    char *         : the name of the type
+ ****************************************************************************/
+
+GQuark ltt_type_name(LttType *t)
+{
+  return t->element_name;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_class : get the type class of the type
+ *Input params
+ *    t              : a type   
+ *Return value
+ *    LttTypeEnum  : the type class of the type
+ ****************************************************************************/
+
+LttTypeEnum ltt_type_class(LttType *t)
+{
+  return t->type_class;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_size : obtain the type size. The size is the number of bytes 
+ *                    for primitive types (INT, UINT, FLOAT, ENUM)
+ *                    or the size for the unsigned integer length count for
+ *                    sequences
+ *Input params
+ *    tf            : trace file
+ *    t             : a type   
+ *Return value
+ *                  : the type size
+ *    returns 0 if erroneous, and show a critical warning message.
+ ****************************************************************************/
+
+size_t ltt_type_size(LttTrace * trace, LttType *t)
+{
+  size_t size;
+
+  switch(t->type_class) {
+
+    case LTT_INT:
+    case LTT_UINT:
+    case LTT_SEQUENCE:
+    case LTT_ENUM:
+      if(likely(t->size < INT_SIZES_NUMBER))
+        size = intSizes[t->size];
+      else
+        goto error;
+      break;
+    case LTT_FLOAT:
+      if(likely(t->size < FLOAT_SIZES_NUMBER))
+        size = floatSizes[t->size];
+      else
+        goto error;
+      break;
+    case LTT_POINTER:
+    case LTT_LONG:
+    case LTT_ULONG:
+    case LTT_SIZE_T:
+    case LTT_SSIZE_T:
+    case LTT_OFF_T:
+    case LTT_STRING:
+    case LTT_ARRAY:
+    case LTT_STRUCT:
+    case LTT_UNION:
+      goto error;
+      break;
+  }
+
+  return size;
+
+
+error:
+  g_warning("no size known for the type");
+  return 0;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_element_type : obtain the type of nested elements for arrays 
+ *                            and sequences 
+ *Input params
+ *    t                     : a type   
+ *Return value
+ *    LttType              : the type of nested element of array or sequence
+ ****************************************************************************/
+
+LttType *ltt_type_element_type(LttType *t)
+{
+  LttType *element_type;
+
+  if(unlikely(t->type_class != LTT_ARRAY && t->type_class != LTT_SEQUENCE))
+    element_type = NULL;
+  else
+    element_type = t->element_type[0];
+
+  return element_type;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_element_number : obtain the number of elements for arrays 
+ *Input params
+ *    t                       : a type   
+ *Return value
+ *    unsigned                : the number of elements for arrays
+ ****************************************************************************/
+
+unsigned ltt_type_element_number(LttType *t)
+{
+  unsigned ret = 0;
+
+  if(likely(t->type_class == LTT_ARRAY))
+    ret = t->element_number;
+
+  return ret;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_member_number : obtain the number of data members for structure 
+ *Input params
+ *    t                      : a type   
+ *Return value
+ *    unsigned               : the number of members for structure
+ ****************************************************************************/
+
+unsigned ltt_type_member_number(LttType *t)
+{
+  unsigned ret = 0;
+  
+  if(likely(t->type_class == LTT_STRUCT || t->type_class == LTT_UNION))
+    ret =t->element_number;
+
+  return ret;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_type_member_type : obtain the type of a data member in a structure 
+ *                           or union.
+ *Input params
+ *    t                    : a type   
+ *    i                    : index of the member
+ *Return value
+ *    LttType *           : the type of structure member
+ ****************************************************************************/
+
+LttType *ltt_type_member_type(LttType *t, unsigned i, GQuark *name)
+{
+  LttType *member_type = NULL;
+
+  if(unlikely(  (t->type_class != LTT_STRUCT
+                 && t->type_class != LTT_UNION)
+              ||
+                (i >= t->element_number)
+             )) {
+      *name = 0;
+  } else {
+    *name = t->element_type[i]->element_name;
+    member_type = t->element_type[i];
+  }
+
+  return member_type;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_enum_string_get : for enumerations, obtain the symbolic string 
+ *                          associated with a value (0 to n - 1 for an 
+ *                          enumeration of n elements) 
+ *Input params
+ *    t                   : a type   
+ *    i                   : index of the member
+ *Return value
+ *    char *              : symbolic string associated with a value
+ ****************************************************************************/
+
+GQuark ltt_enum_string_get(LttType *t, unsigned i)
+{ 
+  if(likely(t->type_class == LTT_ENUM && i < t->element_number))
+    return t->enum_strings[i];
+  else
+    return 0;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_field_element : obtain the field of nested elements for arrays and
+ *                        sequence 
+ *Input params
+ *    f                 : a field   
+ *Return value
+ *    LttField *       : the field of the nested element
+ ****************************************************************************/
+
+LttField *ltt_field_element(LttField *f)
+{
+  LttField *nest = NULL;
+  
+  if(likely(f->field_type->type_class == LTT_ARRAY ||
+              f->field_type->type_class == LTT_SEQUENCE))
+    nest = f->child[0];
+
+  return nest;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_field_member  : obtain the field of data members for structure
+ *Input params
+ *    f                 : a field   
+ *    i                 : index of member field
+ *Return value
+ *    LttField *       : the field of the nested element
+ ****************************************************************************/
+
+LttField *ltt_field_member(LttField *f, unsigned i)
+{
+  LttField *field_member;
+
+  g_assert(f->field_type->type_class == LTT_STRUCT ||
+              f->field_type->type_class == LTT_UNION);
+  g_assert(i < f->field_type->element_number);
+#if 0
+  if(unlikely(   f->field_type->type_class != LTT_STRUCT
+                 && f->field_type->type_class != LTT_UNION)
+              || i >= f->field_type->element_number )
+    field_member = NULL;
+  else
+#endif //0
+  field_member = f->child[i];
+
+  return field_member;
+}
+
+/*****************************************************************************
+ *Function name
+ *    ltt_field_type  : obtain the type of the field 
+ *Input params
+ *    f               : a field   
+ *Return value
+ *    ltt_tyoe *      : the type of field
+ ****************************************************************************/
+
+LttType *ltt_field_type(LttField *f)
+{
+  if(unlikely(!f))return NULL;
+  return f->field_type;
+}
+
+int ltt_field_size(LttField * f)
+{
+  if(unlikely(!f))return 0;
+  return f->field_size;
+}
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/type.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/ltt/type.h
new file mode 100644 (file)
index 0000000..98e7b8c
--- /dev/null
@@ -0,0 +1,102 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TYPE_H
+#define TYPE_H
+
+
+/* Different types allowed */
+
+#include <ltt/ltt.h>
+
+
+/* All event types, data types and fields belong to their trace and 
+   are released at the same time. */
+
+/* Obtain the name, description, facility, facility relative id, global id, 
+   type and root field for an eventtype */
+
+GQuark ltt_eventtype_name(LttEventType *et);
+
+gchar *ltt_eventtype_description(LttEventType *et);
+
+LttFacility *ltt_eventtype_facility(LttEventType *et);
+
+unsigned ltt_eventtype_relative_id(LttEventType *et);
+
+guint8 ltt_eventtype_id(LttEventType *et);
+
+LttType *ltt_eventtype_type(LttEventType *et);
+
+LttField *ltt_eventtype_field(LttEventType *et);
+
+
+/* obtain the type name and size. The size is the number of bytes for
+   primitive types (INT, UINT, FLOAT, ENUM), or the size for the unsigned
+   integer length count for sequences. */
+GQuark ltt_type_name(LttType *t);
+
+LttTypeEnum ltt_type_class(LttType *t);
+
+unsigned ltt_type_size(LttTrace *trace, LttType *t); 
+
+
+/* The type of nested elements for arrays and sequences. */
+
+LttType *ltt_type_element_type(LttType *t);
+
+
+/* The number of elements for arrays. */
+
+unsigned ltt_type_element_number(LttType *t);
+
+
+/* The number of data members for structures and unions. */
+
+unsigned ltt_type_member_number(LttType *t);
+
+
+/* The type of a data member in a structure. */
+
+LttType *ltt_type_member_type(LttType *t, unsigned i, GQuark *name);
+
+
+/* For enumerations, obtain the symbolic string associated with a value
+   (0 to n - 1 for an enumeration of n elements). */
+
+GQuark ltt_enum_string_get(LttType *t, unsigned i);
+
+
+/* The fields form a tree representing a depth first search of the 
+   corresponding event type directed acyclic graph. Fields for arrays and
+   sequences simply point to one nested field representing the currently
+   selected element among all the (identically typed) elements. For structures,
+   a nested field exists for each data member. Each field stores the
+   platform/trace specific offset values (for efficient access) and
+   points back to the corresponding LttType for the rest. */
+
+LttField *ltt_field_element(LttField *f);
+
+LttField *ltt_field_member(LttField *f, unsigned i);
+
+LttType *ltt_field_type(LttField *f);
+
+int ltt_field_size(LttField * f);
+
+#endif // TYPE_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttctl/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttctl/Makefile.am
new file mode 100644 (file)
index 0000000..6a5180d
--- /dev/null
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CFLAGS = -DPACKAGE_DATA_DIR=\""$(datadir)"\" -DPACKAGE_BIN_DIR=\""$(bindir)"\"
+
+bin_PROGRAMS = lttctl
+
+lttctl_SOURCES = \
+       lttctl.c
+lttctl_DEPENDENCIES = ../liblttctl/liblttctl.la
+lttctl_LDADD = $(lttctl_DEPENDENCIES)
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttctl/lttctl.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttctl/lttctl.c
new file mode 100644 (file)
index 0000000..5b8c262
--- /dev/null
@@ -0,0 +1,496 @@
+/* lttctl
+ *
+ * Linux Trace Toolkit Control
+ *
+ * Small program that controls LTT through libltt.
+ *
+ * Copyright 2005 -
+ *     Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <liblttctl/lttctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/stat.h>
+
+/* Buffer for file copy : 4k seems optimal. */
+#define BUF_SIZE 4194304
+
+enum trace_ctl_op {
+  CTL_OP_CREATE_START,
+       CTL_OP_CREATE,
+       CTL_OP_DESTROY,
+  CTL_OP_STOP_DESTROY,
+       CTL_OP_START,
+       CTL_OP_STOP,
+       CTL_OP_DAEMON,
+       CTL_OP_DESCRIPTION,
+       CTL_OP_NONE
+};
+
+static char *trace_name = NULL;
+static char *mode_name = NULL;
+static unsigned subbuf_size = 0;
+static unsigned n_subbufs = 0;
+static unsigned append_trace = 0;
+static enum trace_mode mode = LTT_TRACE_NORMAL;
+static enum trace_ctl_op op = CTL_OP_NONE;
+static char *channel_root = NULL;
+static char *trace_root = NULL;
+
+static int sigchld_received = 0;
+
+void sigchld_handler(int signo)
+{
+       printf("signal %d received\n", signo);
+       sigchld_received = 1;
+}
+
+
+/* Args :
+ *
+ */
+void show_arguments(void)
+{
+       printf("Please use the following arguments :\n");
+       printf("\n");
+       printf("-n name       Name of the trace.\n");
+       printf("-b            Create trace channels and start tracing (no daemon).\n");
+       printf("-c            Create trace channels.\n");
+       printf("-m mode       Normal or flight recorder mode.\n");
+       printf("              Mode values : normal (default) or flight.\n");
+       printf("-r            Destroy trace channels.\n");
+       printf("-R            Stop tracing and destroy trace channels.\n");
+       printf("-s            Start tracing.\n");
+       //printf("              Note : will automatically create a normal trace if "
+       //                                                                                      "none exists.\n");
+       printf("-q            Stop tracing.\n");
+       printf("-d            Create trace, spawn a lttd daemon, start tracing.\n");
+       printf("              (optionnaly, you can set LTT_DAEMON\n");
+       printf("              and the LTT_FACILITIES env. vars.)\n");
+       printf("-t            Trace root path. (ex. /root/traces/example_trace)\n");
+       printf("-l            LTT channels root path. (ex. /mnt/relayfs/ltt)\n");
+       printf("-z            Size of the subbuffers (will be rounded to next page size)\n");
+       printf("-x            Number of subbuffers\n");
+       printf("-e            Get XML facilities description\n");
+       printf("-a            Append to trace\n");
+       printf("\n");
+}
+
+
+/* parse_arguments
+ *
+ * Parses the command line arguments.
+ *
+ * Returns -1 if the arguments were correct, but doesn't ask for program
+ * continuation. Returns EINVAL if the arguments are incorrect, or 0 if OK.
+ */
+int parse_arguments(int argc, char **argv)
+{
+       int ret = 0;
+       int argn = 1;
+       
+       if(argc == 2) {
+               if(strcmp(argv[1], "-h") == 0) {
+                       return -1;
+               }
+       }
+
+       while(argn < argc) {
+
+               switch(argv[argn][0]) {
+                       case '-':
+                               switch(argv[argn][1]) {
+                                       case 'n':
+                                               if(argn+1 < argc) {
+                                                       trace_name = argv[argn+1];
+                                                       argn++;
+                                               } else {
+                                                       printf("Specify a trace name after -n.\n");
+                                                       printf("\n");
+                                                       ret = EINVAL;
+                                               }
+
+                                               break;
+          case 'b':
+            op = CTL_OP_CREATE_START;
+                                       case 'c':
+                                               op = CTL_OP_CREATE;
+            break;
+                                       case 'm':
+                                               if(argn+1 < argc) {
+                                                       mode_name = argv[argn+1];
+                                                       argn++;
+                                                       if(strcmp(mode_name, "normal") == 0)
+                                                               mode = LTT_TRACE_NORMAL;
+                                                       else if(strcmp(mode_name, "flight") == 0)
+                                                               mode = LTT_TRACE_FLIGHT;
+                                                       else {
+                                                               printf("Invalid mode '%s'.\n", argv[argn]);
+                                                               printf("\n");
+                                                               ret = EINVAL;
+                                                       }
+                                               } else {
+                                                               printf("Specify a mode after -m.\n");
+                                                               printf("\n");
+                                                               ret = EINVAL;
+                                               }
+                                               break;
+                                       case 'r':
+                                               op = CTL_OP_DESTROY;
+                                               break;
+                                       case 'R':
+                                               op = CTL_OP_STOP_DESTROY;
+                                               break;
+                                       case 's':
+                                               op = CTL_OP_START;
+                                               break;
+                                       case 'q':
+                                               op = CTL_OP_STOP;
+                                               break;
+                                       case 'z':
+                                               if(argn+1 < argc) {
+                                                       subbuf_size = (unsigned)atoi(argv[argn+1]);
+                                                       argn++;
+                                               } else {
+                                                       printf("Specify a number of subbuffers after -z.\n");
+                                                       printf("\n");
+                                                       ret = EINVAL;
+                                               }
+                                               break;
+                                       case 'x':
+                                               if(argn+1 < argc) {
+                                                       n_subbufs = (unsigned)atoi(argv[argn+1]);
+                                                       argn++;
+                                               } else {
+                                                       printf("Specify a subbuffer size after -x.\n");
+                                                       printf("\n");
+                                                       ret = EINVAL;
+                                               }
+                                               break;
+                                       case 'd':
+                                               op = CTL_OP_DAEMON;
+                                               break;
+          case 'e':
+            op = CTL_OP_DESCRIPTION;
+            break;
+                                       case 't':
+                                               if(argn+1 < argc) {
+                                                       trace_root = argv[argn+1];
+                                                       argn++;
+                                               } else {
+                                                       printf("Specify a trace root path after -t.\n");
+                                                       printf("\n");
+                                                       ret = EINVAL;
+                                               }
+                                               break;
+                                       case 'l':
+                                               if(argn+1 < argc) {
+                                                       channel_root = argv[argn+1];
+                                                       argn++;
+                                               } else {
+                                                       printf("Specify a channel root path after -l.\n");
+                                                       printf("\n");
+                                                       ret = EINVAL;
+                                               }
+                                               break;
+          case 'a':
+            append_trace = 1;
+            break;
+                                       default:
+                                               printf("Invalid argument '%s'.\n", argv[argn]);
+                                               printf("\n");
+                                               ret = EINVAL;
+                               }
+                               break;
+                       default:
+                               printf("Invalid argument '%s'.\n", argv[argn]);
+                               printf("\n");
+                               ret = EINVAL;
+               }
+               argn++;
+       }
+       
+       if(op != CTL_OP_DESCRIPTION && trace_name == NULL) {
+               printf("Please specify a trace name.\n");
+               printf("\n");
+               ret = EINVAL;
+       }
+
+       if(op == CTL_OP_NONE) {
+               printf("Please specify an operation.\n");
+               printf("\n");
+               ret = EINVAL;
+       }
+
+       if(op == CTL_OP_DAEMON) {
+               if(trace_root == NULL) {
+                       printf("Please specify -t trace_root_path with the -d option.\n");
+                       printf("\n");
+                       ret = EINVAL;
+               }
+               if(channel_root == NULL) {
+                       printf("Please specify -l ltt_root_path with the -d option.\n");
+                       printf("\n");
+                       ret = EINVAL;
+               }
+       }
+
+  if(op == CTL_OP_DESCRIPTION) {
+    if(trace_root == NULL) {
+                       printf("Please specify -t trace_root_path with the -e option.\n");
+                       printf("\n");
+                       ret = EINVAL;
+    }
+  }
+
+       return ret;
+}
+
+void show_info(void)
+{
+       printf("Linux Trace Toolkit Trace Control\n");
+       printf("\n");
+  if(trace_name != NULL) {
+       printf("Controlling trace : %s\n", trace_name);
+       printf("\n");
+  }
+}
+
+int create_eventdefs(void)
+{
+  int ret = 0;
+  char eventdefs_path[PATH_MAX];
+  char eventdefs_file[PATH_MAX];
+  char facilities_file[PATH_MAX];
+  char read_buf[BUF_SIZE];
+  struct dirent *entry;
+       char *facilities_path = getenv("LTT_FACILITIES");
+       if(facilities_path == NULL) facilities_path =
+          PACKAGE_DATA_DIR "/" PACKAGE "/facilities";
+
+  ret = mkdir(trace_root, S_IRWXU|S_IRWXG|S_IRWXO);
+  if(ret == -1 && errno != EEXIST) {
+    ret = errno;
+    perror("Cannot create trace_root directory");
+    printf("trace_root is %s\n", trace_root);
+    goto error;
+  }
+  ret = 0;
+  
+  size_t trace_root_len = strlen(trace_root);
+  strncpy(eventdefs_path, trace_root, PATH_MAX);
+  strncat(eventdefs_path, "/eventdefs/", PATH_MAX - trace_root_len);
+  size_t eventdefs_path_len = strlen(eventdefs_path);
+  ret = mkdir(eventdefs_path, S_IRWXU|S_IRWXG|S_IRWXO);
+  if(ret == -1 && (!append_trace || errno != EEXIST)) {
+    ret = errno;
+    perror("Cannot create eventdefs directory");
+    goto error;
+  }
+  ret = 0;
+  
+  DIR *facilities_dir = opendir(facilities_path);
+  
+  if(facilities_dir == NULL) {
+    perror("Cannot open facilities directory");
+    ret = EEXIST;
+    goto error;
+  }
+
+  while((entry = readdir(facilities_dir)) != NULL) {
+    if(entry->d_name[0] == '.') continue;
+    
+    printf("Appending facility file %s\n", entry->d_name);
+    strncpy(eventdefs_file, eventdefs_path, PATH_MAX);
+    strncat(eventdefs_file, entry->d_name, PATH_MAX - eventdefs_path_len);
+    /* Append to the file */
+    FILE *dest = fopen(eventdefs_file, "a");
+    if(!dest) {
+      perror("Cannot create eventdefs file");
+      continue;
+    }
+    strncpy(facilities_file, facilities_path, PATH_MAX);
+    size_t facilities_dir_len = strlen(facilities_path);
+    strncat(facilities_file, "/", PATH_MAX - facilities_dir_len);
+    strncat(facilities_file, entry->d_name, PATH_MAX - facilities_dir_len-1);
+    FILE *src = fopen(facilities_file, "r");
+    if(!src) {
+      ret = errno;
+      perror("Cannot open eventdefs file for reading");
+      goto close_dest;
+    }
+
+    do {
+      size_t read_size, write_size;
+      read_size = fread(read_buf, sizeof(char), BUF_SIZE, src);
+      if(ferror(src)) {
+        ret = errno;
+        perror("Cannot read eventdefs file");
+        goto close_src;
+      }
+      write_size = fwrite(read_buf, sizeof(char), read_size, dest);
+      if(ferror(dest)) {
+        ret = errno;
+        perror("Cannot write eventdefs file");
+        goto close_src;
+      }
+    } while(!feof(src));
+
+    /* Add spacing between facilities */
+    fwrite("\n", 1, 1, dest);
+    
+close_src:
+    fclose(src);
+close_dest:
+    fclose(dest);
+  }
+
+  closedir(facilities_dir);
+
+error:
+  return ret;
+
+}
+
+
+int lttctl_daemon(struct lttctl_handle *handle, char *trace_name)
+{
+       char channel_path[PATH_MAX] = "";
+       pid_t pid;
+       int ret;
+       char *lttd_path = getenv("LTT_DAEMON");
+       struct sigaction act;
+
+       if(lttd_path == NULL) lttd_path = 
+    PACKAGE_BIN_DIR "/lttd";
+       
+       strcat(channel_path, channel_root);
+       strcat(channel_path, "/");
+       strcat(channel_path, trace_name);
+
+       
+       ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size, n_subbufs);
+       if(ret != 0) goto create_error;
+
+       act.sa_handler = sigchld_handler;
+       sigemptyset(&(act.sa_mask));
+       sigaddset(&(act.sa_mask), SIGCHLD);
+       sigaction(SIGCHLD, &act, NULL);
+       
+       pid = fork();
+
+       if(pid > 0) {
+    int status;
+               /* parent */
+               while(!(sigchld_received)) pause();
+
+    waitpid(pid, &status, 0);
+    ret = 0;
+    if(WIFEXITED(status))
+      ret = WEXITSTATUS(status);
+    if(ret) goto start_error;
+
+               printf("Creating supplementary trace files\n");
+    ret = create_eventdefs();
+    if(ret) goto start_error;
+
+       } else if(pid == 0) {
+               /* child */
+    int ret;
+    if(append_trace) 
+               ret =   execlp(lttd_path, lttd_path, "-t", trace_root, "-c",
+                       channel_path, "-d", "-a", NULL);
+    else
+               ret =   execlp(lttd_path, lttd_path, "-t", trace_root, "-c",
+                       channel_path, "-d", NULL);
+               if(ret) {
+      ret = errno;
+                       perror("Error in executing the lttd daemon");
+                       exit(ret);
+               }
+       } else {
+               /* error */
+               perror("Error in forking for lttd daemon");
+       }
+
+       ret = lttctl_start(handle, trace_name);
+       if(ret != 0) goto start_error;
+
+       return 0;
+
+       /* error handling */
+start_error:
+  printf("Trace start error\n");
+       ret |= lttctl_destroy_trace(handle, trace_name);
+create_error:
+       return ret;
+}
+
+int main(int argc, char ** argv)
+{
+       int ret;
+       struct lttctl_handle *handle;
+       
+       ret = parse_arguments(argc, argv);
+
+       if(ret != 0) show_arguments();
+       if(ret == EINVAL) return EINVAL;
+       if(ret == -1) return 0;
+
+       show_info();
+       
+       handle = lttctl_create_handle();
+       
+       if(handle == NULL) return -1;
+       
+       switch(op) {
+    case CTL_OP_CREATE_START:
+                       ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size,
+                                                                                                                               n_subbufs);
+      if(!ret)
+        ret = lttctl_start(handle, trace_name);
+      break;
+       case CTL_OP_CREATE:
+                       ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size,
+                                                                                                                               n_subbufs);
+      break;
+               case CTL_OP_DESTROY:
+                       ret = lttctl_destroy_trace(handle, trace_name);
+                       break;
+               case CTL_OP_STOP_DESTROY:
+                       ret = lttctl_stop(handle, trace_name);
+      if(!ret)
+                       ret = lttctl_destroy_trace(handle, trace_name);
+                       break;
+               case CTL_OP_START:
+                       ret = lttctl_start(handle, trace_name);
+                       break;
+               case CTL_OP_STOP:
+                       ret = lttctl_stop(handle, trace_name);
+                       break;
+               case CTL_OP_DAEMON:
+                       ret = lttctl_daemon(handle, trace_name);
+                       break;
+    case CTL_OP_DESCRIPTION:
+      ret = create_eventdefs();
+      break;
+               case CTL_OP_NONE:
+                       break;
+       }
+
+       ret |= lttctl_destroy_handle(handle);
+       
+       return ret;
+}
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttd/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttd/Makefile.am
new file mode 100644 (file)
index 0000000..ed620e7
--- /dev/null
@@ -0,0 +1,7 @@
+# Empty TraceDaemon Makefile.am. Insert a real one here.
+
+
+bin_PROGRAMS = lttd
+
+lttd_SOURCES = lttd.c
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttd/lttd.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttd/lttd.c
new file mode 100644 (file)
index 0000000..02724ce
--- /dev/null
@@ -0,0 +1,549 @@
+/* lttd
+ *
+ * Linux Trace Toolkit Daemon
+ *
+ * This is a simple daemon that reads a few relayfs channels and save them in a
+ * trace.
+ *
+ *
+ * Copyright 2005 -
+ *     Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+/* Relayfs IOCTL */
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+/* Get the next sub buffer that can be read. */
+#define RELAYFS_GET_SUBBUF        _IOR(0xF4, 0x00,__u32)
+/* Release the oldest reserved (by "get") sub buffer. */
+#define RELAYFS_PUT_SUBBUF        _IO(0xF4, 0x01)
+/* returns the number of sub buffers in the per cpu channel. */
+#define RELAYFS_GET_N_SUBBUFS     _IOR(0xF4, 0x02,__u32)
+/* returns the size of the sub buffers. */
+#define RELAYFS_GET_SUBBUF_SIZE   _IOR(0xF4, 0x03,__u32)
+
+
+
+enum {
+       GET_SUBBUF,
+       PUT_SUBBUF,
+       GET_N_BUBBUFS,
+       GET_SUBBUF_SIZE
+};
+
+struct fd_pair {
+       int channel;
+       int trace;
+       unsigned int n_subbufs;
+       unsigned int subbuf_size;
+       void *mmap;
+};
+
+struct channel_trace_fd {
+       struct fd_pair *pair;
+       int num_pairs;
+};
+
+static char *trace_name = NULL;
+static char *channel_name = NULL;
+static int     daemon_mode = 0;
+static int     append_mode = 0;
+volatile static int    quit_program = 0;       /* For signal handler */
+
+/* Args :
+ *
+ * -t directory                Directory name of the trace to write to. Will be created.
+ * -c directory                Root directory of the relayfs trace channels.
+ * -d                          Run in background (daemon).
+ * -a                                                  Trace append mode.
+ * -s                                                  Send SIGUSR1 to parent when ready for IO.
+ */
+void show_arguments(void)
+{
+       printf("Please use the following arguments :\n");
+       printf("\n");
+       printf("-t directory  Directory name of the trace to write to.\n"
+                                "              It will be created.\n");
+       printf("-c directory  Root directory of the relayfs trace channels.\n");
+       printf("-d            Run in background (daemon).\n");
+       printf("-a            Append to an possibly existing trace.\n");
+       printf("\n");
+}
+
+
+/* parse_arguments
+ *
+ * Parses the command line arguments.
+ *
+ * Returns 1 if the arguments were correct, but doesn't ask for program
+ * continuation. Returns -1 if the arguments are incorrect, or 0 if OK.
+ */
+int parse_arguments(int argc, char **argv)
+{
+       int ret = 0;
+       int argn = 1;
+       
+       if(argc == 2) {
+               if(strcmp(argv[1], "-h") == 0) {
+                       return 1;
+               }
+       }
+
+       while(argn < argc) {
+
+               switch(argv[argn][0]) {
+                       case '-':
+                               switch(argv[argn][1]) {
+                                       case 't':
+                                               if(argn+1 < argc) {
+                                                       trace_name = argv[argn+1];
+                                                       argn++;
+                                               }
+                                               break;
+                                       case 'c':
+                                               if(argn+1 < argc) {
+                                                       channel_name = argv[argn+1];
+                                                       argn++;
+                                               }
+                                               break;
+                                       case 'd':
+                                               daemon_mode = 1;
+                                               break;
+                                       case 'a':
+                                               append_mode = 1;
+                                               break;
+                                       default:
+                                               printf("Invalid argument '%s'.\n", argv[argn]);
+                                               printf("\n");
+                                               ret = -1;
+                               }
+                               break;
+                       default:
+                               printf("Invalid argument '%s'.\n", argv[argn]);
+                               printf("\n");
+                               ret = -1;
+               }
+               argn++;
+       }
+       
+       if(trace_name == NULL) {
+               printf("Please specify a trace name.\n");
+               printf("\n");
+               ret = -1;
+       }
+       
+       if(channel_name == NULL) {
+               printf("Please specify a channel name.\n");
+               printf("\n");
+               ret = -1;
+       }
+       
+       return ret;
+}
+
+void show_info(void)
+{
+       printf("Linux Trace Toolkit Trace Daemon\n");
+       printf("\n");
+       printf("Reading from relayfs directory : %s\n", channel_name);
+       printf("Writing to trace directory : %s\n", trace_name);
+       printf("\n");
+}
+
+
+/* signal handling */
+
+static void handler(int signo)
+{
+       printf("Signal %d received : exiting cleanly\n", signo);
+       quit_program = 1;
+}
+
+
+
+int open_channel_trace_pairs(char *subchannel_name, char *subtrace_name,
+               struct channel_trace_fd *fd_pairs)
+{
+       DIR *channel_dir = opendir(subchannel_name);
+       struct dirent *entry;
+       struct stat stat_buf;
+       int ret;
+       char path_channel[PATH_MAX];
+       int path_channel_len;
+       char *path_channel_ptr;
+       char path_trace[PATH_MAX];
+       int path_trace_len;
+       char *path_trace_ptr;
+  int open_ret = 0;
+
+       if(channel_dir == NULL) {
+               perror(subchannel_name);
+               open_ret = ENOENT;
+    goto end;
+       }
+
+       printf("Creating trace subdirectory %s\n", subtrace_name);
+       ret = mkdir(subtrace_name, S_IRWXU|S_IRWXG|S_IRWXO);
+       if(ret == -1) {
+               if(errno != EEXIST) {
+                       perror(subtrace_name);
+      open_ret = -1;
+                       goto end;
+               }
+       }
+
+       strncpy(path_channel, subchannel_name, PATH_MAX-1);
+       path_channel_len = strlen(path_channel);
+       path_channel[path_channel_len] = '/';
+       path_channel_len++;
+       path_channel_ptr = path_channel + path_channel_len;
+
+       strncpy(path_trace, subtrace_name, PATH_MAX-1);
+       path_trace_len = strlen(path_trace);
+       path_trace[path_trace_len] = '/';
+       path_trace_len++;
+       path_trace_ptr = path_trace + path_trace_len;
+       
+       while((entry = readdir(channel_dir)) != NULL) {
+
+               if(entry->d_name[0] == '.') continue;
+               
+               strncpy(path_channel_ptr, entry->d_name, PATH_MAX - path_channel_len);
+               strncpy(path_trace_ptr, entry->d_name, PATH_MAX - path_trace_len);
+               
+               ret = stat(path_channel, &stat_buf);
+               if(ret == -1) {
+                       perror(path_channel);
+                       continue;
+               }
+               
+               printf("Channel file : %s\n", path_channel);
+               
+               if(S_ISDIR(stat_buf.st_mode)) {
+
+                       printf("Entering channel subdirectory...\n");
+                       ret = open_channel_trace_pairs(path_channel, path_trace, fd_pairs);
+                       if(ret < 0) continue;
+               } else if(S_ISREG(stat_buf.st_mode)) {
+                       printf("Opening file.\n");
+                       
+                       fd_pairs->pair = realloc(fd_pairs->pair,
+                                       ++fd_pairs->num_pairs * sizeof(struct fd_pair));
+
+                       /* Open the channel in read mode */
+                       fd_pairs->pair[fd_pairs->num_pairs-1].channel = 
+                               open(path_channel, O_RDONLY | O_NONBLOCK);
+                       if(fd_pairs->pair[fd_pairs->num_pairs-1].channel == -1) {
+                               perror(path_channel);
+                               fd_pairs->num_pairs--;
+                               continue;
+                       }
+                       /* Open the trace in write mode, only append if append_mode */
+                       ret = stat(path_trace, &stat_buf);
+                       if(ret == 0) {
+                               if(append_mode) {
+                                       printf("Appending to file %s as requested\n", path_trace);
+
+                                       fd_pairs->pair[fd_pairs->num_pairs-1].trace = 
+                                               open(path_trace, O_WRONLY|O_APPEND,
+                                                               S_IRWXU|S_IRWXG|S_IRWXO);
+
+                                       if(fd_pairs->pair[fd_pairs->num_pairs-1].trace == -1) {
+                                               perror(path_trace);
+                                       }
+                               } else {
+                                       printf("File %s exists, cannot open. Try append mode.\n", path_trace);
+                                       open_ret = -1;
+          goto end;
+                               }
+                       } else {
+                               if(errno == ENOENT) {
+                                       fd_pairs->pair[fd_pairs->num_pairs-1].trace = 
+                                               open(path_trace, O_WRONLY|O_CREAT|O_EXCL,
+                                                               S_IRWXU|S_IRWXG|S_IRWXO);
+                                       if(fd_pairs->pair[fd_pairs->num_pairs-1].trace == -1) {
+                                               perror(path_trace);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+end:
+       closedir(channel_dir);
+
+       return open_ret;
+}
+
+
+int read_subbuffer(struct fd_pair *pair)
+{
+       unsigned int    subbuf_index;
+       int err, ret;
+
+
+       err = ioctl(pair->channel, RELAYFS_GET_SUBBUF, 
+                                                               &subbuf_index);
+       printf("index : %u\n", subbuf_index);
+       if(err != 0) {
+               perror("Error in reserving sub buffer");
+               ret = -EPERM;
+               goto get_error;
+       }
+       
+       err = TEMP_FAILURE_RETRY(write(pair->trace,
+                               pair->mmap + (subbuf_index * pair->subbuf_size),
+                               pair->subbuf_size));
+
+       if(err < 0) {
+               perror("Error in writing to file");
+               ret = err;
+               goto write_error;
+       }
+
+
+write_error:
+       err = ioctl(pair->channel, RELAYFS_PUT_SUBBUF);
+       if(err != 0) {
+               perror("Error in unreserving sub buffer");
+               ret = -EPERM;
+               goto get_error;
+       }
+
+get_error:
+       return ret;
+}
+
+
+/* read_channels
+ *
+ * Read the realyfs channels and write them in the paired tracefiles.
+ *
+ * @fd_pairs : paired channels and trace files.
+ *
+ * returns 0 on success, -1 on error.
+ *
+ * Note that the high priority polled channels are consumed first. We then poll
+ * again to see if these channels are still in priority. Only when no
+ * high priority channel is left, we start reading low priority channels.
+ *
+ * Note that a channel is considered high priority when the buffer is almost
+ * full.
+ */
+
+int read_channels(struct channel_trace_fd *fd_pairs)
+{
+       struct pollfd *pollfd;
+       int i,j;
+       int num_rdy, num_hup;
+       int high_prio;
+       int ret;
+
+       if(fd_pairs->num_pairs <= 0) {
+               printf("No channel to read\n");
+               goto end;
+       }
+       
+       /* Get the subbuf sizes and number */
+
+       for(i=0;i<fd_pairs->num_pairs;i++) {
+               struct fd_pair *pair = &fd_pairs->pair[i];
+
+               ret = ioctl(pair->channel, RELAYFS_GET_N_SUBBUFS, 
+                                                       &pair->n_subbufs);
+               if(ret != 0) {
+                       perror("Error in getting the number of subbuffers");
+                       goto end;
+               }
+               ret = ioctl(pair->channel, RELAYFS_GET_SUBBUF_SIZE, 
+                                                       &pair->subbuf_size);
+               if(ret != 0) {
+                       perror("Error in getting the size of the subbuffers");
+                       goto end;
+               }
+       }
+
+       /* Mmap each FD */
+       for(i=0;i<fd_pairs->num_pairs;i++) {
+               struct fd_pair *pair = &fd_pairs->pair[i];
+
+               pair->mmap = mmap(0, pair->subbuf_size * pair->n_subbufs, PROT_READ,
+                               MAP_SHARED, pair->channel, 0);
+               if(pair->mmap == MAP_FAILED) {
+                       perror("Mmap error");
+                       goto munmap;
+               }
+       }
+
+
+       /* Start polling the FD */
+       
+       pollfd = malloc(fd_pairs->num_pairs * sizeof(struct pollfd));
+
+       /* Note : index in pollfd is the same index as fd_pair->pair */
+       for(i=0;i<fd_pairs->num_pairs;i++) {
+               pollfd[i].fd = fd_pairs->pair[i].channel;
+               pollfd[i].events = POLLIN|POLLPRI;
+       }
+
+       while(1) {
+               high_prio = 0;
+               num_hup = 0; 
+#ifdef DEBUG
+               printf("Press a key for next poll...\n");
+               char buf[1];
+               read(STDIN_FILENO, &buf, 1);
+               printf("Next poll (polling %d fd) :\n", fd_pairs->num_pairs);
+#endif //DEBUG
+               
+               /* Have we received a signal ? */
+               if(quit_program) break;
+               
+               num_rdy = poll(pollfd, fd_pairs->num_pairs, -1);
+               if(num_rdy == -1) {
+                       perror("Poll error");
+                       goto free_fd;
+               }
+
+               printf("Data received\n");
+
+               for(i=0;i<fd_pairs->num_pairs;i++) {
+                       switch(pollfd[i].revents) {
+                               case POLLERR:
+                                       printf("Error returned in polling fd %d.\n", pollfd[i].fd);
+                                       num_hup++;
+                                       break;
+                               case POLLHUP:
+                                       printf("Polling fd %d tells it has hung up.\n", pollfd[i].fd);
+                                       num_hup++;
+                                       break;
+                               case POLLNVAL:
+                                       printf("Polling fd %d tells fd is not open.\n", pollfd[i].fd);
+                                       num_hup++;
+                                       break;
+                               case POLLPRI:
+                                       printf("Urgent read on fd %d\n", pollfd[i].fd);
+                                       /* Take care of high priority channels first. */
+                                       high_prio = 1;
+                                       ret |= read_subbuffer(&fd_pairs->pair[i]);
+                                       break;
+                       }
+               }
+               /* If every FD has hung up, we end the read loop here */
+               if(num_hup == fd_pairs->num_pairs) break;
+
+               if(!high_prio) {
+                       for(i=0;i<fd_pairs->num_pairs;i++) {
+                               switch(pollfd[i].revents) {
+                                       case POLLIN:
+                                               /* Take care of low priority channels. */
+                                               printf("Normal read on fd %d\n", pollfd[i].fd);
+                                               ret |= read_subbuffer(&fd_pairs->pair[i]);
+                                               break;
+                               }
+                       }
+               }
+
+       }
+
+free_fd:
+       free(pollfd);
+
+       /* munmap only the successfully mmapped indexes */
+       i = fd_pairs->num_pairs;
+munmap:
+               /* Munmap each FD */
+       for(j=0;j<i;j++) {
+               struct fd_pair *pair = &fd_pairs->pair[j];
+               int err_ret;
+
+               err_ret = munmap(pair->mmap, pair->subbuf_size * pair->n_subbufs);
+               if(err_ret != 0) {
+                       perror("Error in munmap");
+               }
+               ret |= err_ret;
+       }
+
+end:
+       return ret;
+}
+
+
+void close_channel_trace_pairs(struct channel_trace_fd *fd_pairs)
+{
+       int i;
+       int ret;
+
+       for(i=0;i<fd_pairs->num_pairs;i++) {
+               ret = close(fd_pairs->pair[i].channel);
+               if(ret == -1) perror("Close error on channel");
+               ret = close(fd_pairs->pair[i].trace);
+               if(ret == -1) perror("Close error on trace");
+       }
+       free(fd_pairs->pair);
+}
+
+int main(int argc, char ** argv)
+{
+       int ret;
+       struct channel_trace_fd fd_pairs = { NULL, 0 };
+       struct sigaction act;
+       
+       ret = parse_arguments(argc, argv);
+
+       if(ret != 0) show_arguments();
+       if(ret < 0) return EINVAL;
+       if(ret > 0) return 0;
+
+       show_info();
+
+       if(daemon_mode) {
+               ret = daemon(0, 0);
+    
+    if(ret == -1) {
+      perror("An error occured while daemonizing.");
+      exit(-1);
+    }
+  }
+
+       /* Connect the signal handlers */
+       act.sa_handler = handler;
+       act.sa_flags = 0;
+       sigemptyset(&(act.sa_mask));
+       sigaddset(&(act.sa_mask), SIGTERM);
+       sigaddset(&(act.sa_mask), SIGQUIT);
+       sigaddset(&(act.sa_mask), SIGINT);
+       sigaction(SIGTERM, &act, NULL);
+       sigaction(SIGQUIT, &act, NULL);
+       sigaction(SIGINT, &act, NULL);
+
+       //return 0;
+       if(ret = open_channel_trace_pairs(channel_name, trace_name, &fd_pairs))
+               goto close_channel;
+
+       ret = read_channels(&fd_pairs);
+
+close_channel:
+       close_channel_trace_pairs(&fd_pairs);
+
+       return ret;
+}
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/Makefile.am
new file mode 100644 (file)
index 0000000..8370b90
--- /dev/null
@@ -0,0 +1,4 @@
+# WARNING : modules must be done at the end, so modules can dynamically link
+# themselves to libraries compiled here but not installed in the system.
+SUBDIRS = lttv modules
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/README b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/README
new file mode 100644 (file)
index 0000000..e38ef07
--- /dev/null
@@ -0,0 +1,21 @@
+Linux Trace Toolkit Visualizer
+
+* Getting started
+
+Use ./autogen.sh in the top level directory. It will create the Makefile
+for you. Then, you can use make and make install to install this user
+tool.
+
+Loading it from the command line is then as simple as :
+
+lttv -L modules-path -m module1 -m module2 ...
+
+So, to load the graphical interface with a detailed events list, it
+would be (if the installation prefix is /usr, for instance)
+
+lttv -L /usr/lib/lttv/plugins -m lttvwindow -m guievents
+
+* Tree structure
+lttv:    main program composed of the program itself including helper modules.
+modules: text and graphical viewing and analysis tools.
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/Makefile.am
new file mode 100644 (file)
index 0000000..058e642
--- /dev/null
@@ -0,0 +1,63 @@
+AM_CFLAGS = $(GLIB_CFLAGS) 
+LIBS += $(POPT_LIBS) $(GLIB_LIBS) -lgobject-2.0 -L${top_srcdir}/ltt\
+          -llttvtraceread
+
+bin_PROGRAMS = lttv.real
+
+bin_SCRIPTS = lttv lttv-gui
+CLEANFILES = $(bin_SCRIPTS)
+EXTRA_DIST = lttv.sh lttv-gui.sh
+
+lttv: lttv.sh
+       rm -f lttv
+       echo "#!"$(BASH) > lttv
+       cat lttv.sh >> lttv
+       chmod ugo+x lttv
+
+lttv-gui: lttv-gui.sh
+       rm -f lttv-gui
+       echo "#!"$(BASH) > lttv-gui
+       cat lttv-gui.sh >> lttv-gui
+       chmod ugo+x lttv-gui
+
+
+INCLUDES = \
+       -DPACKAGE_PLUGIN_DIR=\""$(lttvplugindir)"\" \
+       @PACKAGE_CFLAGS@ \
+       $(DEFAULT_INCLUDES)
+
+libdir = ${lttvplugindir}
+
+lttvinclude_HEADERS = \
+       attribute.h\
+       hook.h\
+       iattribute.h\
+       lttv.h\
+       module.h\
+       option.h\
+       state.h\
+       stats.h\
+       tracecontext.h\
+       traceset.h\
+       filter.h\
+       print.h
+
+#noinst_HEADERS = \
+#      filter.h
+
+lttv_real_SOURCES = batchtest.c main.c module.c option.c \
+               hook.c attribute.c \
+               iattribute.c state.c stats.c \
+              tracecontext.c traceset.c filter.c print.c
+
+#man_MANS = lttv.1
+#EXTRA_DIST = lttv.1
+
+#install-data-hook:
+#      cd $(DESTDIR)$(mandir)/man1 && \
+#              $(LN_S) -f lttv.1 lttv-gui.1 \
+#              $(LN_S) -f lttv.1 lttv.real.1
+
+if LTTVSTATIC
+  lttv_real_LDFLAGS = -profile -static
+endif
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/attribute.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/attribute.c
new file mode 100644 (file)
index 0000000..b4402b2
--- /dev/null
@@ -0,0 +1,587 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <lttv/attribute.h>
+#include <ltt/ltt.h>
+#include <ltt/compiler.h>
+
+typedef union _AttributeValue {
+  int dv_int;
+  unsigned dv_uint;
+  long dv_long;
+  unsigned long dv_ulong;
+  float dv_float;
+  double dv_double;
+  LttTime dv_time;
+  gpointer dv_pointer;
+  char *dv_string;
+  GObject *dv_gobject;
+} AttributeValue;
+
+
+typedef struct _Attribute {
+  LttvAttributeName name;
+  LttvAttributeType type;
+  AttributeValue value;
+} Attribute;
+
+
+static __inline__ LttvAttributeValue address_of_value(LttvAttributeType t,
+                                                      AttributeValue *v)
+{
+  LttvAttributeValue va;
+
+  switch(t) {
+  case LTTV_INT: va.v_int = &v->dv_int; break;
+  case LTTV_UINT: va.v_uint = &v->dv_uint; break;
+  case LTTV_LONG: va.v_long = &v->dv_long; break;
+  case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break;
+  case LTTV_FLOAT: va.v_float = &v->dv_float; break;
+  case LTTV_DOUBLE: va.v_double = &v->dv_double; break;
+  case LTTV_TIME: va.v_time = &v->dv_time; break;
+  case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break;
+  case LTTV_STRING: va.v_string = &v->dv_string; break;
+  case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break;
+  case LTTV_NONE: break;
+  }
+  return va;
+}
+
+
+AttributeValue init_value(LttvAttributeType t)
+{
+  AttributeValue v;
+
+  switch(t) {
+  case LTTV_INT: v.dv_int = 0; break;
+  case LTTV_UINT: v.dv_uint = 0; break;
+  case LTTV_LONG: v.dv_long = 0; break;
+  case LTTV_ULONG: v.dv_ulong = 0; break;
+  case LTTV_FLOAT: v.dv_float = 0; break;
+  case LTTV_DOUBLE: v.dv_double = 0; break;
+  case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break;
+  case LTTV_POINTER: v.dv_pointer = NULL; break;
+  case LTTV_STRING: v.dv_string = NULL; break;
+  case LTTV_GOBJECT: v.dv_gobject = NULL; break;
+  case LTTV_NONE: break;
+  }
+  return v;
+}
+
+
+unsigned int 
+lttv_attribute_get_number(LttvAttribute *self)
+{
+  return self->attributes->len;
+}
+
+
+gboolean 
+lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
+{
+  *homogeneous = FALSE;
+  return TRUE;
+}
+
+
+LttvAttributeType 
+lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, 
+    LttvAttributeValue *v)
+{
+  Attribute *a;
+
+  a = &g_array_index(self->attributes, Attribute, i);
+  *name = a->name;
+  *v = address_of_value(a->type, &(a->value));
+  return a->type;
+}
+
+
+LttvAttributeType 
+lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeValue *v)
+{
+  Attribute *a;
+
+  unsigned i;
+
+  gpointer p;
+
+  p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(p == NULL) return LTTV_NONE;
+
+  i = GPOINTER_TO_UINT(p);
+  i--;
+  a = &g_array_index(self->attributes, Attribute, i);
+  *v = address_of_value(a->type, &(a->value));
+  return a->type;
+}
+
+
+LttvAttributeValue 
+lttv_attribute_add(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t)
+{
+  unsigned i;
+
+  Attribute a, *pa;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(i != 0) g_error("duplicate entry in attribute table");
+
+  a.name = name;
+  a.type = t;
+  a.value = init_value(t);
+  g_array_append_val(self->attributes, a);
+  i = self->attributes->len - 1;
+  pa = &g_array_index(self->attributes, Attribute, i);
+  g_hash_table_insert(self->names, GUINT_TO_POINTER(name), 
+      GUINT_TO_POINTER(i + 1));
+  return address_of_value(t, &(pa->value));
+}
+
+
+/* Remove an attribute */
+
+void 
+lttv_attribute_remove(LttvAttribute *self, unsigned i)
+{
+  Attribute *a;
+
+  a = &g_array_index(self->attributes, Attribute, i);
+
+  /* If the element is a gobject, unreference it. */
+  if(a->type == LTTV_GOBJECT && a->value.dv_gobject != NULL)
+    g_object_unref(a->value.dv_gobject);
+  
+  /* Remove the array element and its entry in the name index */
+
+  g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
+  g_array_remove_index_fast(self->attributes, i);
+
+  /* The element used to replace the removed element has its index entry
+     all wrong now. Reinsert it with its new position. */
+
+  if(likely(self->attributes->len != i)){
+    g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
+    g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1));
+  }
+}
+
+void 
+lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
+{
+  unsigned i;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(unlikely(i == 0)) g_error("remove by name non existent attribute");
+
+  lttv_attribute_remove(self, i - 1);
+}
+
+/* Create an empty iattribute object and add it as an attribute under the
+   specified name, or return an existing iattribute attribute. If an
+   attribute of that name already exists but is not a GObject supporting the
+   iattribute interface, return NULL. */
+
+/*CHECK*/LttvAttribute* 
+lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name)
+{
+  unsigned i;
+
+  Attribute a;
+
+  LttvAttribute *new;
+  
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(likely(i != 0)) {
+    a = g_array_index(self->attributes, Attribute, i - 1);
+    if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) {
+      return LTTV_ATTRIBUTE(a.value.dv_gobject);
+    }
+    else return NULL;    
+  }
+  new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new);
+  return (LttvAttribute *)new;
+}
+
+gboolean 
+lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  unsigned i;
+
+  Attribute *a;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(likely(i != 0)) {
+    a = &g_array_index(self->attributes, Attribute, i - 1);
+    if(unlikely(a->type != t)) return FALSE;
+    *v = address_of_value(t, &(a->value));
+    return TRUE;
+  }
+
+  *v = lttv_attribute_add(self, name, t);
+  return TRUE;
+}
+
+
+/*void lttv_attribute_recursive_free(LttvAttribute *self)
+{
+  int i, nb;
+
+  Attribute *a;
+
+  nb = self->attributes->len;
+
+  for(i = 0 ; i < nb ; i++) {
+    a = &g_array_index(self->attributes, Attribute, i);
+    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+      lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject));
+    }
+  }
+  g_object_unref(self);
+}*/
+
+
+void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
+{
+  int i, nb;
+
+  Attribute *a;
+
+  LttvAttributeValue value;
+
+  nb = src->attributes->len;
+
+  for(i = 0 ; i < nb ; i++) {
+    a = &g_array_index(src->attributes, Attribute, i);
+    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+      lttv_attribute_recursive_add(
+      /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
+          (LttvAttribute *)(a->value.dv_gobject));
+    }
+    else {
+      g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
+      switch(a->type) {
+             case LTTV_INT:
+          *value.v_int += a->value.dv_int;
+          break;
+        case LTTV_UINT:
+          *value.v_uint += a->value.dv_uint;
+          break;
+        case LTTV_LONG:
+          *value.v_long += a->value.dv_long;
+          break;
+        case LTTV_ULONG:
+          *value.v_ulong += a->value.dv_ulong;
+          break;
+        case LTTV_FLOAT:
+          *value.v_float += a->value.dv_float;
+          break;
+        case LTTV_DOUBLE:
+          *value.v_double += a->value.dv_double;
+          break;
+        case LTTV_TIME:
+          *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time);
+          break;
+        case LTTV_POINTER:
+          break;
+        case LTTV_STRING:
+          break;
+        case LTTV_GOBJECT:
+          break;
+        case LTTV_NONE:
+          break;
+      }    
+    }
+  }
+}
+
+
+static void
+print_indent(FILE *fp, int pos)
+{
+  int i;
+
+  for(i = 0 ; i < pos ; i++) putc(' ', fp);
+}
+
+
+void 
+lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent)
+{
+  int i, nb;
+
+  Attribute *a;
+
+  nb = self->attributes->len;
+
+  fprintf(fp,"<ATTRS>\n");
+  for(i = 0 ; i < nb ; i++) {
+    a = &g_array_index(self->attributes, Attribute, i);
+    print_indent(fp, pos);
+    fprintf(fp, "<ATTR NAME=\"%s\" ", g_quark_to_string(a->name));
+    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+      fprintf(fp, "TYPE=ATTRS>");
+      lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp,
+          pos + indent, indent);
+    }
+    else {
+      switch(a->type) {
+       case LTTV_INT:
+          fprintf(fp, "TYPE=INT VALUE=%d/>\n", a->value.dv_int);
+          break;
+        case LTTV_UINT:
+          fprintf(fp, "TYPE=UINT VALUE=%u/>\n", a->value.dv_uint);
+          break;
+        case LTTV_LONG:
+          fprintf(fp, "TYPE=LONG VALUE=%ld/>\n", a->value.dv_long);
+          break;
+        case LTTV_ULONG:
+          fprintf(fp, "TYPE=ULONG VALUE=%lu/>\n", a->value.dv_ulong);
+          break;
+        case LTTV_FLOAT:
+          fprintf(fp, "TYPE=FLOAT VALUE=%f/>\n", a->value.dv_float);
+          break;
+        case LTTV_DOUBLE:
+          fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double);
+          break;
+        case LTTV_TIME:
+          fprintf(fp, "TYPE=TIME SEC=%lu NSEC=%lu/>\n", a->value.dv_time.tv_sec,
+              a->value.dv_time.tv_nsec);
+          break;
+        case LTTV_POINTER:
+          fprintf(fp, "TYPE=POINTER VALUE=%p/>\n", a->value.dv_pointer);
+          break;
+        case LTTV_STRING:
+          fprintf(fp, "TYPE=STRING VALUE=\"%s\"/>\n", a->value.dv_string);
+          break;
+        case LTTV_GOBJECT:
+          fprintf(fp, "TYPE=GOBJECT VALUE=%p/>\n", a->value.dv_gobject);
+          break;
+        case LTTV_NONE:
+          fprintf(fp, "TYPE=NONE/>\n");
+          break;
+      }    
+    }
+  }
+  print_indent(fp, pos);
+  fprintf(fp,"</ATTRS>\n");
+}
+
+
+void 
+lttv_attribute_read_xml(LttvAttribute *self, FILE *fp)
+{
+  int res;
+
+  char buffer[256], type[10];
+
+  LttvAttributeName name;
+
+  LttvAttributeValue value;
+
+  LttvAttribute *subtree;
+
+  fscanf(fp,"<ATTRS>");
+  while(1) {
+    res = fscanf(fp, "<ATTR NAME=\"%256[^\"]\" TYPE=%10[^ >]", buffer, type);
+    g_assert(res == 2);
+    name = g_quark_from_string(buffer);
+    if(strcmp(type, "ATTRS") == 0) {
+      fscanf(fp, ">");
+      subtree = lttv_attribute_find_subdir(self, name);
+      lttv_attribute_read_xml(subtree, fp);
+    }
+    else if(strcmp(type, "INT") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_INT);
+      res = fscanf(fp, " VALUE=%d/>", value.v_int);
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "UINT") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_UINT);
+      res = fscanf(fp, " VALUE=%u/>", value.v_uint);
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "LONG") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_LONG);
+      res = fscanf(fp, " VALUE=%ld/>", value.v_long);
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "ULONG") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_ULONG);
+      res = fscanf(fp, " VALUE=%lu/>", value.v_ulong);
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "FLOAT") == 0) {
+      float d;
+      value = lttv_attribute_add(self, name, LTTV_FLOAT);
+      res = fscanf(fp, " VALUE=%f/>", &d);
+      *(value.v_float) = d;
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "DOUBLE") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_DOUBLE);
+      res = fscanf(fp, " VALUE=%lf/>", value.v_double);
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "TIME") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_TIME);
+      res = fscanf(fp, " SEC=%lu NSEC=%lu/>", &(value.v_time->tv_sec), 
+          &(value.v_time->tv_nsec));
+      g_assert(res == 2);
+    }
+    else if(strcmp(type, "POINTER") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_POINTER);
+      res = fscanf(fp, " VALUE=%p/>", value.v_pointer);
+      g_error("Cannot read a pointer");
+    }
+    else if(strcmp(type, "STRING") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_STRING);
+      res = fscanf(fp, " VALUE=\"%256[^\"]\"/>", buffer);
+      *(value.v_string) = g_strdup(buffer);
+      g_assert(res == 1);
+    }
+    else if(strcmp(type, "GOBJECT") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_GOBJECT);
+      res = fscanf(fp, " VALUE=%p/>", value.v_gobject);
+      g_error("Cannot read a pointer");
+    }
+    else if(strcmp(type, "NONE") == 0) {
+      value = lttv_attribute_add(self, name, LTTV_NONE);
+      fscanf(fp, "/>");
+    }
+    else g_error("Unknown type to read");
+  }
+  fscanf(fp,"</ATTRS>");
+}
+
+static LttvAttribute *
+new_attribute (LttvAttribute *self)
+{
+  return g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+}
+
+
+static void
+attribute_interface_init (gpointer g_iface, gpointer iface_data)
+{
+  LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
+
+  klass->new_attribute = (LttvIAttribute* (*) (LttvIAttribute *self))
+      new_attribute;
+
+  klass->get_number = (unsigned int (*) (LttvIAttribute *self)) 
+      lttv_attribute_get_number;
+
+  klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
+      lttv_attribute_named;
+
+  klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, 
+      LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get;
+
+  klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
+      LttvAttributeName name, LttvAttributeValue *v)) 
+      lttv_attribute_get_by_name;
+
+  klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, 
+      LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
+
+  klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) 
+      lttv_attribute_remove;
+
+  klass->remove_by_name = (void (*) (LttvIAttribute *self,
+      LttvAttributeName name)) lttv_attribute_remove_by_name;
+
+  klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, 
+      LttvAttributeName name)) lttv_attribute_find_subdir;
+
+}
+
+static void
+attribute_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  LttvAttribute *self = (LttvAttribute *)instance;
+  self->names = g_hash_table_new(g_direct_hash,
+                                 g_direct_equal);
+  self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
+}
+
+
+static void
+attribute_finalize (LttvAttribute *self)
+{
+  guint i;
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()");
+
+  for(i=0;i<self->attributes->len;i++) {
+    lttv_attribute_remove(self, i);
+  }
+  
+  g_hash_table_destroy(self->names);
+  g_array_free(self->attributes, TRUE);
+}
+
+
+static void
+attribute_class_init (LttvAttributeClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+  
+  gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
+}
+
+GType 
+lttv_attribute_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvAttributeClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) attribute_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvAttribute),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) attribute_instance_init,    /* instance_init */
+      NULL    /* value handling */
+    };
+
+    static const GInterfaceInfo iattribute_info = {
+      (GInterfaceInitFunc) attribute_interface_init,    /* interface_init */
+      NULL,                                       /* interface_finalize */
+      NULL                                        /* interface_data */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info, 
+        0);
+    g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
+  }
+  return type;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/attribute.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/attribute.h
new file mode 100644 (file)
index 0000000..517b478
--- /dev/null
@@ -0,0 +1,125 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+
+/* FIXME : unnamed attributes not implemented */
+
+#include <glib-object.h>
+#include <lttv/iattribute.h>
+#include <stdio.h>
+
+#define LTTV_ATTRIBUTE_TYPE        (lttv_attribute_get_type ())
+#define LTTV_ATTRIBUTE(obj)        (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_ATTRIBUTE_TYPE, LttvAttribute))
+#define LTTV_ATTRIBUTE_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_ATTRIBUTE_TYPE, LttvAttributeClass))
+#define LTTV_IS_ATTRIBUTE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_ATTRIBUTE_TYPE))
+#define LTTV_IS_ATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_ATTRIBUTE_TYPE))
+#define LTTV_ATTRIBUTE_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_ATTRIBUTE_TYPE, LttvAttributeClass))
+
+
+typedef struct _LttvAttribute LttvAttribute;
+typedef struct _LttvAttributeClass LttvAttributeClass;
+
+struct _LttvAttribute {
+  GObject parent;
+
+  /* private members */
+  GHashTable *names;
+  GArray *attributes;
+};
+
+struct _LttvAttributeClass {
+  GObjectClass parent;
+
+};
+
+GType lttv_attribute_get_type (void);
+
+
+/* The functions exported in the IAttribute interface are also available
+   directly. */
+
+
+/* Total number of attributes */
+
+unsigned int lttv_attribute_get_number(LttvAttribute *self);
+
+
+/* Container type. Named (fields in struct or elements in a hash table)
+   or unnamed (elements in an array) attributes, homogeneous type or not. */
+
+gboolean lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous);
+
+
+/* Get the i th attribute along with its type and a pointer to its value. */
+
+LttvAttributeType lttv_attribute_get(LttvAttribute *self, unsigned i, 
+    LttvAttributeName *name, LttvAttributeValue *v);
+
+/* Get the named attribute in the table along with its type and a pointer to
+   its value. If the named attribute does not exist, the type is LTTV_NONE. */
+
+LttvAttributeType lttv_attribute_get_by_name(LttvAttribute *self,
+    LttvAttributeName name, LttvAttributeValue *v);
+
+
+/* Add an attribute, which must not exist. The name is an empty string for
+   containers with unnamed attributes. */
+
+LttvAttributeValue lttv_attribute_add(LttvAttribute *self, 
+    LttvAttributeName name, LttvAttributeType t);
+
+
+/* Remove an attribute */
+
+void lttv_attribute_remove(LttvAttribute *self, unsigned i);
+
+void lttv_attribute_remove_by_name(LttvAttribute *self,
+    LttvAttributeName name);
+
+
+/* Create an empty iattribute object and add it as an attribute under the
+   specified name, or return an existing iattribute attribute. If an
+   attribute of that name already exists but is not a GObject supporting the
+   iattribute interface, return NULL. */
+
+LttvAttribute* lttv_attribute_find_subdir(LttvAttribute *self, 
+      LttvAttributeName name);
+
+gboolean lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v);
+
+
+/* Free recursively a tree of attributes. All contained gobject of type
+   LttvAttribute are freed (unreferenced) recursively. */
+
+// Now done by default.
+// void lttv_attribute_recursive_free(LttvAttribute *self);
+
+/* Add items from a tree of attributes to another tree. */
+
+void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src);
+
+void
+lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent);
+
+void lttv_attribute_read_xml(LttvAttribute *self, FILE *fp);
+
+#endif // ATTRIBUTE_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/batchtest.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/batchtest.c
new file mode 100644 (file)
index 0000000..1a48d6a
--- /dev/null
@@ -0,0 +1,1005 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* This module inserts a hook in the program main loop. This hook processes 
+   all the events in the main tracefile while testing the speed and
+   functionality of the state and stats computations. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <lttv/lttv.h>
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+#include <lttv/option.h>
+#include <lttv/module.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/stats.h>
+#include <ltt/trace.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/facility.h>
+
+#define __UNUSED__ __attribute__((__unused__))
+
+static LttvTraceset *traceset;
+
+static LttvHooks
+  *before_traceset,
+  *after_traceset,
+  *before_trace,
+  *after_trace,
+  *before_tracefile,
+  *after_tracefile,
+  //*before_event,
+  //*after_event,
+  *event_hook,
+  *main_hooks;
+
+static char *a_trace;
+
+static char *a_dump_tracefiles;
+
+static char *a_save_sample;
+
+static int
+  a_sample_interval,
+  a_sample_number,
+  a_seek_number,
+  a_save_interval;
+
+static gboolean
+  a_trace_event,
+  a_save_state_copy,
+  a_test1,
+  a_test2,
+  a_test3,
+  a_test4,
+  a_test5,
+  a_test6,
+  a_test7,
+  a_test8,
+  a_test9,
+  a_test10,
+  a_test_all;
+
+static GQuark QUARK_BLOCK_START,
+              QUARK_BLOCK_END;
+
+LttEventPosition *a_event_position;
+
+typedef struct _save_state {
+  guint count;
+  FILE *fp;
+  guint interval;
+  guint position;
+  guint size;
+  LttTime *write_time;
+  guint version;
+} SaveState;
+
+
+static void lttv_trace_option(void __UNUSED__ *hook_data)
+{ 
+  LttTrace *trace;
+
+  trace = ltt_trace_open(a_trace);
+  if(trace == NULL) {
+    g_critical("cannot open trace %s", a_trace);
+  } else {
+    lttv_traceset_add(traceset, lttv_trace_new(trace));
+  }
+}
+
+static double get_time() 
+{
+  GTimeVal gt;
+
+  g_get_current_time(&gt);
+  return gt.tv_sec + (double)gt.tv_usec / (double)1000000.0;
+}
+
+static double run_one_test(LttvTracesetState *ts, LttTime start, LttTime end)
+{
+  double t0, t1;
+
+  unsigned int i;
+
+  //lttv_traceset_context_add_hooks(&ts->parent,
+  //before_traceset, after_traceset, NULL, before_trace, after_trace,
+  //NULL, before_tracefile, after_tracefile, NULL, before_event, after_event);
+  lttv_process_traceset_begin(&ts->parent,
+                              before_traceset,
+                              before_trace,
+                              before_tracefile,
+                              event_hook,
+                              NULL);
+
+  for(i = 0 ; i < lttv_traceset_number(traceset) ; i++) {
+    ((LttvTraceState *)(ts->parent.traces[i]))->save_interval =a_save_interval;
+  }
+
+  t0 = get_time();
+  lttv_state_traceset_seek_time_closest(ts, start);
+  //lttv_process_traceset(&ts->parent, end, G_MAXULONG);
+  lttv_process_traceset_middle(&ts->parent,
+                               end,
+                               G_MAXULONG,
+                               NULL);
+  t1 = get_time();
+
+  //lttv_traceset_context_remove_hooks(&ts->parent,
+  //before_traceset, after_traceset, NULL, before_trace, after_trace,
+  //NULL, before_tracefile, after_tracefile, NULL, before_event, after_event);
+  lttv_process_traceset_end(&ts->parent,
+                            after_traceset,
+                            after_trace,
+                            after_tracefile,
+                            event_hook,
+                            NULL);
+
+  return t1 - t0;
+}
+
+
+gboolean trace_event(void __UNUSED__ *hook_data, void *call_data)
+{
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  guint nb_block, offset;
+
+  guint64 tsc;
+
+  LttTracefile *tf;
+  LttEvent *e = ltt_tracefile_get_event(tfs->parent.tf);
+  ltt_event_position(e, a_event_position);
+  ltt_event_position_get(a_event_position, &tf, &nb_block, &offset, &tsc);
+  fprintf(stderr,"Event %s %lu.%09lu [%u 0x%x tsc %llu]\n",
+      g_quark_to_string(ltt_eventtype_name(ltt_event_eventtype(e))),
+      tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec,
+      nb_block, offset, tsc);
+  return FALSE;
+}
+
+static LttTime count_previous_time = { 0, 0 };
+
+gboolean count_event(void *hook_data, void __UNUSED__ *call_data)
+{
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+  LttTracefile *tracefile = tfs->parent.tf;
+  guint nb_block, offset;
+  LttTracefile *tf_pos;
+  guint64 tsc;
+  LttEvent * event = ltt_tracefile_get_event(tracefile);
+  LttTime time;
+  guint *pcount = (guint *)hook_data;
+
+  (*pcount)++;
+  
+  time = ltt_event_time(event);
+  ltt_event_position(event, a_event_position);
+  ltt_event_position_get(a_event_position, &tf_pos, &nb_block, &offset, &tsc);
+  
+  if(ltt_time_compare(time, count_previous_time) < 0) {
+    g_warning("Time decreasing trace %s tracefile %s cpu %u position %u/0x%x",
+  g_quark_to_string(ltt_trace_name(ltt_tracefile_get_trace(tracefile))),
+  g_quark_to_string(ltt_tracefile_name(tracefile)), 
+  ltt_tracefile_num(tracefile), nb_block, offset);
+    g_warning("last time %lu.%lu vs current %lu.%lu",
+  count_previous_time.tv_sec, count_previous_time.tv_nsec,
+  time.tv_sec, time.tv_nsec);
+  } 
+  count_previous_time = time;
+
+
+
+  return FALSE;
+}
+
+
+gboolean save_state_copy_event(void *hook_data, void *call_data)
+{
+  SaveState __UNUSED__ *save_state = (SaveState *)hook_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context;
+
+  LttEvent *e = ltt_tracefile_get_event(tfs->parent.tf);
+
+  GString *filename;
+
+  FILE *fp;
+
+  if(ts->nb_event == 0 && 
+      ltt_eventtype_name(ltt_event_eventtype(e)) 
+                            == QUARK_BLOCK_START) {
+    if(a_save_sample != NULL) {
+      filename = g_string_new("");
+      g_string_printf(filename, "%s.copy.%lu.%09lu.xml", a_save_sample, 
+          tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
+      fp = fopen(filename->str, "w");
+      if(fp == NULL) g_error("Cannot open %s", filename->str);
+      g_string_free(filename, TRUE);
+      lttv_state_write(ts, tfs->parent.timestamp, fp);
+      fclose(fp);
+    } //else lttv_state_write(ts, tfs->parent.timestamp, save_state->fp);
+  }
+  return FALSE;
+}
+
+
+gboolean save_state_event(void *hook_data, void *call_data)
+{
+  SaveState *save_state = (SaveState *)hook_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context;
+
+  GString *filename;
+
+  FILE *fp;
+
+  (save_state->count)++;
+  if(save_state->count % save_state->interval == 0 && 
+     save_state->position < save_state->size) {
+    if(a_save_sample != NULL) {
+      filename = g_string_new("");
+      g_string_printf(filename, "%s.%u.xml.%u", a_save_sample, 
+          save_state->position, save_state->version);
+      fp = fopen(filename->str, "w");
+      if(fp == NULL) g_error("Cannot open %s", filename->str);
+      g_string_free(filename, TRUE);
+      lttv_state_write(ts, tfs->parent.timestamp, fp);
+      fclose(fp);
+    } //else lttv_state_write(ts, tfs->parent.timestamp, save_state->fp);
+
+    save_state->write_time[save_state->position] = tfs->parent.timestamp;
+    save_state->position++;
+  }
+  return FALSE;
+}
+
+
+static void sanitize_name(gchar *name)
+{
+  while(*name != '\0') {
+    if(*name == '/') *name = '_';
+    name++;
+  }
+  
+}
+
+
+static void compute_tracefile(LttTracefile *tracefile, void *hook_data)
+{
+  GString *filename;
+  guint nb_equal, nb_block, offset;
+  guint64 tsc;
+  FILE *fp;
+  LttTime time, previous_time;
+  LttEvent *event = ltt_tracefile_get_event(tracefile);
+  LttFacility *facility;
+  LttEventType *event_type;
+  int err;
+  gchar mod_name[PATH_MAX];
+
+  /* start_count is always initialized in this function _if_ there is always
+   * a block_start before a block_end.
+   */
+  long long unsigned cycle_count, start_count=0, delta_cycle;
+
+
+  filename = g_string_new("");
+  strcpy(mod_name, g_quark_to_string(ltt_tracefile_name(tracefile)));
+  
+  sanitize_name(mod_name);
+  
+  g_warning("test %s test", g_quark_to_string(ltt_tracefile_name(tracefile)));
+  g_string_printf(filename, "%s.%s.%u.trace", a_dump_tracefiles,
+      mod_name, ltt_tracefile_num(tracefile));
+  fp = fopen(filename->str, "w");
+  if(fp == NULL) g_error("Cannot open %s", filename->str);
+  g_string_free(filename, TRUE);
+  err = ltt_tracefile_seek_time(tracefile, ltt_time_zero);
+  if(err) goto close;
+  
+  previous_time = ltt_time_zero;
+  nb_equal = 0;
+
+  do {
+    LttTracefile *tf_pos;
+    facility = ltt_event_facility(event);
+    event_type = ltt_event_eventtype(event);
+    time = ltt_event_time(event);
+    ltt_event_position(event, a_event_position);
+    ltt_event_position_get(a_event_position, &tf_pos, &nb_block, &offset, &tsc);
+    //fprintf(fp,"%s.%s: %llu %lu.%09lu position %u/%u\n", 
+    fprintf(fp, "%s.%s: %llu %lu.%09lu position %u/%u, tracefile %s\n", 
+        g_quark_to_string(ltt_facility_name(facility)),
+        g_quark_to_string(ltt_eventtype_name(event_type)),
+        tsc, (unsigned long)time.tv_sec, 
+        (unsigned long)time.tv_nsec, 
+        nb_block, offset,
+        g_quark_to_string(ltt_tracefile_name(tracefile)));
+
+    if(ltt_time_compare(time, previous_time) < 0) {
+      g_warning("Time decreasing trace %s tracefile %s cpu %u position %u/0x%x",
+    g_quark_to_string(ltt_trace_name(ltt_tracefile_get_trace(tracefile))),
+    g_quark_to_string(ltt_tracefile_name(tracefile)), 
+    ltt_tracefile_num(tracefile), nb_block, offset);
+      g_warning("last time %lu.%lu vs current %lu.%lu",
+    previous_time.tv_sec, previous_time.tv_nsec,
+    time.tv_sec, time.tv_nsec);
+    }
+
+#if 0 //FIXME
+    if(ltt_eventtype_name(event_type) == QUARK_BLOCK_START) {
+      start_count = cycle_count;
+      start_time = time;
+    }
+    else if(ltt_eventtype_name(event_type) == QUARK_BLOCK_END) {
+      delta_cycle = cycle_count - start_count;
+      end_nsec_sec = (long long unsigned)time.tv_sec * (long long unsigned)1000000000;
+      end_nsec_nsec = time.tv_nsec;
+      end_nsec = end_nsec_sec + end_nsec_nsec;
+      start_nsec = (long long unsigned)start_time.tv_sec * (long long unsigned)1000000000 + (long long unsigned)start_time.tv_nsec;
+      delta_nsec = end_nsec - start_nsec;
+      cycle_per_nsec = (double)delta_cycle / (double)delta_nsec;
+      nsec_per_cycle = (double)delta_nsec / (double)delta_cycle;
+      added_nsec = (double)delta_cycle * nsec_per_cycle;
+      interpolated_nsec = start_nsec + added_nsec;
+      added_nsec2 = (double)delta_cycle / cycle_per_nsec;
+      interpolated_nsec2 = start_nsec + added_nsec2;
+
+      fprintf(fp,"Time: start_count %llu, end_count %llu, delta_cycle %llu, start_nsec %llu, end_nsec_sec %llu, end_nsec_nsec %llu, end_nsec %llu, delta_nsec %llu, cycle_per_nsec %.25f, nsec_per_cycle %.25f, added_nsec %llu, added_nsec2 %llu, interpolated_nsec %llu, interpolated_nsec2 %llu\n", start_count, cycle_count, delta_cycle, start_nsec, end_nsec_sec, end_nsec_nsec, end_nsec, delta_nsec, cycle_per_nsec, nsec_per_cycle, added_nsec, added_nsec2, interpolated_nsec, interpolated_nsec2);
+    }
+    else {
+#endif //0
+      if(ltt_time_compare(time, previous_time) == 0) nb_equal++;
+      else if(nb_equal > 0) {
+        g_warning("Consecutive %d events with time %lu.%09lu",
+                   nb_equal + 1, previous_time.tv_sec, previous_time.tv_nsec);
+        nb_equal = 0;
+      }
+      previous_time = time;
+    //}
+  } while((!ltt_tracefile_read(tracefile)));
+
+close:
+  fclose(fp);
+}
+
+static gboolean process_traceset(void __UNUSED__ *hook_data, 
+                                 void __UNUSED__ *call_data)
+{
+  GString *filename;
+  LttvTracesetStats *tscs;
+
+  LttvTracesetState *ts;
+
+  LttvTracesetContext *tc;
+
+  FILE *fp;
+
+  double t;
+
+  //guint count, nb_control, nb_tracefile, nb_block, nb_event;
+  //guint i, j, count, nb_control, nb_tracefile, nb_block, nb_event, nb_equal;
+  guint i, j, count;
+
+  LttTrace *trace;
+
+  long long unsigned start_nsec, end_nsec, delta_nsec, added_nsec, added_nsec2;
+
+  double cycle_per_nsec, nsec_per_cycle;
+
+  long long interpolated_nsec, interpolated_nsec2, end_nsec_sec, end_nsec_nsec;
+
+  LttTime start_time;
+
+  LttTime max_time = { G_MAXULONG, G_MAXULONG };
+
+  a_event_position = ltt_event_position_new();
+
+  GData **tracefiles_groups;
+
+  struct compute_tracefile_group_args args;
+
+  args.func = compute_tracefile;
+  args.func_args = NULL;
+  
+  if(a_dump_tracefiles != NULL) {
+    for(i = 0 ; i < lttv_traceset_number(traceset) ; i++) {
+      trace = lttv_trace(lttv_traceset_get(traceset, i));
+      tracefiles_groups = ltt_trace_get_tracefiles_groups(trace);
+
+      g_datalist_foreach(tracefiles_groups, 
+                            (GDataForeachFunc)compute_tracefile_group,
+                            &args);
+      
+    }
+  }
+
+  tscs = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+  ts = &tscs->parent;
+  tc = &tscs->parent.parent;
+
+  lttv_context_init(tc, traceset);
+
+  /* For each case compute and print the elapsed time.
+     The first case is simply to run through all events with a
+     simple counter. */
+
+  if(a_test1 || a_test_all) {
+    count = 0;
+    lttv_hooks_add(event_hook, count_event, &count, LTTV_PRIO_DEFAULT);
+    t = run_one_test(ts, ltt_time_zero, max_time);
+    lttv_hooks_remove_data(event_hook, count_event, &count);
+    g_message(
+        "Processing trace while counting events (%u events in %g seconds)",
+       count, t);
+  }
+
+  /* Run through all events computing the state. */
+
+  if(a_test2 || a_test_all) {
+    lttv_state_add_event_hooks(ts);
+    t = run_one_test(ts, ltt_time_zero, max_time);
+    lttv_state_remove_event_hooks(ts);
+    g_message("Processing trace while updating state (%g seconds)", t);
+  }
+
+  /* Run through all events computing the state and writing it out 
+     periodically. */
+
+  SaveState save_state;
+
+  save_state.interval = a_sample_interval;
+  save_state.size = a_sample_number;
+  save_state.fp = stderr;
+  save_state.write_time = g_new(LttTime, a_sample_number);
+
+
+  if(a_test3 || a_test_all) {
+    for(i = 0 ; i < 2 ; i++) {
+      save_state.count = 0;
+      save_state.position = 0;
+      save_state.version = i;
+      lttv_state_add_event_hooks(ts);
+      lttv_hooks_add(event_hook, save_state_event, &save_state,
+                        LTTV_PRIO_DEFAULT);
+      t = run_one_test(ts, ltt_time_zero, max_time);
+      lttv_state_remove_event_hooks(ts);
+      lttv_hooks_remove_data(event_hook, save_state_event, &save_state);
+      g_warning("Processing while updating/writing state (%g seconds)", t);
+    }
+  }
+
+  /* Run through all events computing the stats. */
+
+  if(a_test4 || a_test_all) {
+    if(lttv_profile_memory) {
+      g_message("Memory summary before computing stats");
+      g_mem_profile();
+    }
+
+    lttv_stats_add_event_hooks(tscs);
+    t = run_one_test(ts, ltt_time_zero, max_time);
+    lttv_stats_remove_event_hooks(tscs);
+    g_message("Processing trace while counting stats (%g seconds)", t);
+
+    if(lttv_profile_memory) {
+      g_message("Memory summary after computing stats");
+      g_mem_profile();
+    }
+
+    lttv_stats_sum_traceset(tscs);
+
+    if(lttv_profile_memory) {
+      g_message("Memory summary after summing stats");
+      g_mem_profile();
+    }
+
+    lttv_context_fini(tc);
+    lttv_context_init(tc, traceset);
+
+    if(lttv_profile_memory) {
+      g_message("Memory summary after cleaning up the stats");
+      g_mem_profile();
+    }
+  }
+
+  /* Run through all events computing the state and stats. */
+
+  if(a_test5 || a_test_all) {
+    if(lttv_profile_memory) {
+      g_message("Memory summary before computing state and stats");
+      g_mem_profile();
+    }
+
+    lttv_state_add_event_hooks(ts);
+    lttv_stats_add_event_hooks(tscs);
+    t = run_one_test(ts, ltt_time_zero, max_time);
+    lttv_state_remove_event_hooks(ts);
+    lttv_stats_remove_event_hooks(tscs);
+    g_message(
+        "Processing trace while counting state and stats (%g seconds)", t);
+
+    if(lttv_profile_memory) {
+      g_message("Memory summary after computing and state and stats");
+      g_mem_profile();
+    }
+
+    lttv_context_fini(tc);
+    lttv_context_init(tc, traceset);
+
+    if(lttv_profile_memory) {
+      g_message("Memory summary after cleaning up the stats");
+      g_mem_profile();
+    }
+  }
+
+  /* Run through all events computing and saving the state. */
+
+  if(a_trace_event) lttv_hooks_add(event_hook, trace_event, NULL,
+                                      LTTV_PRIO_DEFAULT);
+
+  if(a_test6 || a_test_all) {
+    if(lttv_profile_memory) {
+      g_message("Memory summary before computing and saving state");
+      g_mem_profile();
+    }
+
+    lttv_state_add_event_hooks(ts);
+    lttv_state_save_add_event_hooks(ts);
+    if(a_save_state_copy)
+        lttv_hooks_add(event_hook, save_state_copy_event, &save_state,
+                          LTTV_PRIO_DEFAULT);
+    t = run_one_test(ts, ltt_time_zero, max_time);
+    lttv_state_remove_event_hooks(ts);
+    lttv_state_save_remove_event_hooks(ts);
+    if(a_save_state_copy)
+        lttv_hooks_remove_data(event_hook,save_state_copy_event, &save_state);
+
+    g_message("Processing trace while updating/saving state (%g seconds)", t);
+
+    if(lttv_profile_memory) {
+      g_message("Memory summary after computing/saving state");
+      g_mem_profile();
+    }
+  }
+
+  /* Seek a few times to each saved position */
+
+  if((a_test7 && a_test3) || a_test_all) {
+    g_assert(a_seek_number >= 0);
+    for(i = 0 ; i < (guint)a_seek_number ; i++) {
+      gint reverse_j; /* just to make sure j is unsigned */
+      for(reverse_j = save_state.position - 1 ; reverse_j >= 0 ; reverse_j--) {
+        j = (guint)reverse_j;
+        lttv_state_add_event_hooks(ts);
+        t = run_one_test(ts, save_state.write_time[j], 
+            save_state.write_time[j]);
+        lttv_state_remove_event_hooks(ts);
+        g_message("Seeking to %lu.%lu (%g seconds)", 
+            save_state.write_time[j].tv_sec, save_state.write_time[j].tv_nsec,
+            t);
+
+        if(a_save_sample != NULL) {
+          filename = g_string_new("");
+          g_string_printf(filename, "%s.%d.xml.bak%d", a_save_sample, j, i);
+          fp = fopen(filename->str, "w");
+          if(fp == NULL) g_error("Cannot open %s", filename->str);
+          g_string_free(filename, TRUE);
+          lttv_state_write((LttvTraceState *)tc->traces[0], 
+              save_state.write_time[j], fp);
+          fclose(fp);
+        }
+        //else lttv_state_write((LttvTraceState *)tc->traces[0], 
+        //    save_state.write_time[j], save_state.fp);
+      }
+    }
+  }
+
+  /* Seek at specified interval, using states computed in 6, making
+   * sure that there is no more than the number of events between
+   * state save interval to read before getting there.
+   */
+
+  if((a_test8 && a_test6) || a_test_all) {
+    g_message("Running test 8 : check save interval");
+    LttTime time = tc->time_span.start_time;
+    LttTime interval;
+    interval.tv_sec = 0;
+    interval.tv_nsec = 175674987;
+    guint count;
+
+    while(ltt_time_compare(time, tc->time_span.end_time) < 0) {
+      //g_message("Seeking at time %u.%u", time.tv_sec, time.tv_nsec);
+      lttv_process_traceset_seek_time(&ts->parent, ltt_time_zero);
+      lttv_state_traceset_seek_time_closest(ts, time);
+      /* We add no hook to the traceset, not necessary */
+      count = lttv_process_traceset_middle(&ts->parent,
+          time, G_MAXUINT, NULL);
+      g_info("Number of events to jump over : %u", count);
+      
+      if(count > LTTV_STATE_SAVE_INTERVAL)
+        g_warning("Oops! Save interval is %u and it took %u events to seek to a time %lu.%lu supposed to be closer from the last saved state.",
+            LTTV_STATE_SAVE_INTERVAL, count, time.tv_sec, time.tv_nsec);
+      time = ltt_time_add(time, interval);
+    }
+
+  }
+
+  if(a_test9 || a_test_all) {
+    double t0, t1;
+    /* Run seek_forward and seek_backward test */
+    guint count;
+    LttvTracesetContext *tsc = &ts->parent;
+    LttvTracesetContextPosition *saved_pos = 
+      lttv_traceset_context_position_new(tsc);
+    g_message("Running test 9 : seek_forward and seek_backward");
+    lttv_process_traceset_seek_time(tsc, ltt_time_zero);
+
+    count = lttv_process_traceset_seek_n_forward(tsc, 500, NULL);
+    g_assert(count == 500);
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    t0 = get_time();
+    count = lttv_process_traceset_seek_n_forward(tsc, 150000, NULL);
+    t1 = get_time();
+    g_message("Seek forward 150000 events in %g seconds", t1 - t0);
+    g_assert(count == 150000);
+    t0 = get_time();
+    count = lttv_process_traceset_seek_n_backward(tsc, 150000,
+        seek_back_default_offset, lttv_process_traceset_seek_time, NULL);
+    t1 = get_time();
+    g_message("Seek backward 150000 events in %g seconds", t1 - t0);
+    g_assert(count == 150000);
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) {
+      g_warning("Problem with seek_n ! Positions differ. (1)");
+    }
+    
+    lttv_process_traceset_seek_n_forward(tsc, 500, NULL);
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    lttv_process_traceset_seek_n_forward(tsc, 15000, NULL);
+    lttv_process_traceset_seek_n_backward(tsc, 15005,
+        seek_back_default_offset, lttv_process_traceset_seek_time, NULL);
+    lttv_process_traceset_seek_n_forward(tsc, 5, NULL);
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) {
+      g_warning("Problem with seek_n ! Positions differ. (2)");
+    }
+    
+    lttv_process_traceset_seek_time(tsc, ltt_time_infinite);
+    
+    count = lttv_process_traceset_seek_n_forward(tsc, 15000, NULL);
+    if(count > 0)
+      g_warning("Problem with seek_n ! Forward at end of traceset.");
+    
+    lttv_process_traceset_seek_time(tsc, ltt_time_infinite);
+
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    t0 = get_time();
+    lttv_process_traceset_seek_n_backward(tsc, 300,
+        seek_back_default_offset, lttv_process_traceset_seek_time, NULL);
+    t1 = get_time();
+    g_message("Seek backward 300 events in %g seconds", t1 - t0);
+    count = lttv_process_traceset_seek_n_forward(tsc, 299, NULL);
+    count = lttv_process_traceset_seek_n_forward(tsc, 1, NULL);
+
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) {
+      g_warning("Problem with seek_n ! Positions differ. (4)");
+    }
+    
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    t0 = get_time();
+    lttv_process_traceset_seek_n_backward(tsc, 10,
+        seek_back_default_offset, lttv_process_traceset_seek_time, NULL);
+    t1 = get_time();
+    g_message("Seek backward 10 events in %g seconds", t1 - t0);
+    t0 = get_time();
+    count = lttv_process_traceset_seek_n_forward(tsc, 10, NULL);
+    t1 = get_time();
+    g_message("Seek forward 10 events in %g seconds", t1 - t0);
+
+   
+    /* try a volountary error */
+    lttv_process_traceset_seek_time(tsc, ltt_time_infinite);
+
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    lttv_process_traceset_seek_n_backward(tsc, 301,
+        seek_back_default_offset, lttv_process_traceset_seek_time, NULL);
+    count = lttv_process_traceset_seek_n_forward(tsc, 299, NULL);
+    count = lttv_process_traceset_seek_n_forward(tsc, 1, NULL);
+
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos) == 0) {
+      g_warning("Problem with seek_n ! Positions _should_ differ. (5)");
+    }
+
+    /* Try a seek by closest time : Hint : try this one with and without states
+     * computed. */
+    lttv_process_traceset_seek_time(tsc, ltt_time_zero);
+    count = lttv_process_traceset_seek_n_forward(tsc, 200000, NULL);
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    t0 = get_time();
+    lttv_process_traceset_seek_n_backward(tsc, 100301,
+        seek_back_default_offset,
+        (seek_time_fct)lttv_state_traceset_seek_time_closest, NULL);
+    t1 = get_time();
+    g_message("Seek backward 100301 events (with seek closest) in %g seconds",
+                t1 - t0);
+    count = lttv_process_traceset_seek_n_forward(tsc, 100301, NULL);
+    
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) {
+      g_warning("Problem with seek_n with state seek time! Positions differ. (6)");
+    }
+
+    lttv_traceset_context_position_destroy(saved_pos);
+  }
+  
+  if(a_test10 || a_test_all) {
+    g_message("Running test 10 : check seek traceset context position");
+    LttvTracesetContext *tsc = &ts->parent;
+    LttvTracesetContextPosition *saved_pos = 
+      lttv_traceset_context_position_new(tsc);
+
+    lttv_process_traceset_seek_time(tsc, ltt_time_zero);
+    lttv_process_traceset_seek_n_forward(tsc, 200000, NULL);
+    lttv_traceset_context_position_save(tsc, saved_pos);
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos) != 0)
+      g_critical("Error in seek position. (1)");
+
+    lttv_process_traceset_seek_time(tsc, ltt_time_infinite);
+    lttv_process_traceset_seek_n_backward(tsc, 500,
+        seek_back_default_offset, lttv_process_traceset_seek_time, NULL);
+    lttv_traceset_context_position_save(tsc, saved_pos);
+
+    if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos) != 0)
+      g_critical("Error in seek position. (2)");
+    
+    lttv_traceset_context_position_destroy(saved_pos);
+  }
+
+  if(a_trace_event) lttv_hooks_remove_data(event_hook, trace_event, NULL);
+
+  g_free(save_state.write_time);
+  g_free(a_event_position);
+  lttv_context_fini(tc);
+  g_object_unref(tscs);
+
+  if(lttv_profile_memory) {
+    g_message("Memory summary at the end of batchtest");
+    g_mem_profile();
+  }
+
+  g_info("BatchTest end process traceset");
+  return 0;
+}
+
+
+static void init()
+{
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  g_info("Init batchtest.c");
+
+  /* Init GQuarks */
+  QUARK_BLOCK_START = g_quark_from_string("block_start");
+  QUARK_BLOCK_END = g_quark_from_string("block_end");
+
+  
+  lttv_option_add("trace", 't', 
+      "add a trace to the trace set to analyse", 
+      "pathname of the directory containing the trace", 
+      LTTV_OPT_STRING, &a_trace, lttv_trace_option, NULL);
+
+  a_trace_event = FALSE;
+
+  a_dump_tracefiles = NULL;
+  lttv_option_add("dump-tracefiles", 'D', 
+      "Write event by event the content of tracefiles", 
+      "basename for the files where to dump events", 
+      LTTV_OPT_STRING, &a_dump_tracefiles, NULL, NULL);
+
+  a_save_sample = NULL;
+  lttv_option_add("save-sample", 's', 
+      "Save state samples to multiple files", 
+      "basename for the files containing the state samples", 
+      LTTV_OPT_STRING, &a_save_sample, NULL, NULL);
+
+  a_save_state_copy = FALSE;
+  lttv_option_add("save-state-copy", 'S', "Write the state saved for seeking", 
+      "", LTTV_OPT_NONE, &a_save_state_copy, NULL, NULL);
+
+  a_save_interval = 100000;
+  lttv_option_add("save-interval", 'i', 
+      "Interval between saving state", 
+      "number of events before a block start triggers saving state", 
+      LTTV_OPT_INT, &a_save_interval, NULL, NULL);
+
+  a_sample_interval = 100000;
+  lttv_option_add("sample-interval", 'S', 
+      "Interval between sampling state", 
+      "number of events before sampling and writing state", 
+      LTTV_OPT_INT, &a_sample_interval, NULL, NULL);
+
+  a_sample_number = 20;
+  lttv_option_add("sample-number", 'N', 
+      "Number of state samples", 
+      "maximum number", 
+      LTTV_OPT_INT, &a_sample_number, NULL, NULL);
+
+  a_seek_number = 200;
+  lttv_option_add("seek-number", 'K', 
+      "Number of seek", 
+      "number", 
+      LTTV_OPT_INT, &a_seek_number, NULL, NULL);
+
+  a_test1 = FALSE;
+  lttv_option_add("test1", '1', "Test just counting events", "", 
+      LTTV_OPT_NONE, &a_test1, NULL, NULL);
+
+  a_test2 = FALSE;
+  lttv_option_add("test2", '2', "Test computing the state", "", 
+      LTTV_OPT_NONE, &a_test2, NULL, NULL);
+
+  a_test3 = FALSE;
+  lttv_option_add("test3", '3', "Test computing the state, writing out a few",
+      "", LTTV_OPT_NONE, &a_test3, NULL, NULL);
+
+  a_test4 = FALSE;
+  lttv_option_add("test4", '4', "Test computing the stats", "", 
+      LTTV_OPT_NONE, &a_test4, NULL, NULL);
+
+  a_test5 = FALSE;
+  lttv_option_add("test5", '5', "Test computing the state and stats", "", 
+      LTTV_OPT_NONE, &a_test5, NULL, NULL);
+
+  a_test6 = FALSE;
+  lttv_option_add("test6", '6', "Test computing and saving the state", "", 
+      LTTV_OPT_NONE, &a_test6, NULL, NULL);
+
+  a_test7 = FALSE;
+  lttv_option_add("test7", '7', "Test seeking to positions written out in 3", 
+      "", LTTV_OPT_NONE, &a_test7, NULL, NULL);
+
+  a_test8 = FALSE;
+  lttv_option_add("test8", '8', "Test seeking to positions using saved states computed at 6 : check if number of events fits", 
+      "", LTTV_OPT_NONE, &a_test8, NULL, NULL);
+  
+  a_test9 = FALSE;
+  lttv_option_add("test9", '9', "Test seeking backward/forward positions", 
+      "", LTTV_OPT_NONE, &a_test9, NULL, NULL);
+
+  a_test10 = FALSE;
+  lttv_option_add("test10", ' ', "Test seeking traceset by position", 
+      "", LTTV_OPT_NONE, &a_test10, NULL, NULL);
+
+
+
+  a_test_all = FALSE;
+  lttv_option_add("testall", 'a', "Run all tests ", "", 
+      LTTV_OPT_NONE, &a_test_all, NULL, NULL);
+
+  traceset = lttv_traceset_new();
+
+  before_traceset = lttv_hooks_new();
+  after_traceset = lttv_hooks_new();
+  before_trace = lttv_hooks_new();
+  after_trace = lttv_hooks_new();
+  before_tracefile = lttv_hooks_new();
+  after_tracefile = lttv_hooks_new();
+  //before_event = lttv_hooks_new();
+  //after_event = lttv_hooks_new();
+  event_hook = lttv_hooks_new();
+  
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_traceset;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_traceset;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_trace;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_trace;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_tracefile;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_tracefile;
+  //g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/before",
+  //    LTTV_POINTER, &value));
+  //*(value.v_pointer) = before_event;
+  //g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/after",
+  //    LTTV_POINTER, &value));
+  //*(value.v_pointer) = after_event;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = event_hook;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before",
+      LTTV_POINTER, &value));
+  g_assert((main_hooks = *(value.v_pointer)) != NULL);
+  lttv_hooks_add(main_hooks, process_traceset, NULL, LTTV_PRIO_DEFAULT);
+}
+
+
+static void destroy()
+{
+  guint i, nb;
+
+  LttvTrace *trace;
+
+  g_info("Destroy batchAnalysis.c");
+
+  lttv_option_remove("trace");
+  lttv_option_remove("dump-tracefiles");
+  lttv_option_remove("save-sample");
+  lttv_option_remove("save-state-copy");
+  lttv_option_remove("sample-interval");
+  lttv_option_remove("sample-number");
+  lttv_option_remove("seek-number");
+  lttv_option_remove("save-interval");
+  lttv_option_remove("test1");
+  lttv_option_remove("test2");
+  lttv_option_remove("test3");
+  lttv_option_remove("test4");
+  lttv_option_remove("test5");
+  lttv_option_remove("test6");
+  lttv_option_remove("test7");
+  lttv_option_remove("test8");
+  lttv_option_remove("test9");
+  lttv_option_remove("test10");
+  lttv_option_remove("testall");
+
+  lttv_hooks_destroy(before_traceset);
+  lttv_hooks_destroy(after_traceset);
+  lttv_hooks_destroy(before_trace);
+  lttv_hooks_destroy(after_trace);
+  lttv_hooks_destroy(before_tracefile);
+  lttv_hooks_destroy(after_tracefile);
+  //lttv_hooks_destroy(before_event);
+  //lttv_hooks_destroy(after_event);
+  lttv_hooks_destroy(event_hook);
+  lttv_hooks_remove_data(main_hooks, process_traceset, NULL);
+
+  nb = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb ; i++) {
+    trace = lttv_traceset_get(traceset, i);
+    lttv_traceset_remove(traceset,i);
+    ltt_trace_close(lttv_trace(trace));
+    lttv_trace_destroy(trace);
+  }
+
+  lttv_traceset_destroy(traceset); 
+}
+
+
+LTTV_MODULE("batchtest", "Batch processing of a trace for tests", \
+    "Run through a trace calling all the registered hooks for tests", \
+    init, destroy, "state", "stats", "option" )
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/contextmacros.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/contextmacros.h
new file mode 100644 (file)
index 0000000..b6276e9
--- /dev/null
@@ -0,0 +1,376 @@
+/* This file is part of the Linux Trace Toolkit trace reading library
+ * Copyright (C) 2004 Mathieu Desnoyers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License Version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* This is a header that contains macro helpers to give an object-oriented
+ * access to the Trace context, state and statistics.
+ */
+
+
+#include <ltt/trace.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/stats.h>
+
+/************ TracesetContext get methods ***************/
+
+/* LTTV_TRACESET_CONTEXT_GET_TRACE_CONTEXT
+ *
+ * Input : LttvTracesetContext *tsc
+ *         int                  trace number  (0 .. num_traces -1)
+ * returns : (LttvTraceContext *)
+ */
+#define LTTV_TRACESET_CONTEXT_GET_TRACE_CONTEXT(tsc, trace_num)\
+            (tsc->traces[trace_num])
+
+/* LTTV_TRACESET_CONTEXT_GET_NUM_TRACES
+ *
+ * Input : LttvTracesetContext *tsc
+ * returns : (guint)     the number of traces
+ */
+#define LTTV_TRACESET_CONTEXT_GET_NUM_TRACES(tsc)\
+            (lttv_traceset_number(tsc->ts))
+
+/* LTTV_TRACESET_CONTEXT_GET_TRACESET_STATS
+ *
+ * Input : LttvTracesetContext *tsc
+ * returns : (LttvTracesetStats*)
+ */
+#define LTTV_TRACESET_CONTEXT_GET_TRACESET_STATS(tsc)\
+            ((LttvTracesetStats*)tsc)
+
+
+/************ TraceContext get methods ***************/
+
+/* LTTV_TRACE_CONTEXT_GET_TRACESET_CONTEXT
+ *
+ * Input : LttvTraceContext *tc
+ * returns : (LttvTracesetContext *)
+ */
+#define LTTV_TRACE_CONTEXT_GET_TRACESET_CONTEXT(tc)\
+            (tc->ts_context)
+
+/* LTTV_TRACE_CONTEXT_GET_TRACE_INDEX
+ *
+ * Input : LttvTraceContext *tc
+ * returns : (guint)      trace context index in its traceset context.
+ */
+#define LTTV_TRACE_CONTEXT_GET_TRACE_INDEX(tc)\
+            (tc->index)
+
+
+
+/* LTTV_TRACE_CONTEXT_GET_TRACE_STATE
+ *
+ * Input : LttvTraceContext *tc
+ * returns : (LttvTraceState *)
+ */
+#define LTTV_TRACE_CONTEXT_GET_TRACE_STATE(tc)\
+            ((LttvTraceState*)tc)
+
+/* LTTV_TRACE_CONTEXT_GET_TRACE_STATS
+ *
+ * Input : LttvTraceContext *tc
+ * returns : (LttvTraceStats *)
+ */
+#define LTTV_TRACE_CONTEXT_GET_TRACE_STATS(tc)\
+            ((LttvTraceStats*)tc)
+
+/* LTTV_TRACE_CONTEXT_GET_CPU_TRACEFILE_CONTEXT
+ *
+ * Input : LttvTraceContext *tc
+ *         guint             cpu_index (0 .. number_cpu-1)
+ * returns : (LttvTracefileContext*)
+ */
+#define LTTV_TRACE_CONTEXT_GET_CPU_TRACEFILE_CONTEXT(tc, cpu_index)\
+        ( tc->tracefiles[cpu_index + ltt_trace_control_tracefile_number(tc->t)] )
+
+/* LTTV_TRACE_CONTEXT_GET_NUMBER_CPU
+ *
+ * input : LttvTraceContext *tc
+ * returns : (guint)    number_cpu
+ */
+#define LTTV_TRACE_CONTEXT_GET_NUMBER_CPU(tc)\
+        ( ltt_trace_per_cpu_tracefile_number(tc->t) )
+
+
+/* LTTV_TRACE_CONTEXT_GET_CONTROL_TRACEFILE_CONTEXT
+ *
+ * Input : LttvTraceContext *tc
+ *         guint             control_index (0 .. number_control-1)
+ * returns : (LttvTracefileContext*)
+ */
+#define LTTV_TRACE_CONTEXT_GET_CONTROL_TRACEFILE_CONTEXT(tc, control_index)\
+            (tc->tracefiles[control_index])
+
+/* LTTV_TRACE_CONTEXT_GET_NUMBER_CONTROL
+ *
+ * Input : LttvTraceContext *tc
+ * returns : (guint)    number_control
+ */
+#define LTTV_TRACE_CONTEXT_GET_NUMBER_CONTROL(tc)\
+        ( ltt_trace_control_tracefile_number(tc->t) )
+
+/* LTTV_TRACE_CONTEXT_GET_TRACE
+ *
+ * Input : LttvTraceContext *tc
+ * returns : (LttvTrace*)
+ *
+ * NOTE : see traceset.h for LttvTrace methods
+ */
+#define LTTV_TRACE_CONTEXT_GET_TRACE(tc)\
+            (tc->vt)
+
+
+
+
+
+/************ TracefileContext get methods ***************/
+
+/* LTTV_TRACEFILE_CONTEXT_GET_TRACE_CONTEXT
+ *
+ * Input : LttvTracefileContext *tfc
+ * returns : (LttvTraceContext*)
+ */
+#define LTTV_TRACEFILE_CONTEXT_GET_TRACE_CONTEXT(tfc)\
+            (tfc->t_context)
+
+/* LTTV_TRACEFILE_CONTEXT_GET_EVENT
+ *
+ * Input : LttvTracefileContext *tfc
+ * returns : (LttEvent *)
+ */
+#define LTTV_TRACEFILE_CONTEXT_GET_EVENT(tfc)\
+            (tfc->e)
+
+/* LTTV_TRACEFILE_CONTEXT_GET_TRACEFILE_STATE
+ *
+ * Input : LttvTracefileContext *tfc
+ * returns : (LttvTracefileState *)
+ */
+#define LTTV_TRACEFILE_CONTEXT_GET_TRACEFILE_STATE(tfc)\
+            ((LttvTracefileState*)tfc)
+
+/* LTTV_TRACEFILE_CONTEXT_GET_TRACEFILE_STATS
+ *
+ * Input : LttvTracefileContext *tfc
+ * returns : (LttvTracefileStats *)
+ */
+#define LTTV_TRACEFILE_CONTEXT_GET_TRACEFILE_STATS(tfc)\
+            ((LttvTracefileStats*)tfc)
+
+/* LTTV_TRACEFILE_CONTEXT_GET_TRACEFILE_INDEX
+ * 
+ * Returns the tracefile index.
+ *
+ * It checks if it's a control tracefile or a cpu tracefile and returns the
+ * cpu_index or control_index, depending of the case.
+ * 
+ * Input : LttvTracefileContext *tfc
+ * returns : (guint)     cpu_index or control_index.
+ */
+#define LTTV_TRACEFILE_CONTEXT_GET_TRACEFILE_INDEX(tfc)\
+            (tfc->control?\
+               tfc->index:\
+               tfc->index-ltt_trace_control_tracefile_number(tfc->t_context->t))
+
+
+
+/************ TraceState get methods ***************/
+
+/* LTTV_TRACE_STATE_GET_TRACE_CONTEXT
+ *
+ * Input : LttvTraceState *tse
+ * returns : (LttvTraceContext*)
+ *
+ */
+#define LTTV_TRACE_STATE_GET_TRACE_CONTEXT(tse)\
+            ((LttvTraceContext*)tse)
+
+/* LTTV_TRACE_STATE_GET_EVENTTYPE_NAME
+ *
+ * Input : LttvTraceState *tse
+ *         guint           eventtype_number
+ * returns : (GQuark)
+ *
+ * NOTE : use g_quark_to_string to convert a GQuark into a static char *
+ */
+#define LTTV_TRACE_STATE_GET_EVENTTYPE_NAME(tse, eventtype_number)\
+            (tse->eventtype_names[eventtype_number])
+
+/* LTTV_TRACE_STATE_GET_SYSCALL_NAME
+ *
+ * Input : LttvTraceState *tse
+ *         guint           syscall_number
+ * returns : (GQuark)
+ *
+ * NOTE : use g_quark_to_string to convert a GQuark into a static char *
+ */
+#define LTTV_TRACE_STATE_GET_SYSCALL_NAME(tse, syscall_number)\
+            (tse->syscall_names[syscall_number])
+
+/* LTTV_TRACE_STATE_GET_TRAP_NAME
+ *
+ * Input : LttvTraceState *tse
+ *         guint           trap_number
+ * returns : (GQuark)
+ *
+ * NOTE : use g_quark_to_string to convert a GQuark into a static char *
+ */
+#define LTTV_TRACE_STATE_GET_TRAP_NAME(tse, trap_number)\
+            (tse->trap_names[trap_number])
+
+/* LTTV_TRACE_STATE_GET_IRQ_NAME
+ *
+ * Input : LttvTraceState *tse
+ *         guint           irq_number
+ * returns : (GQuark)
+ *
+ * NOTE : use g_quark_to_string to convert a GQuark into a static char *
+ */
+#define LTTV_TRACE_STATE_GET_IRQ_NAME(tse, irq_number)\
+            (tse->irq_names[irq_number])
+
+
+/* LTTV_TRACE_STATE_GET_PROCESS_STATE
+ *
+ * Input : LttvTraceState *tse
+ *         guint           pid
+ *         guint           cpu_index  (0 .. number_cpu-1)
+ * returns : (LttvProcessState *)
+ *
+ * NOTE : if pid is 0, the special process corresponding to the CPU that
+ *                     corresponds to the tracefile will be returned.
+ *        if pid is different than 0, the process returned may be running
+ *                     on any cpu of the trace.
+ */
+#define LTTV_TRACE_STATE_GET_PROCESS_STATE(tse, pid, cpu_index)\
+          (lttv_state_find_process( \
+            (LttvTraceFileState*)tse->parent->tracefiles[\
+             cpu_index+\
+             ltt_trace_control_tracefile_number((LttvTraceContext*)tse->t)], pid))
+
+
+/* LTTV_TRACE_STATE_GET_NUMBER_CPU
+ *
+ * input : LttvTraceState *tse
+ * returns : (guint)    number_cpu
+ */
+#define LTTV_TRACE_STATE_GET_NUMBER_CPU(tse)\
+        ( ltt_trace_per_cpu_tracefile_number((LttvTraceState*)tse->t) )
+
+
+
+
+/************ TracefileState get methods ***************/
+
+/* LTTV_TRACEFILE_STATE_GET_TRACEFILE_CONTEXT
+ *
+ * Input : LttvTracefileState *tfse
+ * returns : (LttvTracefileContext*)
+ *
+ */
+#define LTTV_TRACEFILE_STATE_GET_TRACEFILE_CONTEXT(tfse)\
+            ((LttvTracefileContext*)tfse)
+
+
+/* LTTV_TRACEFILE_STATE_GET_CURRENT_PROCESS_STATE
+ *
+ * Returns the state of the current process.
+ *
+ * Input : LttvTracefileState *tfse
+ * returns : (LttvProcessState *)
+ */
+#define LTTV_TRACEFILE_STATE_GET_CURRENT_PROCESS_STATE(tfse)\
+            (tfse->process)
+
+/* LTTV_TRACEFILE_STATE_GET_CPU_NAME
+ *
+ * Input : LttvTracefileState *tfse
+ * returns : (GQuark)
+ *
+ * NOTE : use g_quark_to_string to convert a GQuark into a static char *
+ */
+#define LTTV_TRACEFILE_STATE_GET_CPU_NAME(tfse)\
+            (tfse->cpu_name)
+
+
+/* LTTV_TRACEFILE_STATE_GET_PROCESS_STATE
+ *
+ * Input : LttvTracefileState *tfse
+ *         guint           pid
+ * returns : (LttvProcessState *)
+ *
+ * NOTE : if pid is 0, the special process corresponding to the CPU that
+ *                     corresponds to the tracefile will be returned.
+ *        if pid is different than 0, the process returned may be running
+ *                     on any cpu of the trace.
+ */
+#define LTTV_TRACEFILE_STATE_GET_PROCESS_STATE(tfse, pid)\
+            (lttv_state_find_process(tfse, pid))
+
+
+
+
+
+/************ ProcessState get methods ***************/
+/* Use direct access to LttvProcessState members for other attributes */
+/* see struct _LttvProcessState definition in state.h */
+
+/* LTTV_PROCESS_STATE_GET_CURRENT_EXECUTION_STATE
+ *
+ * Input : LttvProcessState *pse
+ * returns : (LttvExecutionState*)
+ */
+#define LTTV_PROCESS_STATE_GET_EXECUTION_STATE(pse)\
+            (pse->state)
+
+/* LTTV_PROCESS_STATE_GET_NESTED_EXECUTION_STATE
+ *
+ * Input : LttvProcessState *pse
+ *         guint             nest_number (0 to num_nest-1)
+ * returns : (LttvExecutionState*)
+ */
+#define LTTV_PROCESS_STATE_GET_NESTED_EXECUTION_STATE(pse, num_nest)\
+       (&g_array_index(pse->execution_stack,LttvExecutionState,num_nest))
+
+
+/* LTTV_PROCESS_STATE_GET_NUM_NESTED_EXECUTION_STATES
+ *
+ * Returns the number of nested execution states currently on the stack.
+ * 
+ * Input : LttvProcessState *pse
+ * returns : (guint)
+ */
+#define LTTV_PROCESS_STATE_GET_NUM_NESTED_EXECUTION_STATES(pse)\
+            (pse->execution_stack->len)
+
+
+/************ ExecutionState get methods ***************/
+/* Use direct access to LttvExecutionState members to access attributes */
+/* see struct _LttvExecutionState definition in state.h */
+
+
+
+
+
+
+/* Statistics */
+
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/filter.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/filter.c
new file mode 100644 (file)
index 0000000..4d02187
--- /dev/null
@@ -0,0 +1,2041 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2005 Michel Dagenais and Simon Bouvier-Zappa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*! \file lttv/lttv/filter.c
+ *  \brief Defines the core filter of application
+ *
+ *  consist in AND, OR and NOT nested expressions, forming a tree with 
+ *  simple relations as leaves. The simple relations test if a field
+ *  in an event is equal, not equal, smaller, smaller or equal, larger, or
+ *  larger or equal to a specified value.
+ *
+ *  Fields specified in a simple expression can take following 
+ *  values
+ *
+ *  \verbatim
+ *  LttvTracefileContext{} 
+ *  |->event\ 
+ *  | |->name (String, converted to GQuark)
+ *  | |->facility (String, converted to GQuark)
+ *  | |->category (String, not yet implemented)
+ *  | |->time (LttTime)
+ *  | |->tsc (LttCycleCount --> uint64)
+ *  | |->fields
+ *  |   |->"event name"
+ *  |     |->"field name"
+ *  |       |->"sub-field name"
+ *  |         |->...
+ *  |           |->"leaf-field name" (field type)
+ *  |->tracefile
+ *  | |->name (String, converted to GQuark)
+ *  |->trace
+ *  | |->name (String, converted to GQuark)
+ *  |->state
+ *    |->pid (guint)
+ *    |->ppid (guint)
+ *    |->creation_time (LttTime)
+ *    |->insertion_time (LttTime)
+ *    |->process_name (String, converted to GQuark)
+ *    |->execution_mode (LttvExecutionMode)
+ *    |->execution_submode (LttvExecutionSubmode)
+ *    |->process_status (LttvProcessStatus)
+ *    |->cpu (guint)
+ *  \endverbatim
+ */
+
+/*
+ *  \todo 
+ *  - refine switch of expression in multiple uses functions
+ *  - remove the idle expressions in the tree 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//#define TEST
+#ifdef TEST
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttv/filter.h>
+#include <ltt/trace.h>
+#include <ltt/type.h>
+#include <ltt/facility.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * @fn LttvSimpleExpression* lttv_simple_expression_new()
+ * 
+ * Constructor for LttvSimpleExpression
+ * @return pointer to new LttvSimpleExpression
+ */
+LttvSimpleExpression* 
+lttv_simple_expression_new() {
+
+  LttvSimpleExpression* se = g_new(LttvSimpleExpression,1);
+
+  se->field = LTTV_FILTER_UNDEFINED;
+  se->op = NULL;
+  se->offset = 0;
+
+  return se;
+}
+
+/**
+ *  @fn gboolean lttv_simple_expression_assign_field(GPtrArray*,LttvSimpleExpression*)
+ * 
+ *  Parse through filtering field hierarchy as specified 
+ *  by user.  This function compares each value to 
+ *  predetermined quarks
+ *  @param fp The field path list
+ *  @param se current simple expression
+ *  @return success/failure of operation
+ */
+gboolean
+lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
+
+  GString* f = NULL;
+  
+  if(fp->len < 2) return FALSE;
+  g_assert((f=g_ptr_array_remove_index(fp,0))); 
+  
+  /*
+   * Parse through the specified 
+   * hardcoded fields.
+   *
+   * Take note however that the 
+   * 'event' subfields might change 
+   * depending on values specified 
+   * in core.xml file.  Hence, if 
+   * none of the subfields in the 
+   * array match the hardcoded 
+   * subfields, it will be considered 
+   * as a dynamic field
+   */
+  if(!g_strcasecmp(f->str,"trace") ) {
+    /*
+     * Possible values:
+     *  trace.name
+     */
+    g_string_free(f,TRUE);
+    f=g_ptr_array_remove_index(fp,0);
+    if(!g_strcasecmp(f->str,"name")) {
+      se->field = LTTV_FILTER_TRACE_NAME;    
+    }
+  } else if(!g_strcasecmp(f->str,"traceset") ) {
+    /* 
+     * FIXME: not yet implemented !
+     */
+  } else if(!g_strcasecmp(f->str,"tracefile") ) {
+    /*
+     * Possible values:
+     *  tracefile.name
+     */
+    g_string_free(f,TRUE);
+    f=g_ptr_array_remove_index(fp,0);
+    if(!g_strcasecmp(f->str,"name")) {
+      se->field = LTTV_FILTER_TRACEFILE_NAME;
+    }
+  } else if(!g_strcasecmp(f->str,"state") ) {
+    /*
+     * Possible values:
+     *  state.pid
+     *  state.ppid
+     *  state.creation_time
+     *  state.insertion_time
+     *  state.process_name
+     *  state.execution_mode
+     *  state.execution_submode
+     *  state.process_status
+     *  state.cpu
+     */
+    g_string_free(f,TRUE);
+    f=g_ptr_array_remove_index(fp,0);
+    if(!g_strcasecmp(f->str,"pid") ) { 
+      se->field = LTTV_FILTER_STATE_PID; 
+    }
+    else if(!g_strcasecmp(f->str,"ppid") ) { 
+      se->field = LTTV_FILTER_STATE_PPID; 
+    }
+    else if(!g_strcasecmp(f->str,"creation_time") ) {
+      se->field = LTTV_FILTER_STATE_CT;
+    }
+    else if(!g_strcasecmp(f->str,"insertion_time") ) {
+      se->field = LTTV_FILTER_STATE_IT;
+    }
+    else if(!g_strcasecmp(f->str,"process_name") ) {
+      se->field = LTTV_FILTER_STATE_P_NAME;
+    }
+    else if(!g_strcasecmp(f->str,"execution_mode") ) {
+      se->field = LTTV_FILTER_STATE_EX_MODE;
+    }
+    else if(!g_strcasecmp(f->str,"execution_submode") ) {
+      se->field = LTTV_FILTER_STATE_EX_SUBMODE;
+    }
+    else if(!g_strcasecmp(f->str,"process_status") ) {
+      se->field = LTTV_FILTER_STATE_P_STATUS;
+    }
+    else if(!g_strcasecmp(f->str,"cpu") ) {
+      se->field = LTTV_FILTER_STATE_CPU;
+    }
+  } else if(!g_strcasecmp(f->str,"event") ) {
+    /*
+     * Possible values:
+     *  event.name
+     *  event.category
+     *  event.time
+     *  event.tsc
+     */
+    g_string_free(f,TRUE);
+    f=g_ptr_array_remove_index(fp,0);
+    if(!g_strcasecmp(f->str,"name") ) {
+      se->field = LTTV_FILTER_EVENT_NAME;
+    }
+    else if(!g_strcasecmp(f->str,"facility") ) {
+      se->field = LTTV_FILTER_EVENT_FACILITY;
+    }
+    else if(!g_strcasecmp(f->str,"category") ) {
+      /*
+       * FIXME: Category not yet functional in lttv
+       */
+      se->field = LTTV_FILTER_EVENT_CATEGORY;
+    }
+    else if(!g_strcasecmp(f->str,"time") ) {
+      se->field = LTTV_FILTER_EVENT_TIME;
+    }
+    else if(!g_strcasecmp(f->str,"tsc") ) {
+      se->field = LTTV_FILTER_EVENT_TSC;
+    }
+    else {  /* core.xml specified options */
+      se->field = LTTV_FILTER_EVENT_FIELD;
+    }
+  } else {
+    g_warning("Unrecognized field in filter string");
+  }
+
+  /* free memory for last string */
+  g_string_free(f,TRUE);
+
+  /* array should be empty */
+  g_assert(fp->len == 0);
+  if(se->field == LTTV_FILTER_UNDEFINED) {
+    g_warning("The specified field was not recognized !");
+    return FALSE;
+  }  
+  return TRUE;  
+}
+
+/**
+ *  @fn gboolean lttv_simple_expression_assign_operator(LttvSimpleExpression*,LttvExpressionOp)
+ * 
+ *  Sets the function pointer for the current
+ *  Simple Expression
+ *  @param se current simple expression
+ *  @param op current operator
+ *  @return success/failure of operation
+ */
+gboolean 
+lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionOp op) {
+     
+  switch(se->field) {
+     /* 
+      * string
+      */
+     case LTTV_FILTER_TRACE_NAME:
+     case LTTV_FILTER_TRACEFILE_NAME:
+     case LTTV_FILTER_STATE_P_NAME:
+     case LTTV_FILTER_EVENT_NAME:
+     case LTTV_FILTER_EVENT_FACILITY:
+     case LTTV_FILTER_STATE_EX_MODE:
+     case LTTV_FILTER_STATE_EX_SUBMODE:
+     case LTTV_FILTER_STATE_P_STATUS:
+       switch(op) {
+         case LTTV_FIELD_EQ:
+           se->op = lttv_apply_op_eq_quark;
+           break;
+         case LTTV_FIELD_NE:
+           se->op = lttv_apply_op_ne_quark;
+           break;
+         default:
+           g_warning("Error encountered in operator assignment = or != expected");
+           return FALSE;
+       }
+       break;
+     /* 
+      * integer
+      */
+     case LTTV_FILTER_EVENT_TSC:
+       switch(op) {
+         case LTTV_FIELD_EQ:
+           se->op = lttv_apply_op_eq_uint64;
+           break;
+         case LTTV_FIELD_NE:
+           se->op = lttv_apply_op_ne_uint64;
+           break;
+         case LTTV_FIELD_LT:
+           se->op = lttv_apply_op_lt_uint64;
+           break;
+         case LTTV_FIELD_LE:
+           se->op = lttv_apply_op_le_uint64;
+           break;
+         case LTTV_FIELD_GT:
+           se->op = lttv_apply_op_gt_uint64;
+           break;
+         case LTTV_FIELD_GE:
+           se->op = lttv_apply_op_ge_uint64;
+           break;
+         default:
+           g_warning("Error encountered in operator assignment");
+           return FALSE;
+       }
+       break;
+     /* 
+      * unsigned integers
+      */
+     case LTTV_FILTER_STATE_CPU:
+     case LTTV_FILTER_STATE_PID:
+     case LTTV_FILTER_STATE_PPID:
+       switch(op) {
+         case LTTV_FIELD_EQ:
+           se->op = lttv_apply_op_eq_uint;
+           break;
+         case LTTV_FIELD_NE:
+           se->op = lttv_apply_op_ne_uint;
+           break;
+         case LTTV_FIELD_LT:
+           se->op = lttv_apply_op_lt_uint;
+           break;
+         case LTTV_FIELD_LE:
+           se->op = lttv_apply_op_le_uint;
+           break;
+         case LTTV_FIELD_GT:
+           se->op = lttv_apply_op_gt_uint;
+           break;
+         case LTTV_FIELD_GE:
+           se->op = lttv_apply_op_ge_uint;
+           break;
+         default:
+           g_warning("Error encountered in operator assignment");
+           return FALSE;
+       }
+       break;
+
+     /*
+      * Enums
+      * Entered as string, converted to enum
+      * 
+      * can only be compared with 'equal' or 'not equal' operators
+      *
+      * unsigned int of 16 bits are used here since enums 
+      * should not go over 2^16-1 values
+      */
+//      case /*NOTHING*/:
+//       switch(op) {
+//         case LTTV_FIELD_EQ:
+//           se->op = lttv_apply_op_eq_uint16;
+//           break;
+//         case LTTV_FIELD_NE:
+//           se->op = lttv_apply_op_ne_uint16;
+//           break;
+//         default:
+//           g_warning("Error encountered in operator assignment = or != expected");
+//           return FALSE;
+//       }
+//       break;
+     /*
+      * Ltttime
+      */
+     case LTTV_FILTER_STATE_CT:
+     case LTTV_FILTER_STATE_IT:
+     case LTTV_FILTER_EVENT_TIME:
+       switch(op) {
+         case LTTV_FIELD_EQ:
+           se->op = lttv_apply_op_eq_ltttime;
+           break;
+         case LTTV_FIELD_NE:
+           se->op = lttv_apply_op_ne_ltttime;
+           break;
+         case LTTV_FIELD_LT:
+           se->op = lttv_apply_op_lt_ltttime;
+           break;
+         case LTTV_FIELD_LE:
+           se->op = lttv_apply_op_le_ltttime;
+           break;
+         case LTTV_FIELD_GT:
+           se->op = lttv_apply_op_gt_ltttime;
+           break;
+         case LTTV_FIELD_GE:
+           se->op = lttv_apply_op_ge_ltttime;
+           break;
+         default:
+           g_warning("Error encountered in operator assignment");
+           return FALSE;
+       }
+       break;
+     default:
+       g_warning("Error encountered in operator assignation ! Field type:%i",se->field);
+       return FALSE;
+   }
+  
+  return TRUE;
+
+}
+
+/**
+ *  @fn gboolean lttv_simple_expression_assign_value(LttvSimpleExpression*,char*)
+ *
+ *  Assign the value field to the current LttvSimpleExpression
+ *  @param se pointer to the current LttvSimpleExpression
+ *  @param value string value for simple expression
+ */
+gboolean 
+lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value) {
+
+  unsigned i;
+  gboolean is_double = FALSE;
+  LttTime t = ltt_time_zero;
+  GString* v;
+  
+  switch(se->field) {
+     /* 
+      * Strings
+      * entered as strings, converted to Quarks
+      */
+     case LTTV_FILTER_TRACE_NAME:
+     case LTTV_FILTER_TRACEFILE_NAME:
+     case LTTV_FILTER_STATE_P_NAME:
+     case LTTV_FILTER_EVENT_NAME:
+     case LTTV_FILTER_EVENT_FACILITY:
+     case LTTV_FILTER_STATE_EX_MODE:
+     case LTTV_FILTER_STATE_EX_SUBMODE:
+     case LTTV_FILTER_STATE_P_STATUS:
+      // se->value.v_string = value;
+       se->value.v_uint32 = g_quark_from_string(value);
+       g_free(value);
+       break;
+     /* 
+      * integer -- supposed to be uint64
+      */
+     case LTTV_FILTER_EVENT_TSC:
+       se->value.v_uint64 = atoi(value);
+       g_free(value);
+       break;
+     /*
+      * unsigned integers
+      */
+     case LTTV_FILTER_STATE_PID:
+     case LTTV_FILTER_STATE_PPID:
+     case LTTV_FILTER_STATE_CPU:
+       se->value.v_uint = atoi(value);
+       g_free(value);
+       break;
+     /*
+      * LttTime
+      */
+     case LTTV_FILTER_STATE_CT:
+     case LTTV_FILTER_STATE_IT:
+     case LTTV_FILTER_EVENT_TIME:
+       //se->value.v_double = atof(value);
+       /*
+        * parsing logic could be optimised,
+        * but as for now, simpler this way
+        */
+       v = g_string_new("");
+       for(i=0;i<strlen(value);i++) {
+          if(value[i] == '.') { 
+              /* cannot specify number with more than one '.' */
+              if(is_double) return FALSE; 
+              else is_double = TRUE;
+              t.tv_sec = atoi(v->str);
+              g_string_free(v,TRUE);
+              v = g_string_new("");
+          } else g_string_append_c(v,value[i]);
+       }
+       /* number can be integer or double */
+       if(is_double) t.tv_nsec = atoi(v->str);
+       else t.tv_sec = atoi(v->str);
+       
+       g_string_free(v,TRUE);
+       
+       se->value.v_ltttime = t;
+       g_free(value);
+       break;
+     default:
+       g_warning("Error encountered in value assignation ! Field type = %i",se->field);
+       g_free(value);
+       return FALSE;
+   }
+  
+  return TRUE;
+  
+}
+
+/**
+ *  @fn void lttv_simple_expression_destroy(LttvSimpleExpression*)
+ *
+ *  Disallocate memory for the current 
+ *  simple expression
+ *  @param se pointer to the current LttvSimpleExpression
+ */
+void
+lttv_simple_expression_destroy(LttvSimpleExpression* se) {
+  
+ // g_free(se->value);
+//  switch(se->field) {
+//     case LTTV_FILTER_TRACE_NAME:
+//     case LTTV_FILTER_TRACEFILE_NAME:
+//     case LTTV_FILTER_STATE_P_NAME:
+//     case LTTV_FILTER_EVENT_NAME:
+//       g_free(se->value.v_string);
+//       break;
+//  }
+  g_free(se);
+
+}
+
+/**
+ *  @fn gint lttv_struct_type(gint)
+ * 
+ *  Finds the structure type depending 
+ *  on the fields in parameters
+ *  @params ft Field of the current structure
+ *  @return LttvStructType enum or -1 for error
+ */
+gint
+lttv_struct_type(gint ft) {
+  
+    switch(ft) {
+        case LTTV_FILTER_TRACE_NAME:
+            return LTTV_FILTER_TRACE;
+            break;
+        case LTTV_FILTER_TRACEFILE_NAME:
+            return LTTV_FILTER_TRACEFILE;
+            break;
+        case LTTV_FILTER_STATE_PID:
+        case LTTV_FILTER_STATE_PPID:
+        case LTTV_FILTER_STATE_CT:
+        case LTTV_FILTER_STATE_IT:
+        case LTTV_FILTER_STATE_P_NAME:
+        case LTTV_FILTER_STATE_EX_MODE:
+        case LTTV_FILTER_STATE_EX_SUBMODE:
+        case LTTV_FILTER_STATE_P_STATUS:
+        case LTTV_FILTER_STATE_CPU:
+            return LTTV_FILTER_STATE;
+            break;
+        case LTTV_FILTER_EVENT_NAME:
+        case LTTV_FILTER_EVENT_FACILITY:
+        case LTTV_FILTER_EVENT_CATEGORY:
+        case LTTV_FILTER_EVENT_TIME:
+        case LTTV_FILTER_EVENT_TSC:
+        case LTTV_FILTER_EVENT_FIELD:
+            return LTTV_FILTER_EVENT;
+            break;
+        default:
+            return -1;
+    }
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_uint(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_uint(const gpointer v1, LttvFieldValue v2) {
+
+  guint* r = (guint*) v1;
+  return (*r == v2.v_uint);
+  
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_uint64(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_uint64(const gpointer v1, LttvFieldValue v2) {
+
+  guint64* r = (guint64*) v1;
+  return (*r == v2.v_uint64);
+  
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_uint32(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_uint32(const gpointer v1, LttvFieldValue v2) {
+  guint32* r = (guint32*) v1;
+  return (*r == v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_uint16(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_uint16(const gpointer v1, LttvFieldValue v2) {
+  guint16* r = (guint16*) v1;
+  return (*r == v2.v_uint16);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_double(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_double(const gpointer v1, LttvFieldValue v2) {
+  double* r = (double*) v1;
+  return (*r == v2.v_double);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_string(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_string(const gpointer v1, LttvFieldValue v2) {
+  char* r = (char*) v1;
+  return (!g_strcasecmp(r,v2.v_string));
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_quark(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_quark(const gpointer v1, LttvFieldValue v2) {
+  GQuark* r = (GQuark*) v1;
+//  g_print("v1:%i v2:%i\n",*r,v2.v_uint32);
+  return (*r == v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_eq_ltttime(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_ltttime(const gpointer v1, LttvFieldValue v2) {
+  LttTime* r = (LttTime*) v1;
+  return ltt_time_compare(*r, v2.v_ltttime)==0?1:0;
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_uint(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_uint(const gpointer v1, LttvFieldValue v2) {
+  guint* r = (guint*) v1;
+  return (*r != v2.v_uint);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_uint64(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_uint64(const gpointer v1, LttvFieldValue v2) {
+  guint64* r = (guint64*) v1;
+  return (*r != v2.v_uint64);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_uint32(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_uint32(const gpointer v1, LttvFieldValue v2) {
+  guint32* r = (guint32*) v1;
+  return (*r != v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_uint16(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_uint16(const gpointer v1, LttvFieldValue v2) {
+  guint16* r = (guint16*) v1;
+  return (*r != v2.v_uint16);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_double(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_double(const gpointer v1, LttvFieldValue v2) {
+  double* r = (double*) v1;
+  return (*r != v2.v_double);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_string(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_string(const gpointer v1, LttvFieldValue v2) {
+  char* r = (char*) v1;
+  return (g_strcasecmp(r,v2.v_string));
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_quark(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_quark(const gpointer v1, LttvFieldValue v2) {
+  GQuark* r = (GQuark*) v1;
+  return (*r != v2.v_uint32);
+}
+
+
+/**
+ *  @fn gboolean lttv_apply_op_ne_ltttime(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'not equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_ltttime(const gpointer v1, LttvFieldValue v2) {
+  LttTime* r = (LttTime*) v1;
+  return ltt_time_compare(*r, v2.v_ltttime)!=0?1:0;
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_lt_uint(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_lt_uint(const gpointer v1, LttvFieldValue v2) {
+  guint* r = (guint*) v1;
+  return (*r < v2.v_uint);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_lt_uint64(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_lt_uint64(const gpointer v1, LttvFieldValue v2) {
+  guint64* r = (guint64*) v1;
+  return (*r < v2.v_uint64);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_lt_uint32(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_lt_uint32(const gpointer v1, LttvFieldValue v2) {
+  guint32* r = (guint32*) v1;
+  return (*r < v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_lt_uint16(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_lt_uint16(const gpointer v1, LttvFieldValue v2) {
+  guint16* r = (guint16*) v1;
+  return (*r < v2.v_uint16);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_lt_double(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_lt_double(const gpointer v1, LttvFieldValue v2) {
+  double* r = (double*) v1;
+  return (*r < v2.v_double);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_lt_ltttime(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_lt_ltttime(const gpointer v1, LttvFieldValue v2) {
+  LttTime* r = (LttTime*) v1;
+//  return ((r->tv_sec < v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec < v2.v_ltttime.tv_nsec)));
+  return ltt_time_compare(*r, v2.v_ltttime)==-1?1:0;
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_le_uint(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_le_uint(const gpointer v1, LttvFieldValue v2) {
+  guint* r = (guint*) v1;
+  return (*r <= v2.v_uint);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_le_uint64(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_le_uint64(const gpointer v1, LttvFieldValue v2) {
+  guint64* r = (guint64*) v1;
+  return (*r <= v2.v_uint64);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_le_uint32(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_le_uint32(const gpointer v1, LttvFieldValue v2) {
+  guint32* r = (guint32*) v1;
+  return (*r <= v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_le_uint16(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_le_uint16(const gpointer v1, LttvFieldValue v2) {
+  guint16* r = (guint16*) v1;
+  return (*r <= v2.v_uint16);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_le_double(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_le_double(const gpointer v1, LttvFieldValue v2) {
+  double* r = (double*) v1;
+  return (*r <= v2.v_double);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_le_ltttime(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'lower or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_le_ltttime(const gpointer v1, LttvFieldValue v2) {
+  LttTime* r = (LttTime*) v1;
+//  return ((r->tv_sec < v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec <= v2.v_ltttime.tv_nsec)));
+  return ltt_time_compare(*r, v2.v_ltttime)<1?1:0;
+}
+
+
+/**
+ *  @fn gboolean lttv_apply_op_gt_uint(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_gt_uint(const gpointer v1, LttvFieldValue v2) {
+  guint* r = (guint*) v1;
+  return (*r > v2.v_uint);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_gt_uint64(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_gt_uint64(const gpointer v1, LttvFieldValue v2) {
+  guint64* r = (guint64*) v1;
+  return (*r > v2.v_uint64);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_gt_uint32(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_gt_uint32(const gpointer v1, LttvFieldValue v2) {
+  guint32* r = (guint32*) v1;
+  return (*r > v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_gt_uint16(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_gt_uint16(const gpointer v1, LttvFieldValue v2) {
+  guint16* r = (guint16*) v1;
+  return (*r > v2.v_uint16);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_gt_double(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_gt_double(const gpointer v1, LttvFieldValue v2) {
+  double* r = (double*) v1;
+  return (*r > v2.v_double);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_gt_ltttime(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater than' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_gt_ltttime(const gpointer v1, LttvFieldValue v2) {
+  LttTime* r = (LttTime*) v1;
+//  return ((r->tv_sec > v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec > v2.v_ltttime.tv_nsec)));
+  return ltt_time_compare(*r, v2.v_ltttime)==1?1:0;
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ge_uint(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ge_uint(const gpointer v1, LttvFieldValue v2) {
+  guint* r = (guint*) v1;
+  return (*r >= v2.v_uint);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ge_uint64(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ge_uint64(const gpointer v1, LttvFieldValue v2) {
+  guint64* r = (guint64*) v1;
+  return (*r >= v2.v_uint64);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ge_uint32(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ge_uint32(const gpointer v1, LttvFieldValue v2) {
+  guint32* r = (guint32*) v1;
+  return (*r >= v2.v_uint32);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ge_uint16(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ge_uint16(const gpointer v1, LttvFieldValue v2) {
+  guint16* r = (guint16*) v1;
+  return (*r >= v2.v_uint16);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ge_double(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ge_double(const gpointer v1, LttvFieldValue v2) {
+  double* r = (double*) v1;
+  return (*r >= v2.v_double);
+}
+
+/**
+ *  @fn gboolean lttv_apply_op_ge_ltttime(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'greater or equal' operator to the
+ *  specified structure and value 
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ge_ltttime(const gpointer v1, LttvFieldValue v2) {
+  LttTime* r = (LttTime*) v1;
+//  return ((r->tv_sec > v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec >= v2.v_ltttime.tv_nsec)));
+  return ltt_time_compare(*r, v2.v_ltttime)>-1?1:0;
+}
+
+
+
+/**
+ *  Makes a copy of the current filter tree
+ *  @param tree pointer to the current tree
+ *  @return new copy of the filter tree
+ */
+LttvFilterTree*
+lttv_filter_tree_clone(const LttvFilterTree* tree) {
+
+  LttvFilterTree* newtree = lttv_filter_tree_new();  
+
+  newtree->node = tree->node;
+  newtree->left = tree->left;
+  if(newtree->left == LTTV_TREE_NODE) {
+    newtree->l_child.t = lttv_filter_tree_clone(tree->l_child.t);
+  } else if(newtree->left == LTTV_TREE_LEAF) {
+    newtree->l_child.leaf = lttv_simple_expression_new();
+    newtree->l_child.leaf->field = tree->l_child.leaf->field;
+    newtree->l_child.leaf->offset = tree->l_child.leaf->offset;
+    newtree->l_child.leaf->op = tree->l_child.leaf->op;
+    /* FIXME: special case for string copy ! */
+    newtree->l_child.leaf->value = tree->l_child.leaf->value;
+  }
+  newtree->right = tree->right;
+  if(newtree->right == LTTV_TREE_NODE) {
+    newtree->r_child.t = lttv_filter_tree_clone(tree->r_child.t);
+  } else if(newtree->right == LTTV_TREE_LEAF) {
+    newtree->r_child.leaf = lttv_simple_expression_new();
+    newtree->r_child.leaf->field = tree->r_child.leaf->field;
+    newtree->r_child.leaf->offset = tree->r_child.leaf->offset;
+    newtree->r_child.leaf->op = tree->r_child.leaf->op;
+    newtree->r_child.leaf->value = tree->r_child.leaf->value;
+  }
+  
+  return newtree;
+  
+}
+
+/**
+ *  Makes a copy of the current filter
+ *  @param filter pointer to the current filter
+ *  @return new copy of the filter
+ */
+LttvFilter*
+lttv_filter_clone(const LttvFilter* filter) {
+       if(!filter) return NULL;
+
+  LttvFilter* newfilter = g_new(LttvFilter,1); 
+
+  strcpy(newfilter->expression,filter->expression);
+
+  newfilter->head = lttv_filter_tree_clone(filter->head);
+  
+  return newfilter;
+    
+}
+
+
+/**
+ *  @fn LttvFilter* lttv_filter_new()
+ * 
+ *     Creates a new LttvFilter
+ *     @return the current LttvFilter or NULL if error
+ */
+LttvFilter*
+lttv_filter_new() {
+
+  LttvFilter* filter = g_new(LttvFilter,1);
+  filter->expression = NULL;
+  filter->head = NULL;
+
+  return filter;
+    
+}
+
+/**
+ *  @fn gboolean lttv_filter_update(LttvFilter*)
+ * 
+ *  Updates the current LttvFilter by building 
+ *  its tree based upon the expression string
+ *  @param filter pointer to the current LttvFilter
+ *  @return Failure/Success of operation
+ */
+gboolean
+lttv_filter_update(LttvFilter* filter) {
+    
+//  g_print("filter::lttv_filter_new()\n");            /* debug */
+  
+  if(filter->expression == NULL) return FALSE;
+  
+  int  
+    i, 
+    p_nesting=0,       /* parenthesis nesting value */
+    not=0;
+    
+  /* trees */
+  LttvFilterTree
+    *tree = lttv_filter_tree_new(),   /* main tree */
+    *subtree = NULL,                  /* buffer for subtrees */
+    *t1,                              /* buffer #1 */
+    *t2,                              /* buffer #2 */
+    *t3;                              /* buffer #3 */
+
+  /* 
+   * the filter
+   * If the tree already exists, 
+   * destroy it and build a new one
+   */
+  if(filter->head != NULL) lttv_filter_tree_destroy(filter->head);
+  filter->head = NULL;    /* will be assigned at the end */
+  /*
+   * Tree Stack
+   * each element of the list
+   * is a sub tree created 
+   * by the use of parenthesis in the 
+   * global expression.  The final tree 
+   * will be the one left at the root of 
+   * the list
+   */
+  GPtrArray *tree_stack = g_ptr_array_new();
+  g_ptr_array_add( tree_stack,(gpointer) tree );
+  
+  /* temporary values */
+  GString *a_field_component = g_string_new(""); 
+  GPtrArray *a_field_path = g_ptr_array_new(); 
+  
+  /* simple expression buffer */
+  LttvSimpleExpression* a_simple_expression = lttv_simple_expression_new(); 
+  
+  /*
+   *   Parse entire expression and construct
+   *   the binary tree.  There are two steps 
+   *   in browsing that string
+   *     1. finding boolean ops " &,|,^,! " and parenthesis " {,(,[,],),} "
+   *     2. finding simple expressions
+   *       - field path ( separated by dots )
+   *       - op ( >, <, =, >=, <=, !=)
+   *       - value ( integer, string ... )
+   *   To spare computing time, the whole 
+   *   string is parsed in this loop for a 
+   *   O(n) complexity order.
+   *
+   *  When encountering logical op &,|,^
+   *    1. parse the last value if any
+   *    2. create a new tree
+   *    3. add the expression (simple exp, or exp (subtree)) to the tree
+   *    4. concatenate this tree with the current tree on top of the stack
+   *  When encountering math ops >,>=,<,<=,=,!=
+   *    1. add to op to the simple expression
+   *    2. concatenate last field component to field path
+   *  When encountering concatening ops .
+   *    1. concatenate last field component to field path
+   *  When encountering opening parenthesis (,{,[
+   *    1. create a new subtree on top of tree stack
+   *  When encountering closing parenthesis ),},]
+   *    1. add the expression on right child of the current tree
+   *    2. the subtree is completed, allocate a new subtree
+   *    3. pop the tree value from the tree stack
+   */
+#ifdef TEST
+  struct timeval starttime;
+  struct timeval endtime;
+  gettimeofday(&starttime, NULL);
+#endif
+  
+  for(i=0;i<strlen(filter->expression);i++) {
+    // debug
+//    g_print("%c\n ",filter->expression[i]);
+    
+    switch(filter->expression[i]) {
+      /*
+       *   logical operators
+       */
+      case '&':   /* and */
+    
+        /* get current tree in tree stack */
+        t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
+
+        /* get current node at absolute right */
+        while(t1->right != LTTV_TREE_IDLE) {
+          g_assert(t1->right == LTTV_TREE_NODE);
+          t1 = t1->r_child.t;
+        }
+        t2 = lttv_filter_tree_new();
+        t2->node = LTTV_LOGICAL_AND;
+        t1->right = LTTV_TREE_NODE;
+        t1->r_child.t = t2;
+        if(not) {   /* add not operator to tree */
+          t3 = lttv_filter_tree_new();
+          t3->node = LTTV_LOGICAL_NOT;
+          t2->left = LTTV_TREE_NODE;
+          t2->l_child.t = t3;
+          t2 = t3;
+          not = 0;
+        }
+        if(subtree != NULL) {   /* append subtree to current tree */
+          t2->left = LTTV_TREE_NODE;
+          t2->l_child.t = subtree;
+          subtree = NULL;
+        } else {  /* append a simple expression */
+          lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE)); 
+          a_field_component = g_string_new("");
+          t2->left = LTTV_TREE_LEAF;
+          t2->l_child.leaf = a_simple_expression;
+          a_simple_expression = lttv_simple_expression_new(); 
+        }
+        break;
+      
+      case '|':   /* or */
+      
+        t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
+         while(t1->right != LTTV_TREE_IDLE) {
+          g_assert(t1->right == LTTV_TREE_NODE);
+          t1 = t1->r_child.t;
+        }
+        t2 = lttv_filter_tree_new();
+        t2->node = LTTV_LOGICAL_OR;
+        t1->right = LTTV_TREE_NODE;
+        t1->r_child.t = t2;
+        if(not) { // add not operator to tree
+          t3 = lttv_filter_tree_new();
+          t3->node = LTTV_LOGICAL_NOT;
+          t2->left = LTTV_TREE_NODE;
+          t2->l_child.t = t3;
+          t2 = t3;
+          not = 0;
+       }
+       if(subtree != NULL) {   /* append subtree to current tree */
+          t2->left = LTTV_TREE_NODE;
+          t2->l_child.t = subtree;
+          subtree = NULL;
+       } else {    /* append a simple expression */
+          lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE)); 
+          a_field_component = g_string_new("");
+          t2->left = LTTV_TREE_LEAF;
+          t2->l_child.leaf = a_simple_expression;
+          a_simple_expression = lttv_simple_expression_new();
+        }
+        break;
+      
+      case '^':   /* xor */
+        
+        t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
+        while(t1->right != LTTV_TREE_IDLE) {
+          g_assert(t1->right == LTTV_TREE_NODE);
+          t1 = t1->r_child.t;
+        }
+        t2 = lttv_filter_tree_new();
+        t2->node = LTTV_LOGICAL_XOR;
+        t1->right = LTTV_TREE_NODE;
+        t1->r_child.t = t2;
+        if(not) { // add not operator to tree
+          t3 = lttv_filter_tree_new();
+          t3->node = LTTV_LOGICAL_NOT;
+          t2->left = LTTV_TREE_NODE;
+          t2->l_child.t = t3;
+          t2 = t3;
+          not = 0;
+        }
+        if(subtree != NULL) {   /* append subtree to current tree */
+          t2->left = LTTV_TREE_NODE;
+          t2->l_child.t = subtree;
+          subtree = NULL;
+        } else {    /* append a simple expression */
+          lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE)); 
+          a_field_component = g_string_new("");
+          t2->left = LTTV_TREE_LEAF;
+          t2->l_child.leaf = a_simple_expression;
+          a_simple_expression = lttv_simple_expression_new(); 
+        }
+        break;
+      
+      case '!':   /* not, or not equal (math op) */
+        
+        if(filter->expression[i+1] == '=') {  /* != */
+          g_ptr_array_add( a_field_path,(gpointer) a_field_component );
+          lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
+          a_field_component = g_string_new("");         
+          lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_NE);
+          i++;
+        } else {  /* ! */
+          not=1;
+        }
+        break;
+      
+      case '(':   /* start of parenthesis */
+      case '[':
+      case '{':
+        
+        p_nesting++;      /* incrementing parenthesis nesting value */
+        t1 = lttv_filter_tree_new();
+        if(not) { /* add not operator to tree */
+          t3 = lttv_filter_tree_new();
+          t3->node = LTTV_LOGICAL_NOT;
+          t1->right = LTTV_TREE_NODE;
+          t1->r_child.t = t3;
+          not = 0;
+        }
+        g_ptr_array_add( tree_stack,(gpointer) t1 );
+        break;
+      
+      case ')':   /* end of parenthesis */
+      case ']':
+      case '}':
+        
+        p_nesting--;      /* decrementing parenthesis nesting value */
+        if(p_nesting<0 || tree_stack->len<2) {
+          g_warning("Wrong filtering options, the string\n\"%s\"\n\
+                     is not valid due to parenthesis incorrect use",filter->expression);       
+          return FALSE;
+        }
+  
+        /* there must at least be the root tree left in the array */
+        g_assert(tree_stack->len>0);
+        t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
+        while(t1->right != LTTV_TREE_IDLE) {
+           t1 = t1->r_child.t;
+        }
+        if(not) { // add not operator to tree
+          g_print("ici");
+          t3 = lttv_filter_tree_new();
+          t3->node = LTTV_LOGICAL_NOT;
+          t1->right = LTTV_TREE_NODE;
+          t1->r_child.t = t3;
+          t1 = t3;
+          not = 0;
+        }
+        if(subtree != NULL) {   /* append subtree to current tree */
+          t1->right = LTTV_TREE_NODE;
+          t1->r_child.t = subtree;
+          subtree = g_ptr_array_index(tree_stack,tree_stack->len-1);
+          g_ptr_array_remove_index(tree_stack,tree_stack->len-1);
+        } else {    /* assign subtree as current tree */
+          lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE)); 
+          a_field_component = g_string_new("");
+          t1->right = LTTV_TREE_LEAF;
+          t1->r_child.leaf = a_simple_expression;
+          a_simple_expression = lttv_simple_expression_new(); 
+          subtree = g_ptr_array_remove_index(tree_stack,tree_stack->len-1);
+        }
+        break;
+
+      /*       
+       *       mathematic operators
+       */
+      case '<':   /* lower, lower or equal */
+        
+        g_ptr_array_add( a_field_path,(gpointer) a_field_component );
+        lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
+        a_field_component = g_string_new("");         
+        if(filter->expression[i+1] == '=') { /* <= */
+          i++;
+          lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_LE);
+        } else lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_LT);
+       break;
+      
+      case '>':   /* higher, higher or equal */
+        
+        g_ptr_array_add( a_field_path,(gpointer) a_field_component );   
+        lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
+        a_field_component = g_string_new("");         
+        if(filter->expression[i+1] == '=') {  /* >= */
+          i++;
+          lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_GE);
+        } else lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_GT);
+       break;
+      
+      case '=':   /* equal */
+        
+        g_ptr_array_add( a_field_path,(gpointer) a_field_component );
+        lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
+        a_field_component = g_string_new("");         
+        lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_EQ);
+        break;
+        
+      /*
+       *  Field concatening caracter
+       */
+      case '.':   /* dot */
+        
+        /*
+         * divide field expression into elements 
+         * in a_field_path array.
+         *
+         * A dot can also be present in double values
+         */
+        if(a_simple_expression->field == LTTV_FILTER_UNDEFINED) {
+          g_ptr_array_add( a_field_path,(gpointer) a_field_component );
+          a_field_component = g_string_new("");
+        }
+        break;
+      case ' ':   /* ignore */
+      case '\n':  /* ignore */
+        break;
+      default:    /* concatening current string */
+        g_string_append_c(a_field_component,filter->expression[i]);
+    }
+  }
+
+  /*
+   * Preliminary check to see
+   * if tree was constructed correctly
+   */
+  if( p_nesting>0 ) { 
+    g_warning("Wrong filtering options, the string\n\"%s\"\n\
+        is not valid due to parenthesis incorrect use",filter->expression);    
+    return FALSE;
+  }
+  if(tree_stack->len != 1) /* only root tree should remain */ 
+    return FALSE;
+  
+  /*  
+   *  processing last element of expression   
+   */
+  t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
+  while(t1->right != LTTV_TREE_IDLE) {
+    g_assert(t1->right == LTTV_TREE_NODE);
+    t1 = t1->r_child.t;
+  }
+  if(not) { // add not operator to tree
+     t3 = lttv_filter_tree_new();
+     t3->node = LTTV_LOGICAL_NOT;
+     t1->right = LTTV_TREE_NODE;
+     t1->r_child.t = t3;
+     t1 = t3;
+     not = 0;
+  }
+  if(subtree != NULL) {  /* add the subtree */
+    t1->right = LTTV_TREE_NODE;
+    t1->r_child.t = subtree;
+    subtree = NULL;
+  } else {  /* add a leaf */
+    lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE)); 
+    a_field_component = NULL;
+    t1->right = LTTV_TREE_LEAF;
+    t1->r_child.leaf = a_simple_expression;
+    a_simple_expression = NULL;
+  }
+  
+  
+  /* free the pointer array */
+  g_assert(a_field_path->len == 0);
+  g_ptr_array_free(a_field_path,TRUE);
+
+  /* free the tree stack -- but keep the root tree */
+  filter->head = g_ptr_array_remove_index(tree_stack,0);
+  g_ptr_array_free(tree_stack,TRUE);
+  
+  /* free the field buffer if allocated */
+  if(a_field_component != NULL) g_string_free(a_field_component,TRUE); 
+  /* free the simple expression buffer if allocated */
+  if(a_simple_expression != NULL) lttv_simple_expression_destroy(a_simple_expression);
+  
+  g_assert(filter->head != NULL); /* tree should exist */
+  g_assert(subtree == NULL); /* remaining subtree should be included in main tree */
+#ifdef TEST
+  gettimeofday(&endtime, NULL);
+
+  /* Calcul du temps de l'algorithme */
+  double time1 = starttime.tv_sec + (starttime.tv_usec/1000000.0);
+  double time2 = endtime.tv_sec + (endtime.tv_usec/1000000.0);
+// g_print("Tree build took %.10f ms for strlen of %i\n",(time2-time1)*1000,strlen(filter->expression));
+  g_print("%.10f %i\n",(time2-time1)*1000,strlen(filter->expression));
+#endif
+  
+  /* debug */
+  g_debug("+++++++++++++++ BEGIN PRINT ++++++++++++++++\n");
+  lttv_print_tree(filter->head,0) ;
+  g_debug("+++++++++++++++ END PRINT ++++++++++++++++++\n");
+  
+  /* success */
+  return TRUE;
+
+}
+
+/**
+ *  @fn void lttv_filter_destroy(LttvFilter*)
+ * 
+ *  Destroy the current LttvFilter
+ *  @param filter pointer to the current LttvFilter
+ */
+void
+lttv_filter_destroy(LttvFilter* filter) {
+  
+       if(!filter) return;
+
+       if(filter->expression)
+         g_free(filter->expression);
+       if(filter->head)
+         lttv_filter_tree_destroy(filter->head);
+  g_free(filter);
+  
+}
+
+/**
+ *  @fn LttvFilterTree* lttv_filter_tree_new()
+ * 
+ *  Assign a new tree for the current expression
+ *  or sub expression
+ *  @return pointer of LttvFilterTree
+ */
+LttvFilterTree* 
+lttv_filter_tree_new() {
+  LttvFilterTree* tree;
+
+  tree = g_new(LttvFilterTree,1);
+  tree->node = 0; //g_new(lttv_expression,1);
+  tree->left = LTTV_TREE_IDLE;
+  tree->right = LTTV_TREE_IDLE;
+  tree->r_child.t = NULL;
+  tree->l_child.t = NULL;
+  
+  return tree;
+}
+
+/**
+ *  @fn void lttv_filter_append_expression(LttvFilter*,char*)
+ * 
+ *  Append a new expression to the expression 
+ *  defined in the current filter
+ *  @param filter pointer to the current LttvFilter
+ *  @param expression string that must be appended
+ *  @return Success/Failure of operation
+ */
+gboolean 
+lttv_filter_append_expression(LttvFilter* filter, const char *expression) {
+
+  if(expression == NULL) return FALSE;
+  if(filter == NULL) return FALSE;
+  if(expression[0] == '\0') return FALSE;  /* Empty expression */
+
+  GString* s = g_string_new("");
+  if(filter->expression != NULL) {
+    g_string_append(s,filter->expression);
+    g_string_append_c(s,'&');
+  }
+  g_string_append(s,expression);
+  g_free(filter->expression);
+  filter->expression = g_string_free(s,FALSE);
+  
+  /* TRUE if construction of tree proceeded without errors */
+  return lttv_filter_update(filter);
+  
+}
+
+/**
+ *  @fn void lttv_filter_clear_expression(LttvFilter*)
+ * 
+ *  Clear the filter expression from the 
+ *  current filter and sets its pointer to NULL
+ *  @param filter pointer to the current LttvFilter
+ */
+void 
+lttv_filter_clear_expression(LttvFilter* filter) {
+  
+  if(filter->expression != NULL) {
+    g_free(filter->expression);
+    filter->expression = NULL;
+  }
+  
+}
+
+/**
+ *  @fn void lttv_filter_tree_destroy(LttvFilterTree*)
+ * 
+ *  Destroys the tree and his sub-trees
+ *  @param tree Tree which must be destroyed
+ */
+void 
+lttv_filter_tree_destroy(LttvFilterTree* tree) {
+  if(tree == NULL) return;
+
+  if(tree->left == LTTV_TREE_LEAF) lttv_simple_expression_destroy(tree->l_child.leaf);
+  else if(tree->left == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->l_child.t);
+
+  if(tree->right == LTTV_TREE_LEAF) lttv_simple_expression_destroy(tree->r_child.leaf);
+  else if(tree->right == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->r_child.t);
+
+//  g_free(tree->node);
+  g_free(tree);
+}
+
+/**
+ *  Global parsing function for the current
+ *  LttvFilterTree
+ *  @param t pointer to the current LttvFilterTree
+ *  @param event current LttEvent, NULL if not used
+ *  @param tracefile current LttTracefile, NULL if not used
+ *  @param trace current LttTrace, NULL if not used
+ *  @param state current LttvProcessState, NULL if not used
+ *  @param context current LttvTracefileContext, NULL if not used
+ *  @return response of filter
+ */
+gboolean
+lttv_filter_tree_parse(
+        const LttvFilterTree* t,
+        const LttEvent* event,
+        const LttTracefile* tracefile,
+        const LttTrace* trace,
+        const LttvTracefileContext* context
+        /*,...*/) 
+{
+
+   /*
+   *  Each tree is parsed in inorder.
+   *  This way, it's possible to apply the left filter of the 
+   *  tree, then decide whether or not the right branch should 
+   *  be parsed depending on the linking logical operator
+   *
+   *  Each node consists in a
+   *  1. logical operator
+   *  2. left child ( node or simple expression )
+   *  3. right child ( node or simple expression )
+   *  
+   *  When the child is a simple expression, we must 
+   *  before all determine if the expression refers to 
+   *  a structure which is whithin observation ( not NULL ). 
+   *    -If so, the expression is evaluated.
+   *    -If not, the result is set to TRUE since this particular 
+   *     operation does not interfere with the lttv structure
+   *
+   *  The result of each simple expression will directly 
+   *  affect the next branch.  This way, depending on 
+   *  the linking logical operator, the parser will decide 
+   *  to explore or not the next branch.
+   *  1. AND OPERATOR
+   *     -If result of left branch is 0 / FALSE
+   *      then don't explore right branch and return 0;
+   *     -If result of left branch is 1 / TRUE then explore
+   *  2. OR OPERATOR
+   *     -If result of left branch is 1 / TRUE
+   *      then don't explore right branch and return 1;
+   *     -If result of left branch is 0 / FALSE then explore
+   *  3. XOR OPERATOR
+   *     -Result of left branch will not affect exploration of 
+   *      right branch
+   */
+    
+  gboolean lresult = FALSE, rresult = FALSE;
+
+  LttvProcessState* state;
+  
+  guint cpu = ltt_tracefile_num(context->tf);
+  LttvTraceState *ts = (LttvTraceState*)context->t_context;
+  state = ts->running_process[cpu];
+  
+  /*
+   * Parse left branch
+   */
+  if(t->left == LTTV_TREE_NODE) {
+      lresult = lttv_filter_tree_parse(t->l_child.t,event,tracefile,trace,context);
+  }
+  else if(t->left == LTTV_TREE_LEAF) {
+      lresult = lttv_filter_tree_parse_branch(t->l_child.leaf,event,tracefile,trace,state,context);
+  }
+   
+  /*
+   * Parse linking operator
+   * make a cutoff if possible
+   */
+  if((t->node & LTTV_LOGICAL_OR) && lresult == TRUE) return TRUE;
+  if((t->node & LTTV_LOGICAL_AND) && lresult == FALSE) return FALSE;
+
+  /*
+   * Parse right branch
+   */
+  if(t->right == LTTV_TREE_NODE) {
+      rresult = lttv_filter_tree_parse(t->r_child.t,event,tracefile,trace,context);
+  }
+  else if(t->right == LTTV_TREE_LEAF) {
+      rresult = lttv_filter_tree_parse_branch(t->r_child.leaf,event,tracefile,trace,state,context);
+  }
+
+  
+  /*
+   * Apply and return the 
+   * logical link between the 
+   * two operation
+   */
+  switch(t->node) {
+    case LTTV_LOGICAL_OR: return (lresult | rresult);
+    case LTTV_LOGICAL_AND: return (lresult & rresult);
+    case LTTV_LOGICAL_NOT: 
+      return (t->left==LTTV_TREE_LEAF)?!lresult:((t->right==LTTV_TREE_LEAF)?!rresult:TRUE);
+    case LTTV_LOGICAL_XOR: return (lresult ^ rresult);
+    case 0: return (rresult);
+    default: 
+      /*
+       * This case should never be 
+       * parsed, if so, this subtree
+       * is cancelled !
+       */
+      return TRUE;
+  }
+  
+}
+
+/**
+ *  This function parses a particular branch of the tree
+ *  @param se pointer to the current LttvSimpleExpression
+ *  @param event current LttEvent, NULL if not used
+ *  @param tracefile current LttTracefile, NULL if not used
+ *  @param trace current LttTrace, NULL if not used
+ *  @param state current LttvProcessState, NULL if not used
+ *  @param context current LttvTracefileContext, NULL if not used
+ *  @return response of filter
+ */
+gboolean 
+lttv_filter_tree_parse_branch(
+        const LttvSimpleExpression* se,
+        const LttEvent* event,
+        const LttTracefile* tracefile,
+        const LttTrace* trace,
+        const LttvProcessState* state,
+        const LttvTracefileContext* context) {
+
+    LttvFieldValue v;
+    v = se->value;
+    switch(se->field) {
+        case LTTV_FILTER_TRACE_NAME:
+            if(trace == NULL) return TRUE;
+            else {
+                GQuark quark = ltt_trace_name(trace);
+                return se->op((gpointer)&quark,v);
+            }
+            break;
+        case LTTV_FILTER_TRACEFILE_NAME:
+            if(tracefile == NULL) return TRUE;
+            else {
+                GQuark quark = ltt_tracefile_name(tracefile);
+                return se->op((gpointer)&quark,v);
+            }
+            break;
+        case LTTV_FILTER_STATE_PID:
+            if(state == NULL) return TRUE;
+            else return se->op((gpointer)&state->pid,v);
+            break;
+        case LTTV_FILTER_STATE_PPID:
+            if(state == NULL) return TRUE;
+            else return se->op((gpointer)&state->ppid,v);
+            break;
+        case LTTV_FILTER_STATE_CT:
+            if(state == NULL) return TRUE;
+            else {
+              return se->op((gpointer)&state->creation_time,v);
+            }
+            break;
+        case LTTV_FILTER_STATE_IT:
+            if(state == NULL) return TRUE;
+            else {
+              return se->op((gpointer)&state->insertion_time,v);
+            }
+            break;
+        case LTTV_FILTER_STATE_P_NAME:
+            /*
+             * All 'unnamed' for the moment  
+             */
+            if(state == NULL) return TRUE;
+            else {
+              GQuark quark = state->name;
+              return se->op((gpointer)&quark,v);
+            }
+            break;
+        case LTTV_FILTER_STATE_EX_MODE:
+            if(state == NULL) return TRUE;
+            else return se->op((gpointer)&state->state->t,v);
+            break;
+        case LTTV_FILTER_STATE_EX_SUBMODE:
+            if(state == NULL) return TRUE;
+            else return se->op((gpointer)&state->state->n,v);
+            break;
+        case LTTV_FILTER_STATE_P_STATUS:
+            if(state == NULL) return TRUE;
+            else return se->op((gpointer)&state->state->s,v);
+            break;
+        case LTTV_FILTER_STATE_CPU:
+            if(context == NULL) return TRUE;
+            else {
+              /* FIXME: not sure of that one  Mathieu : fixed.*/
+ //             GQuark quark = ((LttvTracefileState*)context)->cpu_name;
+ //                return se->op((gpointer)&quark,v);
+              if(state == NULL) return TRUE;
+              else return se->op((gpointer)&state->cpu,v);
+            }
+            break;
+        case LTTV_FILTER_EVENT_NAME:
+            if(event == NULL) return TRUE;
+            else {
+              LttEventType* et;
+              et = ltt_event_eventtype(event);
+              GQuark quark = ltt_eventtype_name(et);
+              return se->op((gpointer)&quark,v);
+            }
+            break;
+         case LTTV_FILTER_EVENT_FACILITY:
+            if(event == NULL) return TRUE;
+            else {
+              LttFacility* fac;
+              fac = ltt_event_facility(event);
+              GQuark quark = ltt_facility_name(fac);
+              return se->op((gpointer)&quark,v);
+            }
+            break;
+        case LTTV_FILTER_EVENT_CATEGORY:
+            /*
+             * TODO: Not yet implemented
+             */
+            return TRUE;
+            break;
+        case LTTV_FILTER_EVENT_TIME:
+            if(event == NULL) return TRUE;
+            else {
+                LttTime time = ltt_event_time(event);
+                return se->op((gpointer)&time,v);
+            }
+            break;
+        case LTTV_FILTER_EVENT_TSC:
+            if(event == NULL) return TRUE;
+            else {
+              LttCycleCount count = ltt_event_cycle_count(event);
+              return se->op((gpointer)&count,v);
+            }
+            break;
+        case LTTV_FILTER_EVENT_FIELD:
+            /*
+             * TODO: Use the offset to 
+             * find the dynamic field 
+             * in the event struct
+             */
+            return TRUE; 
+        default:
+            /*
+             * This case should never be 
+             * parsed, if so, the whole 
+             * filtering is cancelled
+             */
+            g_warning("Error while parsing the filter tree");
+            return TRUE;
+    }
+
+    /* should never get here */
+    return TRUE;
+    
+}
+
+
+
+/**
+ *  Debug function.  Prints tree memory allocation.
+ *  @param t the pointer to the current LttvFilterTree
+ */
+void
+lttv_print_tree(const LttvFilterTree* t, const int count) {
+
+  g_debug("node:%p lchild:%p rchild:%p depth:%i\n",t, //t->l_child.t,t->r_child.t);
+          (t->left==LTTV_TREE_NODE)?t->l_child.t:NULL,
+          (t->right==LTTV_TREE_NODE)?t->r_child.t:NULL,
+          count);
+  g_debug("logic operator: %s\n",(t->node&1)?"OR":((t->node&2)?"AND":((t->node&4)?"NOT":((t->node&8)?"XOR":"IDLE"))));
+  g_debug("|-> left branch %p is a %s\n",t->l_child.t,(t->left==LTTV_TREE_NODE)?"NODE":((t->left==LTTV_TREE_LEAF)?"LEAF":"IDLE"));
+  if(t->left == LTTV_TREE_LEAF) {
+    g_debug("| |-> field type number: %i\n",t->l_child.leaf->field);
+    g_debug("| |-> offset is: %i\n",t->l_child.leaf->offset);
+    g_debug("| |-> operator function is: %p\n",t->l_child.leaf->op);
+  }
+  g_debug("|-> right branch %p is a %s\n",t->r_child.t,(t->right==LTTV_TREE_NODE)?"NODE":((t->right==LTTV_TREE_LEAF)?"LEAF":"IDLE"));
+  if(t->right == LTTV_TREE_LEAF) {
+    g_debug("| |-> field type number: %i\n",t->r_child.leaf->field);
+    g_debug("| |-> offset is: %i\n",t->r_child.leaf->offset);
+    g_debug("| |-> operator function is: %p\n",t->r_child.leaf->op);
+  }
+
+  if(t->left == LTTV_TREE_NODE) lttv_print_tree(t->l_child.t,count+1);
+  if(t->right == LTTV_TREE_NODE) lttv_print_tree(t->r_child.t,count+1);
+}
+
+/**
+ *  @fn static void module_init()
+ * 
+ *  Initializes the filter module and specific values
+ */
+static void module_init()
+{
+
+}
+
+/**
+ *  Destroys the filter module and specific values
+ */
+static void module_destroy() 
+{
+
+}
+
+
+LTTV_MODULE("filter", "Filters traceset and events", \
+    "Filters traceset and events specifically to user input", \
+    module_init, module_destroy)
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/filter.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/filter.h
new file mode 100644 (file)
index 0000000..fcc2d78
--- /dev/null
@@ -0,0 +1,357 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2005 Michel Dagenais and Simon Bouvier-Zappa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef FILTER_H
+#define FILTER_H
+
+/*! \file lttv/lttv/filter.h
+ *  \brief Defines the core filter of application 
+ *
+ *  A filter expression consists in nested AND, OR and NOT expressions
+ *  involving boolean relation (>, >=, =, !=, <, <=) between event fields and 
+ *  specific values. It is compiled into an efficient data structure which
+ *  is used in functions to check if a given event or tracefile satisfies the
+ *  filter.
+ * 
+ *  The grammar for filters is:
+ * 
+ *  filter = expression
+ * 
+ *  expression = "(" expression ")" | "!" expression | 
+ *              expression "&&" expression | expression "||" expression |
+ *              simpleExpression
+ *
+ *  simpleExpression = fieldPath op value
+ *
+ *  fieldPath = fieldComponent [ "." fieldPath ]
+ *
+ *  fieldComponent = name [ "[" integer "]" ]
+ *
+ *  value = integer | double | string 
+ */
+
+
+#include <lttv/traceset.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/module.h>
+#include <ltt/ltt.h>
+#include <ltt/time.h>
+#include <ltt/event.h>
+
+/* structures prototypes */
+typedef enum _LttvStructType LttvStructType; 
+typedef enum _LttvFieldType LttvFieldType; 
+typedef enum _LttvExpressionOp LttvExpressionOp;
+typedef enum _LttvTreeElement LttvTreeElement;
+typedef enum _LttvLogicalOp LttvLogicalOp;
+
+typedef union _LttvFieldValue LttvFieldValue;
+
+typedef struct _LttvSimpleExpression LttvSimpleExpression;
+typedef struct _LttvFilterTree LttvFilterTree;
+
+#ifndef LTTVFILTER_TYPE_DEFINED
+typedef struct _LttvFilter LttvFilter;
+#define LTTVFILTER_TYPE_DEFINED
+#endif
+
+/**
+ * @enum _LttvStructType
+ * @brief The lttv structures
+ *
+ * the LttvStructType enumerates 
+ * the possible structures for the 
+ * lttv core filter
+ */
+enum _LttvStructType {
+  LTTV_FILTER_TRACE,                /**< trace (LttTrace) */
+  LTTV_FILTER_TRACESET,             /**< traceset */
+  LTTV_FILTER_TRACEFILE,            /**< tracefile (LttTracefile) */
+  LTTV_FILTER_EVENT,                /**< event (LttEvent) */
+  LTTV_FILTER_STATE                 /**< state (LttvProcessState) */
+};
+
+/**
+ * @enum _LttvFieldType
+ * @brief Possible fields for the structures
+ *
+ * the LttvFieldType enum consists on 
+ * all the hardcoded structures and 
+ * their appropriate fields on which 
+ * filters can be applied.
+ */
+enum _LttvFieldType {
+  LTTV_FILTER_TRACE_NAME,             /**< trace.name (char*) */
+  LTTV_FILTER_TRACEFILE_NAME,         /**< tracefile.name (char*) */
+  LTTV_FILTER_STATE_PID,              /**< state.pid (guint) */
+  LTTV_FILTER_STATE_PPID,             /**< state.ppid (guint) */
+  LTTV_FILTER_STATE_CT,               /**< state.creation_time (double) */
+  LTTV_FILTER_STATE_IT,               /**< state.insertion_time (double) */
+  LTTV_FILTER_STATE_P_NAME,           /**< state.process_name (char*) */
+  LTTV_FILTER_STATE_EX_MODE,          /**< state.execution_mode (LttvExecutionMode) */
+  LTTV_FILTER_STATE_EX_SUBMODE,       /**< state.execution_submode (LttvExecutionSubmode) */
+  LTTV_FILTER_STATE_P_STATUS,         /**< state.process_status (LttvProcessStatus) */
+  LTTV_FILTER_STATE_CPU,              /**< state.cpu (?last_cpu?) */
+  LTTV_FILTER_EVENT_NAME,             /**< event.name (char*) */
+  LTTV_FILTER_EVENT_FACILITY,         /**< event.facility (char*) */
+  LTTV_FILTER_EVENT_CATEGORY,         /**< FIXME: not implemented */
+  LTTV_FILTER_EVENT_TIME,             /**< event.time (double) */
+  LTTV_FILTER_EVENT_TSC,              /**< event.tsc (double) */
+  LTTV_FILTER_EVENT_FIELD,            /**< dynamic field, specified in core.xml */
+  LTTV_FILTER_UNDEFINED               /**< undefined field */
+};
+  
+/**
+ *     @enum _LttvExpressionOp
+ *  @brief Contains possible operators
+ *
+ *  This enumeration defines the 
+ *  possible operator used to compare 
+ *  right and left member in simple 
+ *  expression
+ */
+enum _LttvExpressionOp
+{ 
+  LTTV_FIELD_EQ,                           /**< equal */
+  LTTV_FIELD_NE,                           /**< not equal */
+  LTTV_FIELD_LT,                           /**< lower than */
+  LTTV_FIELD_LE,                           /**< lower or equal */
+  LTTV_FIELD_GT,                           /**< greater than */
+  LTTV_FIELD_GE                                    /**< greater or equal */
+};
+
+/**
+ *  @union _LttvFieldValue
+ *  @brief Contains possible field values
+ *
+ *  This particular union defines the 
+ *  possible set of values taken by the 
+ *  right member of a simple expression.  
+ *  It is used for comparison whithin the 
+ *  'operators' functions
+ */
+union _LttvFieldValue {
+  guint64 v_uint64;                   /**< unsigned int of 64 bytes */
+  guint32 v_uint32;                   /**< unsigned int of 32 bytes */
+  guint16 v_uint16;                   /**< unsigned int of 16 bytes */
+  guint16 v_uint;                     /**< unsigned int */
+  double v_double;                    /**< double */
+  char* v_string;                     /**< string */
+  LttTime v_ltttime;                  /**< LttTime */
+};
+
+/**
+ * @enum _LttvTreeElement
+ * @brief element types for the tree nodes
+ *
+ * LttvTreeElement defines the possible 
+ * types of nodes which build the LttvFilterTree.  
+ */
+enum _LttvTreeElement {
+  LTTV_TREE_IDLE,                     /**< this node does nothing */
+  LTTV_TREE_NODE,                     /**< this node contains a logical operator */
+  LTTV_TREE_LEAF                      /**< this node is a leaf and contains a simple expression */
+};
+
+
+/**
+ * @struct _LttvSimpleExpression
+ * @brief simple expression structure
+ *
+ * An LttvSimpleExpression is the base 
+ * of all filtering operations.  It also 
+ * populates the leaves of the
+ * LttvFilterTree.  Each expression 
+ * consists basically in a structure 
+ * field, an operator and a specific 
+ * value.
+ */
+struct _LttvSimpleExpression
+{ 
+  gint field;                               /**< left member of simple expression */                  
+  gint offset;                              /**< offset used for dynamic fields */
+  gboolean (*op)(gpointer,LttvFieldValue);  /**< operator of simple expression */
+  LttvFieldValue value;                     /**< right member of simple expression */
+};
+
+/**
+ * @enum _LttvLogicalOp
+ * @brief logical operators
+ * 
+ * Contains the possible values taken 
+ * by logical operator used to link 
+ * simple expression.  Values are 
+ * AND, OR, XOR or NOT
+ */
+enum _LttvLogicalOp {
+    LTTV_LOGICAL_OR = 1,              /**< OR (1) */
+    LTTV_LOGICAL_AND = 1<<1,          /**< AND (2) */
+    LTTV_LOGICAL_NOT = 1<<2,          /**< NOT (4) */
+    LTTV_LOGICAL_XOR = 1<<3           /**< XOR (8) */
+};
+    
+/**
+ *  @struct _LttvFilterTree
+ *  @brief The filtering tree
+ *  
+ *  The filtering tree is used to represent the 
+ *  expression string in its entire hierarchy 
+ *  composed of simple expressions and logical 
+ *  operators
+ */
+struct _LttvFilterTree {
+  int node;                         /**< value of LttvLogicalOp */
+  LttvTreeElement left;             /**< nature of left branch (node/leaf) */
+  LttvTreeElement right;            /**< nature of right branch (node/leaf) */
+  union {
+    LttvFilterTree* t;              
+    LttvSimpleExpression* leaf;     
+  } l_child;                        /**< left branch of tree */
+  union {
+    LttvFilterTree* t;              
+    LttvSimpleExpression* leaf;     
+  } r_child;                        /**< right branch of tree */
+};
+
+/**
+ * @struct _LttvFilter
+ * @brief The filter
+ * 
+ * Contains a binary tree of filtering options along 
+ * with the expression itself.
+ */
+struct _LttvFilter {
+  char *expression;                 /**< filtering expression string */
+  LttvFilterTree *head;             /**< tree associated to expression */
+};
+
+/*
+ * Simple Expression
+ */
+LttvSimpleExpression* lttv_simple_expression_new();
+
+gboolean lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se);
+
+gboolean lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionOp op);
+
+gboolean lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value);
+
+void lttv_simple_expression_destroy(LttvSimpleExpression* se);
+
+
+/*
+ * Logical operators functions
+ */
+
+gboolean lttv_apply_op_eq_uint(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_uint64(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_uint32(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_uint16(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_double(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_string(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_quark(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_eq_ltttime(const gpointer v1, LttvFieldValue v2);
+
+gboolean lttv_apply_op_ne_uint(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_uint64(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_uint32(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_uint16(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_double(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_string(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_quark(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ne_ltttime(const gpointer v1, LttvFieldValue v2);
+
+gboolean lttv_apply_op_lt_uint(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_lt_uint64(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_lt_uint32(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_lt_uint16(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_lt_double(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_lt_ltttime(const gpointer v1, LttvFieldValue v2);
+
+gboolean lttv_apply_op_le_uint(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_le_uint64(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_le_uint32(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_le_uint16(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_le_double(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_le_ltttime(const gpointer v1, LttvFieldValue v2);
+
+gboolean lttv_apply_op_gt_uint(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_gt_uint64(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_gt_uint32(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_gt_uint16(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_gt_double(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_gt_ltttime(const gpointer v1, LttvFieldValue v2);
+
+gboolean lttv_apply_op_ge_uint(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ge_uint64(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ge_uint32(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ge_uint16(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ge_double(const gpointer v1, LttvFieldValue v2);
+gboolean lttv_apply_op_ge_ltttime(const gpointer v1, LttvFieldValue v2);
+
+/*
+ * Cloning
+ */
+
+LttvFilterTree* lttv_filter_tree_clone(const LttvFilterTree* tree);
+
+LttvFilter* lttv_filter_clone(const LttvFilter* filter);
+
+/* 
+ * LttvFilter 
+ */
+LttvFilter *lttv_filter_new();
+
+gboolean lttv_filter_update(LttvFilter* filter);
+
+void lttv_filter_destroy(LttvFilter* filter);
+
+gboolean lttv_filter_append_expression(LttvFilter* filter, const char *expression);
+
+void lttv_filter_clear_expression(LttvFilter* filter);
+
+/*
+ * LttvFilterTree 
+ */
+LttvFilterTree* lttv_filter_tree_new();
+
+void lttv_filter_tree_destroy(LttvFilterTree* tree);
+
+gboolean lttv_filter_tree_parse(
+        const LttvFilterTree* t,
+        const LttEvent* event,
+        const LttTracefile* tracefile,
+        const LttTrace* trace,
+        const LttvTracefileContext* context);
+
+gboolean lttv_filter_tree_parse_branch(
+        const LttvSimpleExpression* se,
+        const LttEvent* event,
+        const LttTracefile* tracefile,
+        const LttTrace* trace,
+        const LttvProcessState* state,
+        const LttvTracefileContext* context);
+
+/*
+ *  Debug functions
+ */
+void lttv_print_tree(const LttvFilterTree* t, const int count);
+
+#endif // FILTER_H
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/hook.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/hook.c
new file mode 100644 (file)
index 0000000..c7b43a5
--- /dev/null
@@ -0,0 +1,460 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/hook.h>
+#include <ltt/compiler.h>
+#include <ltt/ltt.h>
+
+typedef struct _LttvHookClosure {
+  LttvHook      hook;
+  void         *hook_data;
+  LttvHookPrio  prio;
+  guint         ref_count;
+} LttvHookClosure;
+
+gint lttv_hooks_prio_compare(LttvHookClosure *a, LttvHookClosure *b)
+{
+  gint ret=0;
+  if(a->prio < b->prio) ret = -1;
+  else if(a->prio > b->prio) ret = 1;
+  return ret;
+}
+
+
+LttvHooks *lttv_hooks_new() 
+{
+  return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure));
+}
+
+
+void lttv_hooks_destroy(LttvHooks *h) 
+{
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "lttv_hooks_destroy()");
+  g_array_free(h, TRUE);
+}
+
+
+void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p) 
+{
+  LttvHookClosure *c, new_c;
+  guint i;
+  
+  if(unlikely(h == NULL))g_error("Null hook added");
+
+  new_c.hook = f;
+  new_c.hook_data = hook_data;
+  new_c.prio = p;
+  new_c.ref_count = 1;
+
+  /* Preliminary check for duplication */
+  /* only hook and hook data is checked */
+  for(i = 0; i < h->len; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(new_c.hook == c->hook && new_c.hook_data == c->hook_data) {
+      g_assert(new_c.prio == c->prio);
+      c->ref_count++;
+      return;
+    }
+  }
+
+
+  for(i = 0; i < h->len; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(new_c.prio < c->prio) {
+      g_array_insert_val(h,i,new_c);
+      return;
+    }
+  }
+  if(i == h->len)
+    g_array_append_val(h,new_c);
+}
+
+/* lttv_hooks_add_list
+ *
+ * Adds a sorted list into another sorted list.
+ *
+ * Note : h->len is modified, but only incremented. This assures
+ * its coherence through the function.
+ *
+ * j is an index to the element following the last one added in the
+ * destination array.
+ */
+void lttv_hooks_add_list(LttvHooks *h, const LttvHooks *list) 
+{
+  guint i,j,k;
+  LttvHookClosure *c;
+  const LttvHookClosure *new_c;
+
+  if(unlikely(list == NULL)) return;
+
+  for(i = 0, j = 0 ; i < list->len; i++) {
+    new_c = &g_array_index(list, LttvHookClosure, i);
+    gboolean found=FALSE;
+
+    /* Preliminary check for duplication */
+    /* only hook and hook data is checked, not priority */
+    for(k = 0; k < h->len; k++) {
+      c = &g_array_index(h, LttvHookClosure, k);
+      if(new_c->hook == c->hook && new_c->hook_data == c->hook_data) {
+        /* Found another identical entry : increment its ref_count and
+         * jump over the source index */
+        g_assert(new_c->prio == c->prio);
+        found=TRUE;
+        c->ref_count++;
+        break;
+      }
+    }
+
+    if(!found) {
+      /* If not found, add it to the destination array */
+      while(j < h->len) {
+        c = &g_array_index(h, LttvHookClosure, j);
+        if(new_c->prio < c->prio) {
+          g_array_insert_val(h,j,*new_c);
+          j++;
+          break;
+        }
+        else j++;
+      }
+      if(j == h->len) {
+        g_array_append_val(h,*new_c);
+        j++;
+      }
+    }
+  }
+}
+
+
+void *lttv_hooks_remove(LttvHooks *h, LttvHook f)
+{
+  unsigned i;
+
+  void *hook_data;
+
+  LttvHookClosure *c;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(c->hook == f) {
+      if(c->ref_count == 1) {
+        hook_data = c->hook_data;
+        lttv_hooks_remove_by_position(h, i);
+        return hook_data;
+      } else {
+        g_assert(c->ref_count != 0);
+        c->ref_count--;
+        return NULL;  /* We do not want anyone to free a hook_data 
+                         still referenced */
+      }
+    }
+  }
+  return NULL;
+}
+
+
+void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data)
+{
+  unsigned i;
+
+  LttvHookClosure *c;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(c->hook == f && c->hook_data == hook_data) {
+      if(c->ref_count == 1) {
+        lttv_hooks_remove_by_position(h, i);
+        return;
+      } else {
+        g_assert(c->ref_count != 0);
+        c->ref_count--;
+        return;
+      }
+    }
+  }
+}
+
+
+void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list)
+{
+  guint i, j;
+
+  LttvHookClosure *c, *c_list;
+
+  if(list == NULL) return;
+  for(i = 0, j = 0 ; i < h->len && j < list->len ;) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    c_list = &g_array_index(list, LttvHookClosure, j);
+    if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) {
+      if(c->ref_count == 1) {
+        lttv_hooks_remove_by_position(h, i);
+      } else {
+        g_assert(c->ref_count != 0);
+        c->ref_count--;
+      }
+      j++;
+    }
+    else i++;
+  }
+
+  /* Normally the hooks in h are ordered as in list. If this is not the case,
+     try harder here. */
+
+  if(unlikely(j < list->len)) {
+    for(; j < list->len ; j++) {
+      c_list = &g_array_index(list, LttvHookClosure, j);
+      lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data);
+    }
+  }
+}
+
+
+unsigned lttv_hooks_number(LttvHooks *h)
+{
+  return h->len;
+}
+
+
+void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data,
+                                              LttvHookPrio *p)
+{
+  LttvHookClosure *c;
+
+  if(unlikely(i >= h->len))
+  {
+    *f = NULL;
+    *hook_data = NULL;
+    *p = 0;
+    return;
+  }
+  
+  c = &g_array_index(h, LttvHookClosure, i);
+  *f = c->hook;
+  *hook_data = c->hook_data;
+  *p = c->prio;
+}
+
+
+void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i)
+{
+  g_array_remove_index(h, i);
+}
+
+gboolean lttv_hooks_call(LttvHooks *h, void *call_data)
+{
+  gboolean ret, sum_ret = FALSE;
+
+  LttvHookClosure *c;
+
+  guint i;
+
+  if(likely(h != NULL)) {
+    for(i = 0 ; i < h->len ; i++) {
+      c = &g_array_index(h, LttvHookClosure, i);
+      ret = c->hook(c->hook_data,call_data);
+      sum_ret = sum_ret || ret;
+    }
+  }
+  return sum_ret;
+}
+
+
+gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data)
+{
+  LttvHookClosure *c;
+
+  guint i;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(unlikely(c->hook(c->hook_data,call_data))) return TRUE;
+  }
+  return FALSE;
+}
+
+/* Optimised for h1 == NULL, h2 != NULL. This is the case
+ * for optimised computation (with specific by id hooks, but
+ * no main hooks).
+ *
+ * The second case that should occur the most often is
+ * h1 != NULL , h2 == NULL.
+ */
+gint lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
+                               LttvHooks *h2, void *call_data2)
+{
+  gint ret, sum_ret = 0;
+
+  LttvHookClosure *c1, *c2;
+
+  guint i, j;
+
+  if(unlikely(h1 != NULL)) {
+    if(unlikely(h2 != NULL)) {
+      for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) {
+        c1 = &g_array_index(h1, LttvHookClosure, i);
+        c2 = &g_array_index(h2, LttvHookClosure, j);
+        if(c1->prio <= c2->prio) {
+          ret = c1->hook(c1->hook_data,call_data1);
+          sum_ret = sum_ret | ret;
+          i++;
+        }
+        else {
+          ret = c2->hook(c2->hook_data,call_data2);
+          sum_ret = sum_ret | ret;
+          j++;
+        }
+      }
+      /* Finish the last list with hooks left */
+      for(;i < h1->len; i++) {
+        c1 = &g_array_index(h1, LttvHookClosure, i);
+        ret = c1->hook(c1->hook_data,call_data1);
+        sum_ret = sum_ret | ret;
+      }
+      for(;j < h2->len; j++) {
+        c2 = &g_array_index(h2, LttvHookClosure, j);
+        ret = c2->hook(c2->hook_data,call_data2);
+        sum_ret = sum_ret | ret;
+      }
+    } else {  /* h1 != NULL && h2 == NULL */
+      for(i = 0 ; i < h1->len ; i++) {
+        c1 = &g_array_index(h1, LttvHookClosure, i);
+        ret = c1->hook(c1->hook_data,call_data1);
+        sum_ret = sum_ret | ret;
+      }
+    }
+  } else if(likely(h2 != NULL)) { /* h1 == NULL && h2 != NULL */
+     for(j = 0 ; j < h2->len ; j++) {
+      c2 = &g_array_index(h2, LttvHookClosure, j);
+      ret = c2->hook(c2->hook_data,call_data2);
+      sum_ret = sum_ret | ret;
+    }
+  }
+
+  return sum_ret;
+}
+
+gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1,
+                                     LttvHooks *h2, void *call_data2)
+{
+  LttvHookClosure *c1, *c2;
+
+  guint i, j;
+
+  if(unlikely(h1 != NULL)) {
+    if(unlikely(h2 != NULL)) {
+      for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) {
+        c1 = &g_array_index(h1, LttvHookClosure, i);
+        c2 = &g_array_index(h2, LttvHookClosure, j);
+        if(c1->prio <= c2->prio) {
+          if(c1->hook(c1->hook_data,call_data1)) return TRUE;
+            i++;
+        }
+        else {
+          if(c2->hook(c2->hook_data,call_data2)) return TRUE;
+          j++;
+        }
+      }
+      /* Finish the last list with hooks left */
+      for(;i < h1->len; i++) {
+        c1 = &g_array_index(h1, LttvHookClosure, i);
+        if(c1->hook(c1->hook_data,call_data1)) return TRUE;
+      }
+      for(;j < h2->len; j++) {
+        c2 = &g_array_index(h2, LttvHookClosure, j);
+        if(c2->hook(c2->hook_data,call_data2)) return TRUE;
+      }
+    } else { /* h2 == NULL && h1 != NULL */
+      for(i = 0 ; i < h1->len ; i++) {
+        c1 = &g_array_index(h1, LttvHookClosure, i);
+        if(c1->hook(c1->hook_data,call_data1)) return TRUE;
+      }
+    }
+  } else if(likely(h2 != NULL)) { /* h1 == NULL && h2 != NULL */
+    for(j = 0 ; j < h2->len ; j++) {
+      c2 = &g_array_index(h2, LttvHookClosure, j);
+      if(c2->hook(c2->hook_data,call_data2)) return TRUE;
+    }
+  }
+   
+  return FALSE;
+
+}
+
+/* Two pointer arrays : 
+ * * one indexed by id for quick search : 
+ *  size : max id
+ *  typically 4 bytes * 256 facilities * 10 events = 10kbytes
+ * * another array that keeps a list of used numbers (for later deletion)
+ *  size : number of ids used.
+ */
+
+LttvHooksById *lttv_hooks_by_id_new() 
+{
+  LttvHooksById *h = g_new(LttvHooksById, 1);
+  h->index = g_ptr_array_sized_new(NUM_FACILITIES * AVG_EVENTS_PER_FACILITIES);
+  h->array = g_array_sized_new(FALSE, FALSE, sizeof(guint), 50);
+  return h;
+}
+
+
+void lttv_hooks_by_id_destroy(LttvHooksById *h) 
+{
+  guint i;
+
+  for(i = 0 ; i < h->array->len ; i++) {
+    guint index = g_array_index(h->array, guint, i);
+    if(h->index->pdata[index] != NULL) { /* hook may have been removed */
+      lttv_hooks_destroy(h->index->pdata[index]);
+      h->index->pdata[index] = NULL;  /* Must be there in case of 
+                                         multiple addition of the same index */
+    }
+  }
+  g_ptr_array_free(h->index, TRUE);
+  g_array_free(h->array, TRUE);
+}
+
+/* Optimised for searching an existing hook */
+LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id)
+{
+  if(unlikely(h->index->len <= id)) g_ptr_array_set_size(h->index, id + 1);
+  if(unlikely(h->index->pdata[id] == NULL)) {
+    h->index->pdata[id] = lttv_hooks_new();
+    g_array_append_val(h->array, id);
+  }
+  return h->index->pdata[id];
+}
+
+
+unsigned lttv_hooks_by_id_max_id(LttvHooksById *h)
+{
+  return h->index->len;
+}
+
+/* We don't bother removing the used slot array id : lttv_hooks_by_id_destroy is
+ * almost never called and is able to deal with used slot repetition. */
+void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id)
+{
+  if(likely(id < h->index->len && h->index->pdata[id] != NULL)) {
+    lttv_hooks_destroy((LttvHooks *)h->index->pdata[id]);
+    h->index->pdata[id] = NULL;
+  }
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/hook.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/hook.h
new file mode 100644 (file)
index 0000000..197184a
--- /dev/null
@@ -0,0 +1,168 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * 25/05/2004 Mathieu Desnoyers : Hook priorities
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef HOOK_H
+#define HOOK_H
+
+#include <glib.h>
+#include <ltt/compiler.h>
+
+/* A hook is a function to call with the supplied hook data, and with 
+   call site specific data (e.g., hooks for events are called with a 
+   pointer to the current event). */
+
+typedef gboolean (*LttvHook)(void *hook_data, void *call_data);
+
+
+/* A list of hooks allows registering hooks to be called later. */
+
+typedef GArray LttvHooks;
+
+/* A priority associated with each hook, from -19 (high prio) to 20 (low prio)
+ * 0 being the default priority.
+ *
+ * Priority ordering is done in the lttv_hooks_add and lttv_hooks_add_list 
+ * functions. Hook removal does not change list order.
+ */
+
+#define LTTV_PRIO_DEFAULT 50
+#define LTTV_PRIO_HIGH 0
+#define LTTV_PRIO_LOW 99
+
+typedef gint LttvHookPrio;
+
+/* Create and destroy a list of hooks */
+
+LttvHooks *lttv_hooks_new();
+
+void lttv_hooks_destroy(LttvHooks *h);
+
+
+/* Add a hook and its hook data to the list */
+
+void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p);
+
+
+/* Add a list of hooks to the list h */
+
+void lttv_hooks_add_list(LttvHooks *h, const LttvHooks *list);
+
+
+/* Remove a hook from the list. Return the hook data. */
+
+void *lttv_hooks_remove(LttvHooks *h, LttvHook f);
+
+
+/* Remove a hook from the list checking that the hook data match. */
+
+void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data);
+
+
+/* Remove a list of hooks from the hooks list in h. */
+
+void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list);
+
+
+/* Return the number of hooks in the list */
+
+unsigned lttv_hooks_number(LttvHooks *h);
+
+
+/* Return the hook at the specified position in the list.
+ * *f and *hook_data are NULL if no hook exists at that position. */
+
+void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data,
+                                              LttvHookPrio *p);
+
+
+/* Remove the specified hook. The position of the following hooks may change */
+/* The hook is removed from the list event if its ref_count is higher than 1 */
+
+void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i);
+
+
+/* Call all the hooks in the list, each with its hook data, 
+   with the specified call data, in priority order. Return TRUE if one hook
+   returned TRUE. */
+
+gboolean lttv_hooks_call(LttvHooks *h, void *call_data);
+
+
+/* Call the hooks in the list in priority order until one returns true,
+ * in which case TRUE is returned. */
+
+gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data);
+
+
+/* Call hooks from two lists in priority order. If priority is the same,
+ * hooks from h1 are called first. */
+
+gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
+                               LttvHooks *h2, void *call_data2);
+
+gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1,
+                                     LttvHooks *h2, void *call_data2);
+
+/* Sometimes different hooks need to be called based on the case. The
+   case is represented by an unsigned integer id */
+
+typedef struct _LttvHooksById {
+  GPtrArray *index;
+  GArray *array;
+} LttvHooksById;
+
+/* macro to calculate the hook ID of a facility/event pair. */
+#define GET_HOOK_ID(fac_id, ev_id) \
+  ( (guint)fac_id | ((guint)ev_id << FACILITIES_BITS) )
+
+/* Create and destroy a hooks by id list */
+
+LttvHooksById *lttv_hooks_by_id_new();
+
+void lttv_hooks_by_id_destroy(LttvHooksById *h);
+
+
+/* Obtain the hooks for a given id, creating a list if needed */
+
+LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id);
+
+
+/* Return an id larger than any for which a list exists. */
+
+unsigned lttv_hooks_by_id_max_id(LttvHooksById *h);
+
+
+/* Get the list of hooks for an id, NULL if none exists */
+
+static inline LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id)
+{
+  LttvHooks *ret;
+  if(likely(id < h->index->len)) ret = h->index->pdata[id];
+  else ret = NULL;
+
+  return ret;
+}
+
+
+/* Remove the list of hooks associated with an id */
+
+void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id);
+
+#endif // HOOK_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/iattribute.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/iattribute.c
new file mode 100644 (file)
index 0000000..a447192
--- /dev/null
@@ -0,0 +1,285 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/iattribute.h>
+
+static void
+lttv_iattribute_base_init (gpointer klass)
+{
+  static gboolean initialized = FALSE;
+
+  if (!initialized) {
+    initialized = TRUE;
+  }
+}
+
+
+GType
+lttv_iattribute_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvIAttributeClass),
+      lttv_iattribute_base_init,   /* base_init */
+      NULL,   /* base_finalize */
+      NULL,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      0,
+      0,      /* n_preallocs */
+      NULL    /* instance_init */
+    };
+    type = g_type_register_static (G_TYPE_INTERFACE, "LttvIAttribute", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+unsigned int lttv_iattribute_get_number(LttvIAttribute *self)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->get_number (self);
+}
+
+
+gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->named (self, homogeneous);
+}
+
+
+LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, 
+    LttvAttributeName *name, LttvAttributeValue *v)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->get (self, i, name, v);
+}
+
+LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self,
+    LttvAttributeName name, LttvAttributeValue *v)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->get_by_name (self, name, v);
+}
+
+
+LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, 
+    LttvAttributeName name, LttvAttributeType t)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->add (self, name, t);
+}
+
+
+void lttv_iattribute_remove(LttvIAttribute *self, unsigned i)
+{
+        return LTTV_IATTRIBUTE_GET_CLASS (self)->remove (self, i);
+}
+
+
+void lttv_iattribute_remove_by_name(LttvIAttribute *self,
+    LttvAttributeName name)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->remove_by_name (self, name);
+}
+
+LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, 
+      LttvAttributeName name)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir (self, name);
+}
+
+
+/* Find the named attribute in the table, which must be of the specified type.
+   If it does not exist, it is created with a default value of 0 (NULL for
+   pointer types). Since the address of the value is obtained, it may be
+   changed easily afterwards. The function returns false when the attribute
+   exists but is of incorrect type. */
+
+gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  LttvAttributeType found_type;
+
+  found_type = lttv_iattribute_get_by_name(self, name, v);
+  if(found_type == t) return TRUE;
+
+  if(found_type == LTTV_NONE) {
+    *v = lttv_iattribute_add(self, name, t);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+/* Trees of attribute tables may be accessed using a hierarchical path with
+   components separated by /, like in filesystems */
+
+gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  LttvIAttribute *node = self;
+
+  LttvAttributeType found_type;
+
+  LttvAttributeName name;
+
+  gchar **components, **cursor;
+
+  components = g_strsplit(path, "\"", G_MAXINT);
+
+  if(components == NULL || *components == NULL) {
+    g_strfreev(components);
+    return FALSE; 
+  }
+
+  for(cursor = components;;) {
+    name = g_quark_from_string(*cursor);
+    cursor++;
+
+    if(*cursor == NULL) {
+      g_strfreev(components);
+      return lttv_iattribute_find(node, name, t, v);
+    }
+    else {
+      found_type = lttv_iattribute_get_by_name(node, name, v);
+      if(found_type == LTTV_NONE) {
+        node = lttv_iattribute_find_subdir(node, name);
+      }
+      else if(found_type == LTTV_GOBJECT && 
+             LTTV_IS_IATTRIBUTE(*(v->v_gobject))) {
+        node = LTTV_IATTRIBUTE(*(v->v_gobject));
+      }
+      else {
+        g_strfreev(components);
+        return FALSE;
+      }
+    }
+  }
+}
+
+
+/* Shallow and deep copies */
+
+LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self)
+{
+  LttvIAttribute *copy;
+
+  LttvAttributeType t;
+
+  LttvAttributeValue v, v_copy;
+
+  LttvAttributeName name;
+
+  int i;
+
+  int nb_attributes = lttv_iattribute_get_number(self);
+
+  copy = LTTV_IATTRIBUTE_GET_CLASS(self)->new_attribute(NULL);
+
+  for(i = 0 ; i < nb_attributes ; i++) {
+    t = lttv_iattribute_get(self, i, &name, &v);
+    v_copy = lttv_iattribute_add(copy, name, t);
+    lttv_iattribute_copy_value(t, v_copy, v);
+  }
+  return copy;
+}
+
+LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self)
+{
+  LttvIAttribute *copy, *child;
+
+  LttvAttributeType t;
+
+  LttvAttributeValue v, v_copy;
+
+  LttvAttributeName name;
+
+  int i;
+
+  int nb_attributes = lttv_iattribute_get_number(self);
+
+  copy = LTTV_IATTRIBUTE_GET_CLASS(self)->new_attribute(NULL);
+
+  for(i = 0 ; i < nb_attributes ; i++) {
+    t = lttv_iattribute_get(self, i, &name, &v);
+    v_copy = lttv_iattribute_add(copy, name, t);
+    if(t == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(*(v.v_gobject))) {
+      child = LTTV_IATTRIBUTE(*(v.v_gobject));
+      *(v_copy.v_gobject) = G_OBJECT(lttv_iattribute_deep_copy(child));
+    }
+    else lttv_iattribute_copy_value(t, v_copy, v);
+  }
+  return copy;
+}
+
+void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, 
+    LttvAttributeValue src) 
+{
+  switch(t) {
+    case LTTV_INT:
+      *(dest.v_int) = *(src.v_int); 
+      break;
+
+    case LTTV_UINT:
+      *(dest.v_uint) = *(src.v_uint); 
+      break;
+
+    case LTTV_LONG:
+      *(dest.v_long) = *(src.v_long); 
+      break;
+
+    case LTTV_ULONG:
+      *(dest.v_ulong) = *(src.v_ulong); 
+      break;
+
+    case LTTV_FLOAT:
+      *(dest.v_float) = *(src.v_float); 
+      break;
+
+    case LTTV_DOUBLE: 
+      *(dest.v_double) = *(src.v_double); 
+      break;
+
+    case LTTV_TIME: 
+      *(dest.v_time) = *(src.v_time); 
+      break;
+
+    case LTTV_POINTER:
+      *(dest.v_pointer) = *(src.v_pointer); 
+      break;
+
+    case LTTV_STRING:
+      *(dest.v_string) = *(src.v_string); 
+      break;
+
+    case LTTV_GOBJECT:
+      *(dest.v_gobject) = *(src.v_gobject);
+      if(*(dest.v_gobject) != NULL) g_object_ref(*(dest.v_gobject));
+      break;
+
+    case LTTV_NONE:
+      break;
+  }
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/iattribute.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/iattribute.h
new file mode 100644 (file)
index 0000000..0783077
--- /dev/null
@@ -0,0 +1,183 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* FIXME : unnamed attributes not implemented */
+
+#ifndef IATTRIBUTE_H
+#define IATTRIBUTE_H
+
+
+#include <glib-object.h>
+#include <ltt/time.h>
+
+/* The content of a data structure may be seen as an array of pairs of
+   attribute name and value. This simple model allows generic navigation 
+   and access functions over a wide range of structures. The names are 
+   represented by unique integer identifiers, GQuarks. */
+
+/* Please note that adding a value of type gobject that is non null does not
+ * increment the reference count of this object : the actual reference to
+ * the object is "given" to the attribute tree. When the gobject value
+ * is removed, the object is unreferenced. A value copy through
+ * lttv_iattribute_copy_value does increase the reference count of the 
+ * gobject. */
+
+typedef GQuark LttvAttributeName;
+
+typedef enum _LttvAttributeType {
+  LTTV_INT, LTTV_UINT, LTTV_LONG, LTTV_ULONG, LTTV_FLOAT, LTTV_DOUBLE, 
+  LTTV_TIME, LTTV_POINTER, LTTV_STRING, LTTV_GOBJECT, LTTV_NONE
+} LttvAttributeType;
+
+typedef union LttvAttributeValue {
+  int *v_int;
+  unsigned *v_uint;
+  long *v_long;
+  unsigned long *v_ulong;
+  float *v_float;
+  double *v_double;
+  LttTime *v_time;
+  gpointer *v_pointer;
+  char **v_string;
+  GObject **v_gobject;
+} LttvAttributeValue;
+
+
+/* GObject interface type macros */
+
+#define LTTV_IATTRIBUTE_TYPE       (lttv_iattribute_get_type ())
+#define LTTV_IATTRIBUTE(obj)        (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_IATTRIBUTE_TYPE, LttvIAttribute))
+#define LTTV_IATTRIBUTE_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_IATTRIBUTE_TYPE, LttvIAttributeClass))
+#define LTTV_IS_IATTRIBUTE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_IATTRIBUTE_TYPE))
+#define LTTV_IS_IATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_IATTRIBUTE_TYPE))
+#define LTTV_IATTRIBUTE_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), LTTV_IATTRIBUTE_TYPE, LttvIAttributeClass))
+
+
+typedef struct _LttvIattribute LttvIAttribute; /* dummy object */
+typedef struct _LttvIAttributeClass LttvIAttributeClass;
+
+
+struct _LttvIAttributeClass {
+  GTypeInterface parent;
+
+  LttvIAttribute* (*new_attribute) (LttvIAttribute *self);
+
+  unsigned int (*get_number) (LttvIAttribute *self);
+
+  gboolean (*named) (LttvIAttribute *self, gboolean *homogeneous);
+
+  LttvAttributeType (*get) (LttvIAttribute *self, unsigned i, 
+      LttvAttributeName *name, LttvAttributeValue *v);
+
+  LttvAttributeType (*get_by_name) (LttvIAttribute *self,
+      LttvAttributeName name, LttvAttributeValue *v);
+
+  LttvAttributeValue (*add) (LttvIAttribute *self, LttvAttributeName name, 
+      LttvAttributeType t);
+
+  void (*remove) (LttvIAttribute *self, unsigned i);
+
+  void (*remove_by_name) (LttvIAttribute *self,
+      LttvAttributeName name);
+
+  LttvIAttribute* (*find_subdir) (LttvIAttribute *self, 
+      LttvAttributeName name);
+};
+
+
+GType lttv_iattribute_get_type(void);
+
+
+/* Total number of attributes */
+
+unsigned int lttv_iattribute_get_number(LttvIAttribute *self);
+
+
+/* Container type. Named (fields in struct or elements in a hash table)
+   or unnamed (elements in an array) attributes, homogeneous type or not. */
+
+gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous);
+
+
+/* Get the i th attribute along with its type and a pointer to its value. */
+
+LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, 
+    LttvAttributeName *name, LttvAttributeValue *v);
+
+/* Get the named attribute in the table along with its type and a pointer to
+   its value. If the named attribute does not exist, the type is LTTV_NONE. */
+
+LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self,
+    LttvAttributeName name, LttvAttributeValue *v);
+
+
+/* Add an attribute, which must not exist. The name is an empty string for
+   containers with unnamed attributes. Its value is initialized to 0 or NULL
+   and its pointer returned. */
+
+LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, 
+    LttvAttributeName name, LttvAttributeType t);
+
+/* Remove an attribute */
+
+void lttv_iattribute_remove(LttvIAttribute *self, unsigned i);
+
+void lttv_iattribute_remove_by_name(LttvIAttribute *self,
+    LttvAttributeName name);
+
+
+/* Create an empty iattribute object and add it as an attribute under the
+   specified name, or return an existing iattribute attribute. If an
+   attribute of that name already exists but is not a GObject supporting the
+   iattribute interface, return NULL. */
+
+LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, 
+      LttvAttributeName name);
+
+
+/* The remaining utility functions are not part of the LttvIAttribute
+   interface but operate on objects implementing it. */
+
+/* Find the named attribute in the table, which must be of the specified type.
+   If it does not exist, it is created with a default value of 0 (NULL for
+   pointer types). Since the address of the value is obtained, it may be
+   changed easily afterwards. The function returns false when the attribute
+   exists but is of incorrect type. */
+
+gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v);
+
+
+/* Trees of attribute tables may be accessed using a hierarchical path with
+   components separated by /, like in filesystems */
+
+gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, 
+    LttvAttributeType t, LttvAttributeValue *v);
+
+
+/* Shallow and deep copies */
+
+void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, 
+    LttvAttributeValue src);
+
+LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self);
+
+LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self);
+
+#endif // IATTRIBUTE_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv-gui.sh b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv-gui.sh
new file mode 100644 (file)
index 0000000..0c115bc
--- /dev/null
@@ -0,0 +1,10 @@
+# -* sh *-
+
+# This is a simple script that starts lttv with default GUI modules
+# Mathieu Desnoyers 15-09-2005
+
+LTTV_CMD=`echo $0 | sed 's/-gui$//'`
+
+$LTTV_CMD.real -m guievents -m guifilter -m guicontrolflow -m guistatistics \
+    -m guitracecontrol $*
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv.h
new file mode 100644 (file)
index 0000000..b0dd43b
--- /dev/null
@@ -0,0 +1,63 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef LTTV_H
+#define LTTV_H
+
+#include <lttv/attribute.h>
+
+/* The modules in the visualizer communicate with the main module and
+   with each other through attributes. There is a global set of attributes */
+
+LttvAttribute *lttv_global_attributes();
+
+extern gboolean lttv_profile_memory;
+
+extern int lttv_argc;
+
+extern char **lttv_argv;
+
+/* A number of global attributes are initialized before modules are
+   loaded, for example hooks lists. More global attributes are defined
+   in individual mudules to store information or to communicate with other
+   modules (GUI windows, menus...).
+
+   The hooks lists (lttv_hooks) are initialized in the main module and may be 
+   used by other modules. Each corresponds to a specific location in the main
+   module processing loop. The attribute key and typical usage for each 
+   is indicated.
+
+   /hooks/options/before
+       Good place to define new command line options to be parsed.
+
+   /hooks/options/after
+       Read the values set by the command line options.
+
+   /hooks/main/before
+
+   /hooks/main/after
+
+*/
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+
+#ifndef g_debug
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+#endif
+
+#endif // LTTV_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv.sh b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/lttv.sh
new file mode 100644 (file)
index 0000000..a7d7dc3
--- /dev/null
@@ -0,0 +1,14 @@
+# -* sh *-
+
+# This is a simple script that starts lttv with no modules :
+# For batch mode.
+# Mathieu Desnoyers 15-09-2005
+
+if [ x"$*" = x"" ]; then
+  echo "This is a wrapper around $0.real for convenience purposes"
+  echo "What you really want is maybe the lttv-gui command ?"
+  echo
+  $0.real --help
+else
+  $0.real $*
+fi
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/main.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/main.c
new file mode 100644 (file)
index 0000000..29aa288
--- /dev/null
@@ -0,0 +1,302 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/hook.h>
+#include <lttv/module.h>
+#include <lttv/lttv.h>
+#include <lttv/iattribute.h>
+#include <lttv/attribute.h>
+#include <lttv/option.h>
+#include <lttv/traceset.h>
+#include <ltt/trace.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* The main program maintains a few central data structures and relies
+   on modules for the rest. These data structures may be accessed by modules
+   through an exported API */
+
+static LttvIAttribute *attributes;
+
+static LttvHooks
+  *before_options,
+  *after_options,
+  *before_main,
+  *after_main;
+
+static char 
+  *a_module,
+  *a_module_path;
+
+static gboolean
+  a_verbose,
+  a_debug,
+  a_fatal;
+
+gboolean lttv_profile_memory;
+
+int lttv_argc;
+
+char **lttv_argv;
+
+static void lttv_module_option(void *hook_data);
+
+static void lttv_module_path_option(void *hook_data);
+
+static void lttv_verbose(void *hook_data);
+
+static void lttv_debug(void *hook_data);
+
+static void lttv_fatal(void *hook_data);
+
+static void lttv_help(void *hook_data);
+
+/* This is the handler to specify when we dont need all the debugging 
+   messages. It receives the message and does nothing. */
+
+void ignore_and_drop_message(const gchar *log_domain, GLogLevelFlags log_level,
+    const gchar *message, gpointer user_data) {
+}
+
+
+/* Since everything is done in modules, the main program only takes care
+   of the infrastructure. */
+
+int main(int argc, char **argv) {
+
+  int i;
+
+  char 
+    *profile_memory_short_option = "-M",
+    *profile_memory_long_option = "--memory";
+
+  gboolean profile_memory = FALSE;
+
+  LttvAttributeValue value;
+
+  lttv_argc = argc;
+  lttv_argv = argv;
+
+  /* Before anything else, check if memory profiling is requested */
+
+  for(i = 1 ; i < argc ; i++) {
+    if(*(argv[i]) != '-') break;
+    if(strcmp(argv[i], profile_memory_short_option) == 0 || 
+       strcmp(argv[i], profile_memory_long_option) == 0) {
+      g_mem_set_vtable(glib_mem_profiler_table);
+      g_message("Memory summary before main");
+      g_mem_profile();
+      profile_memory = TRUE;
+      break;
+    }
+  }
+
+
+  /* Initialize glib and by default ignore info and debug messages */
+
+  g_type_init();
+  //g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS);
+  g_log_set_handler(NULL, G_LOG_LEVEL_INFO, ignore_and_drop_message, NULL);
+  g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, ignore_and_drop_message, NULL);
+
+
+  /* Have an attributes subtree to store hooks to be registered by modules. */
+
+  attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
+
+  before_options = lttv_hooks_new();
+  after_options = lttv_hooks_new();
+  before_main = lttv_hooks_new();
+  after_main = lttv_hooks_new();
+
+
+  /* Create a number of hooks lists */
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/options/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_options;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/options/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_options;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_main;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_main;
+
+
+  /* Initialize the command line options processing */
+
+  GError *error = NULL;
+
+  LttvModule *module_module = lttv_module_require("module", &error);
+  if(error != NULL) g_error("%s", error->message);
+  LttvModule *module_option = lttv_module_require("option", &error);
+  if(error != NULL) g_error("%s", error->message);
+
+  /* Initialize the module loading */
+
+  lttv_library_path_add(PACKAGE_PLUGIN_DIR);
+
+
+  /* Add some built-in options */
+
+  lttv_option_add("module",'m', "load a module", "name of module to load", 
+      LTTV_OPT_STRING, &a_module, lttv_module_option, NULL);
+  lttv_option_add("modules-path", 'L', 
+      "add a directory to the module search path", 
+      "directory to add to the path", LTTV_OPT_STRING, &a_module_path, 
+      lttv_module_path_option, NULL);
+       
+  lttv_option_add("help",'h', "basic help", "none", 
+      LTTV_OPT_NONE, NULL, lttv_help, NULL);
+
+  a_verbose = FALSE; 
+  lttv_option_add("verbose",'v', "print information messages", "none", 
+      LTTV_OPT_NONE, NULL, lttv_verbose, NULL);
+  a_debug = FALSE;
+  lttv_option_add("debug",'d', "print debugging messages", "none", 
+      LTTV_OPT_NONE, NULL, lttv_debug, NULL);
+
+  a_fatal = FALSE;
+  lttv_option_add("fatal",'f', "make critical messages fatal",
+                  "none", 
+      LTTV_OPT_NONE, NULL, lttv_fatal, NULL);
+  lttv_profile_memory = FALSE;
+  lttv_option_add(profile_memory_long_option + 2, 
+      profile_memory_short_option[1], "print memory information", "none", 
+      LTTV_OPT_NONE, &lttv_profile_memory, NULL, NULL);
+
+
+  /* Process the options */
+  lttv_hooks_call(before_options, NULL);
+  lttv_option_parse(argc, argv);
+  lttv_hooks_call(after_options, NULL);
+
+
+  /* Memory profiling to be useful must be activated as early as possible */
+
+  if(profile_memory != lttv_profile_memory) 
+    g_error("Memory profiling options must appear before other options");
+
+
+  /* Do the main work */
+
+  lttv_hooks_call(before_main, NULL);
+  lttv_hooks_call(after_main, NULL);
+
+
+  /* Clean up everything */
+
+  lttv_module_release(module_option);
+  lttv_module_release(module_module);
+
+  lttv_hooks_destroy(before_options);
+  lttv_hooks_destroy(after_options);
+  lttv_hooks_destroy(before_main);
+  lttv_hooks_destroy(after_main);
+  g_object_unref(attributes);
+
+  if(profile_memory) {
+    g_message("Memory summary after main");
+    g_mem_profile();
+  }
+  return 0;
+}
+
+
+LttvAttribute *lttv_global_attributes()
+{
+  return (LttvAttribute*)attributes;
+}
+
+
+void lttv_module_option(void *hook_data)
+{ 
+  GError *error = NULL;
+
+  lttv_module_require(a_module, &error);
+  if(error != NULL) g_error("%s", error->message);
+}
+
+
+void lttv_module_path_option(void *hook_data)
+{
+  lttv_library_path_add(a_module_path);
+}
+
+
+void lttv_verbose(void *hook_data)
+{
+  g_log_set_handler(NULL, G_LOG_LEVEL_INFO, g_log_default_handler, NULL);
+  g_info("Logging set to include INFO level messages");
+}
+
+void lttv_debug(void *hook_data)
+{
+  g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, g_log_default_handler, NULL);
+  g_info("Logging set to include DEBUG level messages");
+}
+
+void lttv_fatal(void *hook_data)
+{
+  g_log_set_always_fatal(G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
+  //g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
+  g_info("Critical log from glib will abort execution");
+}
+
+void lttv_help(void *hook_data)
+{
+       printf("Linux Trace Toolkit Visualizer\n");
+       printf("\n");
+       lttv_option_show_help();
+       printf("\n");
+}
+
+/* 
+
+- Define formally traceset/trace in the GUI for the user and decide how
+   trace/traceset sharing goes in the application.
+
+- Use appropriately the new functions in time.h
+
+- remove the separate tracefiles (control/per cpu) arrays/loops in context.
+
+- split processTrace into context.c and processTrace.c
+
+- check spelling conventions.
+
+- get all the copyright notices.
+
+- remove all the warnings.
+
+- get all the .h files properly doxygen commented to produce useful documents.
+
+- have an intro/architecture document.
+
+- write a tutorial */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/module.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/module.c
new file mode 100644 (file)
index 0000000..aab28bc
--- /dev/null
@@ -0,0 +1,608 @@
+
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+/* module.c : Implementation of the module loading/unloading mechanism. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/module.h>
+#include <gmodule.h>
+
+
+struct _LttvLibrary
+{
+  LttvLibraryInfo info;
+  GPtrArray *modules;
+  GModule *gm;
+  guint locked_loaded;
+};
+
+
+struct _LttvModule
+{
+  LttvModuleInfo info;
+  char **prerequisites_names;
+  GPtrArray *prerequisites;
+};
+
+
+/* Modules are searched by name. However, a library may be loaded which
+   provides a module with the same name as an existing one. A stack of
+   modules is thus maintained for each name. 
+
+   Libraries correspond to glib modules. The g_module function is 
+   responsible for loading each library only once. */
+
+static GHashTable *modules_by_name = NULL;
+
+static GPtrArray *libraries = NULL;
+
+static GHashTable *libraries_by_g_module = NULL;
+
+static GPtrArray *library_paths = NULL;
+
+static gboolean initialized = FALSE;
+
+static gboolean destroyed = TRUE;
+
+static struct _LttvModuleDescription *builtin_chain = NULL;
+
+static struct _LttvModuleDescription *module_chain = NULL;
+
+static struct _LttvModuleDescription **module_next = &module_chain;
+
+static GQuark lttv_module_error;
+
+static void init();
+
+static void finish_destroy();
+
+static void module_release(LttvModule *m);
+
+
+static LttvLibrary *library_add(char *name, char *path, GModule *gm)
+{
+  LttvLibrary *l;
+
+  LttvModule *m;
+
+  struct _LttvModuleDescription *link;
+
+  GPtrArray *modules;
+
+  l = g_new(LttvLibrary, 1);
+  l->modules = g_ptr_array_new();
+  l->gm = gm;
+  l->locked_loaded = 0;
+  l->info.name = g_strdup(name);
+  l->info.path = g_strdup(path);
+  l->info.load_count = 0;
+
+  g_ptr_array_add(libraries, l);
+  g_hash_table_insert(libraries_by_g_module, gm, l);
+
+  *module_next = NULL;
+  for(link = module_chain; link != NULL; link = link->next) {
+    m = g_new(LttvModule, 1);
+    g_ptr_array_add(l->modules, m);
+
+    modules = g_hash_table_lookup(modules_by_name, link->name);
+    if(modules == NULL) {
+      modules = g_ptr_array_new();
+      g_hash_table_insert(modules_by_name, g_strdup(link->name), modules);
+    }
+    g_ptr_array_add(modules, m);
+
+    m->prerequisites_names = link->prerequisites;
+    m->prerequisites = g_ptr_array_new();
+    m->info.name = link->name;
+    m->info.short_description = link->short_description;
+    m->info.description = link->description;
+    m->info.init = link->init;
+    m->info.destroy = link->destroy;
+    m->info.library = l;
+    m->info.require_count = 0;
+    m->info.use_count = 0;
+    m->info.prerequisites_number = link->prerequisites_number;
+  }
+  return l;
+}
+
+
+static void library_remove(LttvLibrary *l)
+{
+  LttvModule *m;
+
+  GPtrArray *modules;
+  GPtrArray **modules_ptr = &modules; /* for strict aliasing */
+  guint i;
+
+  char *key;
+  char **key_ptr = &key; /* for strict aliasing */
+
+  for(i = 0 ; i < l->modules->len ; i++) {
+    m = (LttvModule *)(l->modules->pdata[i]);
+
+    g_hash_table_lookup_extended(modules_by_name, m->info.name, 
+                                (gpointer *)key_ptr, (gpointer *)modules_ptr);
+    g_assert(modules != NULL);
+    g_ptr_array_remove(modules, m);
+    if(modules->len == 0) {
+      g_hash_table_remove(modules_by_name, m->info.name);
+      g_ptr_array_free(modules, TRUE);
+      g_free(key);
+    }
+
+    g_ptr_array_free(m->prerequisites, TRUE);
+    g_free(m);
+  }
+
+  g_ptr_array_remove(libraries, l);
+  g_hash_table_remove(libraries_by_g_module, l->gm);
+  g_ptr_array_free(l->modules, TRUE);
+  g_free(l->info.name);
+  g_free(l->info.path);
+  g_free(l);
+}
+
+
+static LttvLibrary *library_load(char *name, GError **error)
+{
+  GModule *gm = NULL;
+
+  int i, nb;
+
+  /* path is always initialized, checked */
+  char *path = NULL, *pathname;
+
+  LttvLibrary *l;
+
+  GString *messages = g_string_new("");
+
+  /* insure that module.c is initialized */
+
+  init();
+
+  /* Try to find the library along all the user specified paths */
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Load library %s", name);
+  nb = lttv_library_path_number();
+  for(i = 0 ; i <= nb ; i++) {
+    if(i < nb) path = lttv_library_path_get(i);
+    else path = NULL;
+
+    pathname = g_module_build_path(path ,name);
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Try path %s", pathname);
+    module_chain = NULL;
+    module_next = &module_chain;
+    gm = g_module_open(pathname,0);
+    g_free(pathname);
+    
+    if(gm != NULL) break;
+
+    g_string_append(messages, g_module_error());
+    g_string_append(messages, "\n");
+    g_log(G_LOG_DOMAIN,G_LOG_LEVEL_INFO,"Trial failed, %s", g_module_error());
+  }
+
+  /* Module cannot be found */
+
+  if(gm == NULL) {
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Failed to load %s", name); 
+    g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND,
+          "Cannot load library %s: %s", name, messages->str);
+    g_string_free(messages, TRUE);
+    return NULL;
+  }
+  g_string_free(messages, TRUE);
+
+  /* Check if the library was already loaded */
+
+  l = g_hash_table_lookup(libraries_by_g_module, gm);
+
+  /* This library was not already loaded */
+
+  if(l == NULL) {
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Library %s (%s) loaded", name, 
+        g_module_name(gm));
+    l = library_add(name, path, gm);
+  }
+  return l;
+}
+
+
+LttvLibrary *lttv_library_load(char *name, GError **error)
+{
+  LttvLibrary *l = library_load(name, error);
+  if(l != NULL) l->info.load_count++;
+  return l;
+}
+
+/* Returns < 0 if still in use, 0 if freed */
+static gint library_unload(LttvLibrary *l)
+{
+  guint i;
+
+  GModule *gm;
+
+  LttvModule *m;
+
+  if(l->locked_loaded > 0) {
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: locked loaded", 
+        l->info.name);
+    return 1;
+  }
+
+  if(l->info.load_count > 0) {
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: load count %d", 
+       l->info.name, l->info.load_count);
+    return l->info.load_count;
+  }
+
+  /* Check if all its modules have been released */
+
+  for(i = 0 ; i < l->modules->len ; i++) {
+    m = (LttvModule *)(l->modules->pdata[i]);
+    if(m->info.use_count > 0) {
+      g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO,"Unload library %s: module %s used",
+          l->info.name, m->info.name);
+      return 1;
+    }
+  }
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: close the GModule",
+       l->info.name);
+  gm = l->gm;
+  library_remove(l);
+  if(gm != NULL) g_module_close(gm);
+
+  /* insure that module.c will be finalized */
+
+  finish_destroy();
+  return 0;
+}
+
+
+gint lttv_library_unload(LttvLibrary *l)
+{
+  /* In the case where we wait for a module to release, the load count is 0
+   * and should not be decremented. */
+  if(l->info.load_count != 0) {
+    l->info.load_count--;
+    return l->info.load_count;
+  } else {
+    library_unload(l);
+    return 0;
+  }
+}
+
+
+static void library_lock_loaded(LttvLibrary *l)
+{
+  l->locked_loaded++;
+}
+
+
+static gint library_unlock_loaded(LttvLibrary *l)
+{
+  l->locked_loaded--;
+  return library_unload(l);
+}
+
+
+static LttvModule *module_require(char *name, GError **error)
+{
+  GError *tmp_error = NULL;
+
+  guint i, j;
+
+  LttvModule *m, *required;
+
+  LttvLibrary *l = NULL;
+
+  GPtrArray *modules;
+
+  /* Insure that module.c is initialized */
+
+  init();
+
+  /* Check if the module is already loaded */
+
+  modules = g_hash_table_lookup(modules_by_name, name);
+
+  /* Try to load a library having the module name */
+
+  if(modules == NULL) {
+    l = library_load(name, error);
+    if(l == NULL) return NULL;
+    else library_lock_loaded(l);
+
+    /* A library was found, does it contain the named module */
+
+    modules = g_hash_table_lookup(modules_by_name, name);
+    if(modules == NULL) {
+      g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND,
+          "Module %s not found in library %s", name, l->info.name);
+      library_unlock_loaded(l);
+      return NULL;
+    }
+  }
+  m = (LttvModule *)(modules->pdata[modules->len - 1]);
+
+  /* We have the module */
+
+  m->info.use_count++;
+
+  /* First use of the module. Initialize after getting the prerequisites */
+
+  if(m->info.use_count == 1) {
+    for(i = 0 ; i < m->info.prerequisites_number ; i++) {
+      required = module_require(m->prerequisites_names[i], &tmp_error);
+
+      /* A prerequisite could not be found, undo everything and fail */
+
+      if(required == NULL) {
+        for(j = 0 ; j < m->prerequisites->len ; j++) {
+          module_release((LttvModule *)(m->prerequisites->pdata[j]));
+        }
+        g_ptr_array_set_size(m->prerequisites, 0);
+        if(l != NULL) library_unlock_loaded(l);
+        g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND,
+            "Cannot find prerequisite for module %s: %s", name, 
+           tmp_error->message);
+        g_clear_error(&tmp_error);
+        return NULL;
+      }
+      g_ptr_array_add(m->prerequisites, required);
+    }
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Module %s: init()", m->info.name);
+    m->info.init();
+  }
+
+  /* Decrement the load count of the library. It will not really be 
+     unloaded since it contains a currently used module. */
+
+  if(l != NULL) library_unlock_loaded(l);
+
+  return(m);
+}
+
+
+/* The require_count for a module is the number of explicit calls to 
+   lttv_module_require, while the use_count also counts the number of times
+   a module is needed as a prerequisite. */
+
+LttvModule *lttv_module_require(char *name, GError **error)
+{
+  LttvModule *m = module_require(name, error);
+  if(m != NULL) m->info.require_count++;
+  return(m);
+}
+
+
+static void module_release(LttvModule *m)
+{
+  guint i;
+
+  library_lock_loaded(m->info.library);
+
+  m->info.use_count--;
+  if(m->info.use_count == 0) {
+    g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Module %s: destroy()",m->info.name);
+    m->info.destroy();
+    for(i = 0 ; i < m->prerequisites->len ; i++) {
+      module_release((LttvModule *)(m->prerequisites->pdata[i]));
+    }
+    g_ptr_array_set_size(m->prerequisites, 0);
+  }
+  library_unlock_loaded(m->info.library);
+}
+
+
+void lttv_module_release(LttvModule *m)
+{
+  m->info.require_count--;
+  module_release(m);
+}
+
+
+void lttv_module_info(LttvModule *m, LttvModuleInfo *info)
+{
+  *info = m->info;
+}
+
+
+unsigned lttv_module_prerequisite_number(LttvModule *m)
+{
+  return m->prerequisites->len;
+}
+
+
+LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i)
+{
+  return (LttvModule *)(m->prerequisites->pdata[i]);
+}
+
+
+void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info)
+{
+  *info = l->info;
+}
+
+
+unsigned lttv_library_module_number(LttvLibrary *l)
+{
+  return l->modules->len;
+}
+
+
+LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i)
+{
+  return (LttvModule *)(l->modules->pdata[i]);
+}
+
+
+unsigned lttv_library_number()
+{
+  return libraries->len;  
+}
+
+
+LttvLibrary *lttv_library_get(unsigned i)
+{
+  return (LttvLibrary *)(libraries->pdata[i]);
+}
+
+
+void lttv_library_path_add(const char *name)
+{
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add library path %s", name);
+  g_ptr_array_add(library_paths,(char*)g_strdup(name));
+}
+
+
+void lttv_library_path_remove(const char *name) 
+{
+  guint i;
+
+  for(i = 0 ; i < library_paths->len ; i++) {
+    if(g_str_equal(name, library_paths->pdata[i])) {
+      g_free(library_paths->pdata[i]);
+      g_ptr_array_remove_index(library_paths,i);
+      return;
+    }
+  }
+}
+
+
+unsigned lttv_library_path_number()
+{
+  return library_paths->len;
+}
+
+
+char *lttv_library_path_get(unsigned i)
+{
+  return (char *)(library_paths->pdata[library_paths->len - i - 1]);
+}
+
+
+void lttv_module_register(struct _LttvModuleDescription *d)
+{
+  *module_next = d;
+  module_next = &(d->next);
+}
+
+
+static void init() 
+{
+  if(initialized) return;
+  g_assert(destroyed);
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init module.c");
+
+  initialized = TRUE;
+  destroyed = FALSE;
+  lttv_module_error = g_quark_from_string("LTTV_MODULE_ERROR");
+  modules_by_name = g_hash_table_new(g_str_hash, g_str_equal);
+  libraries = g_ptr_array_new();
+  libraries_by_g_module = g_hash_table_new(g_direct_hash, g_direct_equal);
+  library_paths = g_ptr_array_new();
+
+  if(builtin_chain == NULL) builtin_chain = module_chain;
+  module_chain = builtin_chain;
+  library_add("builtin", NULL, NULL);
+}
+
+
+static void finish_destroy()
+{
+  guint i;
+
+  if(initialized) return;
+  g_assert(!destroyed);
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Finish destroy module.c");
+  g_hash_table_destroy(modules_by_name);
+  g_ptr_array_free(libraries, TRUE);
+  g_hash_table_destroy(libraries_by_g_module);
+  for(i = 0 ; i < library_paths->len ; i++) {
+    g_free(library_paths->pdata[i]);
+  }
+  g_ptr_array_free(library_paths, TRUE);
+  destroyed = TRUE;
+}
+
+
+static void destroy() 
+{  
+  guint i, j, nb;
+
+  LttvLibrary *l, **locked_libraries;
+
+  LttvModule *m;
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy module.c");
+
+  /* Unload all libraries */
+
+  nb = libraries->len;
+  locked_libraries = g_new(LttvLibrary *, nb);
+
+  for(i = 0 ; i < nb ; i++) {
+    //g_assert(nb == libraries->len);
+    l = (LttvLibrary *)(libraries->pdata[i]);
+    locked_libraries[i] = l;
+    library_lock_loaded(l);
+    for(j = 0 ; j < l->modules->len ; j++) {
+      m = (LttvModule *)(l->modules->pdata[j]);
+      while(m->info.require_count > 0) lttv_module_release(m);
+    }
+    if(library_unlock_loaded(l) > 0)
+      while(lttv_library_unload(l) > 0);
+
+    /* If the number of librairies loaded have changed, restart from the
+     * beginning */
+    if(nb != libraries->len) {
+      i = 0;
+      nb = libraries->len;
+    }
+
+  }
+
+  for(i = 0 ; i < nb ; i++) {
+    l = locked_libraries[i];
+    library_unlock_loaded(l);
+  }
+  g_free(locked_libraries);
+
+  /* The library containing module.c may be locked by our caller */
+
+  g_assert(libraries->len <= 1); 
+
+  initialized = FALSE;
+}
+
+LTTV_MODULE("module", "Modules in libraries",                        \
+    "Load libraries, list, require and initialize contained modules", \
+    init, destroy)
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/module.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/module.h
new file mode 100644 (file)
index 0000000..6793140
--- /dev/null
@@ -0,0 +1,208 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef MODULES_H
+#define MODULES_H
+
+#include <glib.h>
+
+/* A module contains some functionality which becomes available atfer it is
+   initialized and before it is destroyed. A module is characterized by a name,
+   a description (short and long), a list of names of other modules on which 
+   it depends, and an initialization and a destruction function.
+
+   A library contains one or more modules and may be loaded dynamically.
+   The modules contained in a library are automatically registered through
+   constructors which are called when the library is loaded. For modules
+   directly linked with the main program (builtin), the constructors are
+   called before the main program starts. (However, neither malloc nor glib 
+   functions are used during the registration process).
+
+   The library loading path is a set of directories, where requested
+   libraries and modules are searched for.
+*/
+
+typedef struct _LttvModule LttvModule;
+
+typedef struct _LttvLibrary LttvLibrary;
+
+typedef void (*LttvModuleInit)();
+
+typedef void (*LttvModuleDestroy)();
+
+typedef struct _LttvModuleInfo
+{
+  char *name;
+  char *short_description;
+  char *description;
+  LttvModuleInit init;
+  LttvModuleDestroy destroy;
+  LttvLibrary *library;
+  unsigned require_count;
+  unsigned use_count;
+  unsigned prerequisites_number;
+} LttvModuleInfo;
+
+
+typedef struct _LttvLibraryInfo
+{
+  char *name;
+  char *path;
+  unsigned load_count;
+} LttvLibraryInfo;
+
+
+typedef enum _LttvModuleError 
+{
+  LTTV_MODULE_NOT_FOUND,
+  LTTV_MODULE_NO_INIT
+} LttvModuleError;
+
+
+/* Insure that a module is loaded and initialized. Require count 
+   (number of times the module was required) and use count 
+   (number of times required or used as prerequisite) serve to 
+   insure that a module is destroyed only after it has been released 
+   as many times as it was required (and prerequired).
+
+   The module is searched among the modules currently loaded, then as a 
+   similarly named library to load which should contain the named module.
+   If the module cannot be found or loaded, NULL is returned and an
+   explanation is provided in error. */
+
+LttvModule *lttv_module_require(char *name, GError **error);
+
+void lttv_module_release(LttvModule *m);
+
+
+/* Obtain information about the module, including the containing library */
+
+void lttv_module_info(LttvModule *m, LttvModuleInfo *info);
+
+
+/* List the modules on which this module depends */
+
+unsigned lttv_module_prerequisite_number(LttvModule *m);
+
+LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i);
+
+
+/* Insure that a library is loaded. A load count insures that a library 
+   is unloaded only after it has been asked to unload as
+   many times as it was loaded, and its modules are not in use. The library
+   is searched along the library path if name is a relative pathname. 
+   If the library cannot be found or loaded, NULL is returned and an 
+   explanation is provided in error. */
+
+LttvLibrary *lttv_library_load(char *name, GError **error);
+
+/* Returns 0 if library is unloaded, > 0 otherwise */
+gint lttv_library_unload(LttvLibrary *l);
+
+
+/* Obtain information about the library */
+
+void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info);
+
+
+/* List the modules contained in a library */
+
+unsigned lttv_library_module_number(LttvLibrary *l);
+
+LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i);
+
+
+/* List the currently loaded libraries */
+
+unsigned lttv_library_number();
+
+LttvLibrary *lttv_library_get(unsigned i);
+
+
+
+/* Add or remove directory names to the library search path */
+
+void lttv_library_path_add(const char *name);
+
+void lttv_library_path_remove(const char *name);
+
+
+/* List the directory names in the library search path */
+
+unsigned lttv_library_path_number();
+
+char *lttv_library_path_get(unsigned i);
+
+
+/* To define a module, simply call the LTTV_MODULE macro with the needed
+   arguments: single word name, one line short description, larger
+   description, initialization function, destruction function, and
+   list of names for required modules (e.g., "moduleA", "moduleB").
+   This will insure that the module is registered at library load time.
+
+   Example:
+
+   LTTV_MODULE("option", "Command line options processing", "...", \
+       init, destroy, "moduleA", "moduleB") 
+*/
+
+#define LTTV_MODULE(name, short_desc, desc, init, destroy, ...) \
+  \
+  static void _LTTV_MODULE_REGISTER(__LINE__)() \
+      __attribute__((constructor));             \
+  \
+  static void _LTTV_MODULE_REGISTER(__LINE__)() \
+  { \
+    static char *module_prerequisites[] = { __VA_ARGS__ };     \
+    \
+    static struct _LttvModuleDescription module = { \
+        name, short_desc, desc, init, destroy, \
+        sizeof(module_prerequisites) / sizeof(char *), \
+        module_prerequisites, NULL}; \
+        \
+    lttv_module_register(&module); \
+  }
+
+
+/* Internal structure and function used to register modules, called by 
+   LTTV_MODULE */
+
+#define __LTTV_MODULE_REGISTER(line) _lttv_module_register_ ## line
+#define _LTTV_MODULE_REGISTER(line) __LTTV_MODULE_REGISTER(line)
+
+struct _LttvModuleDescription
+{
+  char *name;
+  char *short_description;
+  char *description;
+  LttvModuleInit init;
+  LttvModuleDestroy destroy;
+  unsigned prerequisites_number;
+  char **prerequisites;
+  struct _LttvModuleDescription *next;
+};
+
+void lttv_module_register(struct _LttvModuleDescription *d);
+
+#endif // MODULES_H
+
+
+
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/option.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/option.c
new file mode 100644 (file)
index 0000000..f0d4425
--- /dev/null
@@ -0,0 +1,317 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <popt.h>
+#include <glib.h>
+#include <lttv/module.h>
+#include <lttv/option.h>
+
+typedef struct _LttvOption {
+  char *long_name;
+  char char_name;
+  char *description;
+  char *arg_description;
+  LttvOptionType t;
+  gpointer p;
+  LttvOptionHook hook;
+  gpointer hook_data;
+
+  /* Keep the order of addition */
+  guint val;
+} LttvOption;
+
+GHashTable *options;
+
+
+static void
+list_options(gpointer key, gpointer value, gpointer user_data)
+{
+  GPtrArray *list = (GPtrArray *)user_data;
+  LttvOption *option = (LttvOption *)value;
+
+  if(list->len < option->val)
+    g_ptr_array_set_size(list, option->val);
+  list->pdata[option->val-1] = option;
+}
+
+
+static void
+free_option(LttvOption *option)
+{
+  g_free(option->long_name);
+  g_free(option->description);
+  g_free(option->arg_description);
+  g_free(option);
+}
+
+
+void lttv_option_add(const char *long_name, const char char_name,
+    const char *description, const char *arg_description,
+    const LttvOptionType t, void *p,
+    const LttvOptionHook h, void *hook_data)
+{
+  LttvOption *option;
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add option %s", long_name);
+  if(g_hash_table_lookup(options, long_name) != NULL) {
+    g_warning("duplicate option");
+    return;
+  }
+
+  option = g_new(LttvOption, 1);
+  option->long_name = g_strdup(long_name);
+  option->char_name = char_name;
+  option->description = g_strdup(description);
+  option->arg_description = g_strdup(arg_description);
+  option->t = t;
+  option->p = p;
+  option->hook = h;
+  option->hook_data = hook_data;
+  option->val = g_hash_table_size(options) + 1;
+  g_hash_table_insert(options, option->long_name, option);
+}
+
+
+void 
+lttv_option_remove(const char *long_name) 
+{
+  LttvOption *option = g_hash_table_lookup(options, long_name);
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Remove option %s", long_name);
+  if(option == NULL) {
+    g_warning("trying to remove unknown option %s", long_name);
+    return;
+  }
+  g_hash_table_remove(options, long_name);
+  free_option(option);
+}
+
+
+static int poptToLTT[] = { 
+  POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG
+};
+
+static struct poptOption endOption = { NULL, '\0', 0, NULL, 0, NULL, NULL };
+
+
+static void 
+build_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc,
+    int argc, char **argv)
+{
+  LttvOption *option;
+
+  GPtrArray *list;
+
+  struct poptOption *popts;
+
+  poptContext c;
+
+  guint i;
+
+  list = g_ptr_array_sized_new(g_hash_table_size(options));
+
+  g_hash_table_foreach(options, list_options, list);
+
+  /* Build a popt options array from our list */
+
+  popts = g_new(struct poptOption, list->len + 1);
+
+  /* add the options in the reverse order, so last additions are parsed first */
+  for(i = 0 ; i < list->len ; i++) {
+    guint reverse_i = list->len-1-i;
+    option = (LttvOption *)list->pdata[i];
+    popts[reverse_i].longName = option->long_name;
+    popts[reverse_i].shortName = option->char_name;
+    popts[reverse_i].descrip = option->description;
+    popts[reverse_i].argDescrip = option->arg_description;
+    popts[reverse_i].argInfo = poptToLTT[option->t];
+    popts[reverse_i].arg = option->p;
+    popts[reverse_i].val = option->val;
+  }
+
+  /* Terminate the array for popt and create the context */
+
+  popts[list->len] = endOption;
+  c = poptGetContext(argv[0], argc, (const char**)argv, popts, 0);
+
+  *plist = list;
+  *ppopts = popts;
+  *pc = c;
+}
+
+
+static void 
+destroy_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc)
+{
+  g_ptr_array_free(*plist, TRUE); *plist = NULL;
+  g_free(*ppopts); *ppopts = NULL;
+  poptFreeContext(*pc);  
+}
+
+
+void lttv_option_parse(int argc, char **argv)
+{
+  GPtrArray *list;
+
+  LttvOption *option;
+
+  int i, rc, first_arg;
+
+  struct poptOption *popts;
+
+  poptContext c;
+
+  i = 0;
+
+  first_arg = 0;
+
+  guint hash_size = 0;
+
+  build_popts(&list, &popts, &c, argc, argv);
+
+  /* Parse options while not end of options event */
+
+  while((rc = poptGetNextOpt(c)) != -1) {
+
+    /* The option was recognized and the rc value returned is the argument
+       position in the array. Call the associated hook if present. */
+  
+    if(rc > 0) {
+      option = (LttvOption *)(list->pdata[rc - 1]);
+      g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Option %s encountered", 
+          option->long_name);
+      hash_size = g_hash_table_size(options);
+      if(option->hook != NULL) { 
+        g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s hook called", 
+            option->long_name);
+        option->hook(option->hook_data);
+      }
+      i++;
+
+      /* If the size of the option hash changed, add new options
+       * right now. It resolves the conflict of multiple same short
+       * option use.
+       */
+      if(hash_size != g_hash_table_size(options)) {
+        destroy_popts(&list, &popts, &c);
+        build_popts(&list, &popts, &c, argc, argv);
+
+        /* Get back to the same argument */
+
+        first_arg = i;
+        for(i = 0; i < first_arg; i++) {
+          rc = poptGetNextOpt(c);
+          option = (LttvOption *)(list->pdata[rc - 1]);
+          g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped",
+              option->long_name);
+        }
+      }
+    } 
+
+    else if(rc == POPT_ERROR_BADOPT && i != first_arg) {
+      g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, 
+          "Option %s not recognized, rescan options with new additions",
+         poptBadOption(c,0));
+
+      /* Perhaps this option is newly added, restart parsing */
+
+      destroy_popts(&list, &popts, &c);
+      build_popts(&list, &popts, &c, argc, argv);
+
+      /* Get back to the same argument */
+
+      first_arg = i;
+      for(i = 0; i < first_arg; i++) {
+        rc = poptGetNextOpt(c);
+        option = (LttvOption *)(list->pdata[rc - 1]);
+        g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped",
+            option->long_name);
+      }
+    }
+
+    else {
+
+      /* The option has some error and it is not because this is a newly
+         added option not recognized. */
+
+      g_error("option %s: %s", poptBadOption(c,0), poptStrerror(rc));
+      break;
+    }
+    
+  }
+
+  destroy_popts(&list, &popts, &c);
+}
+
+/* CHECK */
+static void show_help(LttvOption *option)
+{
+  printf("--%s  -%c  argument: %s\n" , option->long_name,
+                                                                                                                                                       option->char_name,
+                                                                                                                                                       option->arg_description);
+  printf("                     %s\n" , option->description);
+
+}
+
+void lttv_option_show_help(void)
+{
+  GPtrArray *list = g_ptr_array_new();
+
+  guint i;
+
+  g_hash_table_foreach(options, list_options, list);
+
+       printf("Built-in commands available:\n");
+       printf("\n");
+
+  for(i = 0 ; i < list->len ; i++) {
+    show_help((LttvOption *)list->pdata[i]);
+  }
+  g_ptr_array_free(list, TRUE);
+}
+
+static void init()
+{
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init option.c");
+  options = g_hash_table_new(g_str_hash, g_str_equal);
+}
+
+
+static void destroy()
+{
+  GPtrArray *list = g_ptr_array_new();
+
+  guint i;
+
+  g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy option.c");
+  g_hash_table_foreach(options, list_options, list);
+  g_hash_table_destroy(options);
+
+  for(i = 0 ; i < list->len ; i++) {
+    free_option((LttvOption *)list->pdata[i]);
+  }
+  g_ptr_array_free(list, TRUE);
+}
+
+LTTV_MODULE("option", "Command line options processing", \
+    "Functions to add, remove and parse command line options", \
+    init, destroy)
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/option.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/option.h
new file mode 100644 (file)
index 0000000..fc8f14d
--- /dev/null
@@ -0,0 +1,53 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef OPTION_H
+#define OPTION_H
+
+/* Define a new option with a long name (--long_name), a short
+   one character name (-c), a descriptive text, the argument type, and a
+   pointer to where the argument value will be stored. For an option of
+   type LTTV_OPT_NONE, the argument is a boolean value set to true when the
+   option is present. The option hook is called if non NULL. */
+
+typedef enum _LttvOptionType
+{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG } 
+LttvOptionType;
+
+typedef void (*LttvOptionHook)(void *hook_data);
+
+void lttv_option_add(const char *long_name, const char char_name,
+               const char *description, const char *arg_description,
+               const LttvOptionType t, void *p,
+               const LttvOptionHook h, void *hook_data);
+
+
+/* Remove an option */
+
+void lttv_option_remove(const char *long_name);
+
+
+/* Parse command line options. It is possible to add options (through the
+   hooks being called) while the parsing is done. The new options will be
+   used for subsequent command line arguments. */
+
+void lttv_option_parse(int argc, char **argv);
+
+void lttv_option_show_help(void);
+
+#endif // OPTION_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/print.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/print.c
new file mode 100644 (file)
index 0000000..89dad9a
--- /dev/null
@@ -0,0 +1,185 @@
+
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *               2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* print.c
+ *
+ * Event printing routines.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttv/option.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/attribute.h>
+#include <lttv/iattribute.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+#include <lttv/print.h>
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <stdio.h>
+
+
+void lttv_print_field(LttEvent *e, LttField *f, GString *s,
+                      gboolean field_names) {
+
+  LttType *type;
+
+  LttField *element;
+
+  GQuark name;
+
+  int nb, i;
+
+  type = ltt_field_type(f);
+  switch(ltt_type_class(type)) {
+    case LTT_INT:
+    case LTT_LONG:
+    case LTT_SSIZE_T:
+      g_string_append_printf(s, " %lld", ltt_event_get_long_int(e,f));
+      break;
+
+    case LTT_UINT:
+    case LTT_ULONG:
+    case LTT_SIZE_T:
+    case LTT_OFF_T:
+      g_string_append_printf(s, " %llu", ltt_event_get_long_unsigned(e,f));
+      break;
+
+    case LTT_FLOAT:
+      g_string_append_printf(s, " %g", ltt_event_get_double(e,f));
+      break;
+
+    case LTT_POINTER:
+      g_string_append_printf(s, " 0x%llx", ltt_event_get_long_unsigned(e,f));
+      break;
+
+    case LTT_STRING:
+      g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f));
+      break;
+
+    case LTT_ENUM:
+      g_string_append_printf(s, " %s", 
+          g_quark_to_string(ltt_enum_string_get(type,
+          ltt_event_get_unsigned(e,f)-1)));
+      break;
+
+    case LTT_ARRAY:
+    case LTT_SEQUENCE:
+      g_string_append_printf(s, " {");
+      nb = ltt_event_field_element_number(e,f);
+      element = ltt_field_element(f);
+      for(i = 0 ; i < nb ; i++) {
+        ltt_event_field_element_select(e,f,i);
+        lttv_print_field(e, element, s, field_names);
+      }
+      g_string_append_printf(s, " }");
+      break;
+
+    case LTT_STRUCT:
+      g_string_append_printf(s, " {");
+      nb = ltt_type_member_number(type);
+      for(i = 0 ; i < nb ; i++) {
+        element = ltt_field_member(f,i);
+        if(field_names) {
+          ltt_type_member_type(type, i, &name);
+          g_string_append_printf(s, " %s = ", g_quark_to_string(name));
+        }
+        lttv_print_field(e, element, s, field_names);
+      }
+      g_string_append_printf(s, " }");
+      break;
+
+    case LTT_UNION:
+      g_string_append_printf(s, " {");
+      nb = ltt_type_member_number(type);
+      for(i = 0 ; i < nb ; i++) {
+        element = ltt_field_member(f,i);
+        if(field_names) {
+          ltt_type_member_type(type, i, &name);
+          g_string_append_printf(s, " %s = ", g_quark_to_string(name));
+        }
+        lttv_print_field(e, element, s, field_names);
+      }
+      g_string_append_printf(s, " }");
+      break;
+
+  }
+}
+
+
+void lttv_event_to_string(LttEvent *e, GString *s,
+    gboolean mandatory_fields, gboolean field_names, LttvTracefileState *tfs)
+{ 
+  LttFacility *facility;
+
+  LttEventType *event_type;
+
+  LttField *field;
+
+  LttTime time;
+
+  guint cpu = ltt_tracefile_num(tfs->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)tfs->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+
+  g_string_set_size(s,0);
+
+  facility = ltt_event_facility(e);
+  event_type = ltt_event_eventtype(e);
+  field = ltt_event_field(e);
+
+  if(mandatory_fields) {
+    time = ltt_event_time(e);
+    g_string_append_printf(s,"%s.%s: %ld.%09ld (%s_%u)",
+        g_quark_to_string(ltt_facility_name(facility)),
+        g_quark_to_string(ltt_eventtype_name(event_type)),
+        (long)time.tv_sec, time.tv_nsec,
+        g_quark_to_string(ltt_tracefile_name(tfs->parent.tf)),
+        cpu);
+    /* Print the process id and the state/interrupt type of the process */
+    g_string_append_printf(s,", %u, %u,  %s", process->pid,
+                   process->ppid,
+                   g_quark_to_string(process->state->t));
+  }
+
+  if(field)
+    lttv_print_field(e, field, s, field_names);
+} 
+
+static void init()
+{
+}
+
+static void destroy()
+{
+}
+
+LTTV_MODULE("print", "Print events", \
+           "Produce a detailed text printout of events", \
+           init, destroy)
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/print.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/print.h
new file mode 100644 (file)
index 0000000..c21abcd
--- /dev/null
@@ -0,0 +1,34 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *               2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* print.c
+ *
+ * Event printing routines header.
+ *
+ * Use these functions to print textually event fields. 
+ */
+
+
+
+void lttv_print_field(LttEvent *e, LttField *f, GString *s,
+                      gboolean field_names);
+
+void lttv_event_to_string(LttEvent *e, GString *s,
+    gboolean mandatory_fields, gboolean field_names, LttvTracefileState *tfs);
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/state.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/state.c
new file mode 100644 (file)
index 0000000..d5d5403
--- /dev/null
@@ -0,0 +1,2191 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttv/state.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <stdio.h>
+
+#define PREALLOCATED_EXECUTION_STACK 10
+
+/* Facilities Quarks */
+
+GQuark
+    LTT_FACILITY_KERNEL,
+    LTT_FACILITY_PROCESS,
+    LTT_FACILITY_FS;
+
+/* Events Quarks */
+
+GQuark 
+    LTT_EVENT_SYSCALL_ENTRY,
+    LTT_EVENT_SYSCALL_EXIT,
+    LTT_EVENT_TRAP_ENTRY,
+    LTT_EVENT_TRAP_EXIT,
+    LTT_EVENT_IRQ_ENTRY,
+    LTT_EVENT_IRQ_EXIT,
+    LTT_EVENT_SCHEDCHANGE,
+    LTT_EVENT_FORK,
+    LTT_EVENT_EXIT,
+    LTT_EVENT_FREE,
+    LTT_EVENT_EXEC;
+
+/* Fields Quarks */
+
+GQuark 
+    LTT_FIELD_SYSCALL_ID,
+    LTT_FIELD_TRAP_ID,
+    LTT_FIELD_IRQ_ID,
+    LTT_FIELD_OUT,
+    LTT_FIELD_IN,
+    LTT_FIELD_OUT_STATE,
+    LTT_FIELD_PARENT_PID,
+    LTT_FIELD_CHILD_PID,
+    LTT_FIELD_PID,
+    LTT_FIELD_FILENAME;
+
+LttvExecutionMode
+  LTTV_STATE_MODE_UNKNOWN,
+  LTTV_STATE_USER_MODE,
+  LTTV_STATE_SYSCALL,
+  LTTV_STATE_TRAP,
+  LTTV_STATE_IRQ;
+
+LttvExecutionSubmode
+  LTTV_STATE_SUBMODE_UNKNOWN,
+  LTTV_STATE_SUBMODE_NONE;
+
+LttvProcessStatus
+  LTTV_STATE_UNNAMED,
+  LTTV_STATE_WAIT_FORK,
+  LTTV_STATE_WAIT_CPU,
+  LTTV_STATE_EXIT,
+  LTTV_STATE_ZOMBIE,
+  LTTV_STATE_WAIT,
+  LTTV_STATE_RUN,
+  LTTV_STATE_DEAD;
+
+static GQuark
+  LTTV_STATE_TRACEFILES,
+  LTTV_STATE_PROCESSES,
+  LTTV_STATE_PROCESS,
+  LTTV_STATE_RUNNING_PROCESS,
+  LTTV_STATE_EVENT,
+  LTTV_STATE_SAVED_STATES,
+  LTTV_STATE_SAVED_STATES_TIME,
+  LTTV_STATE_TIME,
+  LTTV_STATE_HOOKS,
+  LTTV_STATE_NAME_TABLES,
+  LTTV_STATE_TRACE_STATE_USE_COUNT;
+
+static void create_max_time(LttvTraceState *tcs);
+
+static void get_max_time(LttvTraceState *tcs);
+
+static void free_max_time(LttvTraceState *tcs);
+
+static void create_name_tables(LttvTraceState *tcs);
+
+static void get_name_tables(LttvTraceState *tcs);
+
+static void free_name_tables(LttvTraceState *tcs);
+
+static void free_saved_state(LttvTraceState *tcs);
+
+static void lttv_state_free_process_table(GHashTable *processes);
+
+
+void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
+{
+  LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container);
+}
+
+
+void lttv_state_restore(LttvTraceState *self, LttvAttribute *container)
+{
+  LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
+}
+
+
+void lttv_state_state_saved_free(LttvTraceState *self, 
+    LttvAttribute *container)
+{
+  LTTV_TRACE_STATE_GET_CLASS(self)->state_saved_free(self, container);
+}
+
+
+guint process_hash(gconstpointer key) 
+{
+  guint pid = ((const LttvProcessState *)key)->pid;
+  return (pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ;
+}
+
+
+/* If the hash table hash function is well distributed,
+ * the process_equal should compare different pid */
+gboolean process_equal(gconstpointer a, gconstpointer b)
+{
+  const LttvProcessState *process_a, *process_b;
+  gboolean ret = TRUE;
+  
+  process_a = (const LttvProcessState *)a;
+  process_b = (const LttvProcessState *)b;
+  
+  if(likely(process_a->pid != process_b->pid)) ret = FALSE;
+  else if(likely(process_a->pid == 0 && 
+                 process_a->cpu != process_b->cpu)) ret = FALSE;
+
+  return ret;
+}
+
+
+static void
+restore_init_state(LttvTraceState *self)
+{
+  guint i, nb_cpus;
+
+  LttvTracefileState *tfcs;
+  
+  /* Free the process tables */
+  if(self->processes != NULL) lttv_state_free_process_table(self->processes);
+  self->processes = g_hash_table_new(process_hash, process_equal);
+  self->nb_event = 0;
+
+  /* Seek time to beginning */
+  // Mathieu : fix : don't seek traceset here : causes inconsistency in seek
+  // closest. It's the tracecontext job to seek the trace to the beginning
+  // anyway : the init state might be used at the middle of the trace as well...
+  //g_tree_destroy(self->parent.ts_context->pqueue);
+  //self->parent.ts_context->pqueue = g_tree_new(compare_tracefile);
+  
+  
+  //lttv_process_trace_seek_time(&self->parent, ltt_time_zero);
+
+  nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+  
+  /* Put the per cpu running_process to beginning state : process 0. */
+  for(i=0; i< nb_cpus; i++) {
+    self->running_process[i] = lttv_state_create_process(self, NULL, i, 0,
+        &ltt_time_zero);
+    self->running_process[i]->state->s = LTTV_STATE_RUN;
+    self->running_process[i]->cpu = i;
+  }
+  
+#if 0
+  nb_tracefile = self->parent.tracefiles->len;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfcs =
+      LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+                                          LttvTracefileContext*, i));
+    ltt_trace_time_span_get(self->parent.t, &tfcs->parent.timestamp, NULL);
+//    tfcs->saved_position = 0;
+    tfcs->process = lttv_state_create_process(tfcs, NULL,0);
+    tfcs->process->state->s = LTTV_STATE_RUN;
+    tfcs->process->last_cpu = tfcs->cpu_name;
+    tfcs->process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfcs)->tf);
+  }
+#endif //0
+}
+
+//static LttTime time_zero = {0,0};
+
+static void
+init(LttvTracesetState *self, LttvTraceset *ts)
+{
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTraceState *tcs;
+
+  LttvTracefileState *tfcs;
+  
+  LttvAttributeValue v;
+
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
+      init((LttvTracesetContext *)self, ts);
+
+  nb_trace = lttv_traceset_number(ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->parent.traces[i];
+    tcs = LTTV_TRACE_STATE(tc);
+    tcs->save_interval = LTTV_STATE_SAVE_INTERVAL;
+    lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT, 
+        LTTV_UINT, &v);
+    (*v.v_uint)++;
+
+    if(*(v.v_uint) == 1) {
+      create_name_tables(tcs);
+      create_max_time(tcs);
+    }
+    get_name_tables(tcs);
+    get_max_time(tcs);
+
+    nb_tracefile = tc->tracefiles->len;
+#if 0
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfcs = 
+          LTTV_TRACEFILE_STATE(g_array_index(tc->tracefiles,
+                                          LttvTracefileContext*, j));
+      tfcs->tracefile_name = ltt_tracefile_name(tfcs->parent.tf);
+    }
+#endif //0
+    tcs->processes = NULL;
+    tcs->running_process = g_new(LttvProcessState*, 
+                                 ltt_trace_get_num_cpu(tc->t));
+    restore_init_state(tcs);
+  }
+}
+
+
+static void
+fini(LttvTracesetState *self)
+{
+  guint i, nb_trace;
+
+  LttvTraceState *tcs;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttributeValue v;
+
+  nb_trace = lttv_traceset_number(LTTV_TRACESET_CONTEXT(self)->ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]);
+    lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT, 
+        LTTV_UINT, &v);
+
+    g_assert(*(v.v_uint) != 0);
+    (*v.v_uint)--;
+
+    if(*(v.v_uint) == 0) {
+      free_name_tables(tcs);
+      free_max_time(tcs);
+      free_saved_state(tcs);
+    }
+    g_free(tcs->running_process);
+    tcs->running_process = NULL;
+    lttv_state_free_process_table(tcs->processes);
+    tcs->processes = NULL;
+  }
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
+      fini((LttvTracesetContext *)self);
+}
+
+
+static LttvTracesetContext *
+new_traceset_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATE_TYPE, NULL));
+}
+
+
+static LttvTraceContext * 
+new_trace_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATE_TYPE, NULL));
+}
+
+
+static LttvTracefileContext *
+new_tracefile_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATE_TYPE, NULL));
+}
+
+
+/* Write the process state of the trace */
+
+static void write_process_state(gpointer key, gpointer value,
+    gpointer user_data)
+{
+  LttvProcessState *process;
+
+  LttvExecutionState *es;
+
+  FILE *fp = (FILE *)user_data;
+
+  guint i;
+
+  process = (LttvProcessState *)value;
+  fprintf(fp,
+"  <PROCESS CORE=%p PID=%u PPID=%u CTIME_S=%lu CTIME_NS=%lu NAME=\"%s\" CPU=\"%u\">\n",
+      process, process->pid, process->ppid, process->creation_time.tv_sec,
+      process->creation_time.tv_nsec, g_quark_to_string(process->name),
+      process->cpu);
+
+  for(i = 0 ; i < process->execution_stack->len; i++) {
+    es = &g_array_index(process->execution_stack, LttvExecutionState, i);
+    fprintf(fp, "    <ES MODE=\"%s\" SUBMODE=\"%s\" ENTRY_S=%lu ENTRY_NS=%lu",
+           g_quark_to_string(es->t), g_quark_to_string(es->n),
+            es->entry.tv_sec, es->entry.tv_nsec);
+    fprintf(fp, " CHANGE_S=%lu CHANGE_NS=%lu STATUS=\"%s\"/>\n",
+            es->change.tv_sec, es->change.tv_nsec, g_quark_to_string(es->s)); 
+  }
+  fprintf(fp, "  </PROCESS>\n");
+}
+
+
+void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp)
+{
+  guint i, nb_tracefile, nb_block, offset;
+  guint64 tsc;
+
+  LttvTracefileState *tfcs;
+
+  LttTracefile *tf;
+
+  LttEventPosition *ep;
+
+  guint nb_cpus;
+
+  ep = ltt_event_position_new();
+
+  fprintf(fp,"<PROCESS_STATE TIME_S=%lu TIME_NS=%lu>\n", t.tv_sec, t.tv_nsec);
+
+  g_hash_table_foreach(self->processes, write_process_state, fp);
+  
+  nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+  for(i=0;i<nb_cpus;i++) {
+    fprintf(fp,"<CPU NUM=%u RUNNING_PROCESS=%u>\n",
+        i, self->running_process[i]->pid);
+  }
+
+  nb_tracefile = self->parent.tracefiles->len;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfcs = 
+          LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+                                          LttvTracefileContext*, i));
+    fprintf(fp, "  <TRACEFILE TIMESTAMP_S=%lu TIMESTAMP_NS=%lu", 
+        tfcs->parent.timestamp.tv_sec, 
+        tfcs->parent.timestamp.tv_nsec);
+    LttEvent *e = ltt_tracefile_get_event(tfcs->parent.tf);
+    if(e == NULL) fprintf(fp,"/>\n");
+    else {
+      ltt_event_position(e, ep);
+      ltt_event_position_get(ep, &tf, &nb_block, &offset, &tsc);
+      fprintf(fp, " BLOCK=%u OFFSET=%u TSC=%llu/>\n", nb_block, offset,
+          tsc);
+    }
+  }
+  g_free(ep);
+  fprintf(fp,"</PROCESS_STATE>");
+}
+
+
+/* Copy each process from an existing hash table to a new one */
+
+static void copy_process_state(gpointer key, gpointer value,gpointer user_data)
+{
+  LttvProcessState *process, *new_process;
+
+  GHashTable *new_processes = (GHashTable *)user_data;
+
+  guint i;
+
+  process = (LttvProcessState *)value;
+  new_process = g_new(LttvProcessState, 1);
+  *new_process = *process;
+  new_process->execution_stack = g_array_sized_new(FALSE, FALSE, 
+      sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
+  new_process->execution_stack = 
+              g_array_set_size(new_process->execution_stack,
+                  process->execution_stack->len);
+  for(i = 0 ; i < process->execution_stack->len; i++) {
+    g_array_index(new_process->execution_stack, LttvExecutionState, i) =
+        g_array_index(process->execution_stack, LttvExecutionState, i);
+  }
+  new_process->state = &g_array_index(new_process->execution_stack, 
+      LttvExecutionState, new_process->execution_stack->len - 1);
+  g_hash_table_insert(new_processes, new_process, new_process);
+}
+
+
+static GHashTable *lttv_state_copy_process_table(GHashTable *processes)
+{
+  GHashTable *new_processes = g_hash_table_new(process_hash, process_equal);
+
+  g_hash_table_foreach(processes, copy_process_state, new_processes);
+  return new_processes;
+}
+
+
+/* The saved state for each trace contains a member "processes", which
+   stores a copy of the process table, and a member "tracefiles" with
+   one entry per tracefile. Each tracefile has a "process" member pointing
+   to the current process and a "position" member storing the tracefile
+   position (needed to seek to the current "next" event. */
+
+static void state_save(LttvTraceState *self, LttvAttribute *container)
+{
+  guint i, nb_tracefile, nb_cpus;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttribute *tracefiles_tree, *tracefile_tree;
+  
+  guint *running_process;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttEventPosition *ep;
+
+  tracefiles_tree = lttv_attribute_find_subdir(container, 
+      LTTV_STATE_TRACEFILES);
+
+  value = lttv_attribute_add(container, LTTV_STATE_PROCESSES,
+      LTTV_POINTER);
+  *(value.v_pointer) = lttv_state_copy_process_table(self->processes);
+
+  /* Add the currently running processes array */
+  nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+  running_process = g_new(guint, nb_cpus);
+  for(i=0;i<nb_cpus;i++) {
+    running_process[i] = self->running_process[i]->pid;
+  }
+  value = lttv_attribute_add(container, LTTV_STATE_RUNNING_PROCESS, 
+                             LTTV_POINTER);
+  *(value.v_pointer) = running_process;
+  
+  g_info("State save");
+  
+  nb_tracefile = self->parent.tracefiles->len;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfcs = 
+          LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+                                          LttvTracefileContext*, i));
+    tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    value = lttv_attribute_add(tracefiles_tree, i, 
+        LTTV_GOBJECT);
+    *(value.v_gobject) = (GObject *)tracefile_tree;
+#if 0
+    value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS, 
+        LTTV_UINT);
+    *(value.v_uint) = tfcs->process->pid;
+#endif //0
+    value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT, 
+        LTTV_POINTER);
+    /* Only save the position if the tfs has not infinite time. */
+    //if(!g_tree_lookup(self->parent.ts_context->pqueue, &tfcs->parent)
+    //    && current_tfcs != tfcs) {
+    if(ltt_time_compare(tfcs->parent.timestamp, ltt_time_infinite) == 0) {
+      *(value.v_pointer) = NULL;
+    } else {
+      LttEvent *e = ltt_tracefile_get_event(tfcs->parent.tf);
+      ep = ltt_event_position_new();
+      ltt_event_position(e, ep);
+      *(value.v_pointer) = ep;
+
+      guint nb_block, offset;
+      guint64 tsc;
+      LttTracefile *tf;
+      ltt_event_position_get(ep, &tf, &nb_block, &offset, &tsc);
+      g_info("Block %u offset %u tsc %llu time %lu.%lu", nb_block, offset,
+          tsc,
+          tfcs->parent.timestamp.tv_sec, tfcs->parent.timestamp.tv_nsec);
+    }
+  }
+}
+
+
+static void state_restore(LttvTraceState *self, LttvAttribute *container)
+{
+  guint i, nb_tracefile, pid, nb_cpus;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttribute *tracefiles_tree, *tracefile_tree;
+
+  guint *running_process;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttEventPosition *ep;
+
+  LttvTracesetContext *tsc = self->parent.ts_context;
+
+  tracefiles_tree = lttv_attribute_find_subdir(container, 
+      LTTV_STATE_TRACEFILES);
+
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, 
+      &value);
+  g_assert(type == LTTV_POINTER);
+  lttv_state_free_process_table(self->processes);
+  self->processes = lttv_state_copy_process_table(*(value.v_pointer));
+
+  /* Add the currently running processes array */
+  nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_RUNNING_PROCESS, 
+        &value);
+  g_assert(type == LTTV_POINTER);
+  running_process = *(value.v_pointer);
+  for(i=0;i<nb_cpus;i++) {
+    pid = running_process[i];
+    self->running_process[i] = lttv_state_find_process(self, i, pid);
+    g_assert(self->running_process[i] != NULL);
+  }
+
+  nb_tracefile = self->parent.tracefiles->len;
+
+  //g_tree_destroy(tsc->pqueue);
+  //tsc->pqueue = g_tree_new(compare_tracefile);
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfcs = 
+          LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+                                          LttvTracefileContext*, i));
+    type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
+    g_assert(type == LTTV_GOBJECT);
+    tracefile_tree = *((LttvAttribute **)(value.v_gobject));
+#if 0
+    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS, 
+        &value);
+    g_assert(type == LTTV_UINT);
+    pid = *(value.v_uint);
+    tfcs->process = lttv_state_find_process_or_create(tfcs, pid);
+#endif //0
+    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, 
+        &value);
+    g_assert(type == LTTV_POINTER);
+    //g_assert(*(value.v_pointer) != NULL);
+    ep = *(value.v_pointer);
+    g_assert(tfcs->parent.t_context != NULL);
+    
+    LttvTracefileContext *tfc = LTTV_TRACEFILE_CONTEXT(tfcs);
+    g_tree_remove(tsc->pqueue, tfc);
+    
+    if(ep != NULL) {
+      g_assert(ltt_tracefile_seek_position(tfc->tf, ep) == 0);
+      tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf));
+      g_assert(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0);
+      g_tree_insert(tsc->pqueue, tfc, tfc);
+      g_info("Restoring state for a tf at time %lu.%lu", tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
+    } else {
+      tfc->timestamp = ltt_time_infinite;
+    }
+  }
+}
+
+
+static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
+{
+  guint i, nb_tracefile, nb_cpus;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttribute *tracefiles_tree, *tracefile_tree;
+
+  guint *running_process;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttEventPosition *ep;
+
+  tracefiles_tree = lttv_attribute_find_subdir(container, 
+      LTTV_STATE_TRACEFILES);
+  g_object_ref(G_OBJECT(tracefiles_tree));
+  lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES);
+
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, 
+      &value);
+  g_assert(type == LTTV_POINTER);
+  lttv_state_free_process_table(*(value.v_pointer));
+  *(value.v_pointer) = NULL;
+  lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
+
+  /* Free running processes array */
+  nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_RUNNING_PROCESS, 
+        &value);
+  g_assert(type == LTTV_POINTER);
+  running_process = *(value.v_pointer);
+  g_free(running_process);
+
+  nb_tracefile = self->parent.tracefiles->len;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfcs = 
+          LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+                                          LttvTracefileContext*, i));
+    type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
+    g_assert(type == LTTV_GOBJECT);
+    tracefile_tree = *((LttvAttribute **)(value.v_gobject));
+
+    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, 
+        &value);
+    g_assert(type == LTTV_POINTER);
+    if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer));
+  }
+  g_object_unref(G_OBJECT(tracefiles_tree));
+}
+
+
+static void free_saved_state(LttvTraceState *self)
+{
+  guint i, nb;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttvAttribute *saved_states;
+
+  saved_states = lttv_attribute_find_subdir(self->parent.t_a,
+      LTTV_STATE_SAVED_STATES);
+
+  nb = lttv_attribute_get_number(saved_states);
+  for(i = 0 ; i < nb ; i++) {
+    type = lttv_attribute_get(saved_states, i, &name, &value);
+    g_assert(type == LTTV_GOBJECT);
+    state_saved_free(self, *((LttvAttribute **)value.v_gobject));
+  }
+
+  lttv_attribute_remove_by_name(self->parent.t_a, LTTV_STATE_SAVED_STATES);
+}
+
+
+static void 
+create_max_time(LttvTraceState *tcs) 
+{
+  LttvAttributeValue v;
+
+  lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, 
+        LTTV_POINTER, &v);
+  g_assert(*(v.v_pointer) == NULL);
+  *(v.v_pointer) = g_new(LttTime,1);
+  *((LttTime *)*(v.v_pointer)) = ltt_time_zero;
+}
+
+
+static void 
+get_max_time(LttvTraceState *tcs) 
+{
+  LttvAttributeValue v;
+
+  lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, 
+        LTTV_POINTER, &v);
+  g_assert(*(v.v_pointer) != NULL);
+  tcs->max_time_state_recomputed_in_seek = (LttTime *)*(v.v_pointer);
+}
+
+
+static void 
+free_max_time(LttvTraceState *tcs) 
+{
+  LttvAttributeValue v;
+
+  lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, 
+        LTTV_POINTER, &v);
+  g_free(*(v.v_pointer));
+  *(v.v_pointer) = NULL;
+}
+
+
+typedef struct _LttvNameTables {
+ // FIXME  GQuark *eventtype_names;
+  GQuark *syscall_names;
+  GQuark *trap_names;
+  GQuark *irq_names;
+} LttvNameTables;
+
+
+static void 
+create_name_tables(LttvTraceState *tcs) 
+{
+  int i, nb;
+
+  GQuark f_name, e_name;
+
+  LttvTraceHook h;
+
+  LttvTraceHookByFacility *thf;
+
+  LttEventType *et;
+
+  LttType *t;
+
+  GString *fe_name = g_string_new("");
+
+  LttvNameTables *name_tables = g_new(LttvNameTables, 1);
+
+  LttvAttributeValue v;
+
+  lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, 
+      LTTV_POINTER, &v);
+  g_assert(*(v.v_pointer) == NULL);
+  *(v.v_pointer) = name_tables;
+#if 0 // Use iteration over the facilities_by_name and then list all event
+      // types of each facility
+  nb = ltt_trace_eventtype_number(tcs->parent.t);
+  name_tables->eventtype_names = g_new(GQuark, nb);
+  for(i = 0 ; i < nb ; i++) {
+    et = ltt_trace_eventtype_get(tcs->parent.t, i);
+    e_name = ltt_eventtype_name(et);
+    f_name = ltt_facility_name(ltt_eventtype_facility(et));
+    g_string_printf(fe_name, "%s.%s", f_name, e_name);
+    name_tables->eventtype_names[i] = g_quark_from_string(fe_name->str);    
+  }
+#endif //0
+  if(lttv_trace_find_hook(tcs->parent.t,
+      LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+      LTT_FIELD_SYSCALL_ID, 0, 0,
+      NULL, NULL, &h))
+    return;
+  
+  thf = lttv_trace_hook_get_first(&h);
+  
+  t = ltt_field_type(thf->f1);
+  nb = ltt_type_element_number(t);
+  
+  lttv_trace_hook_destroy(&h);
+
+  /* CHECK syscalls should be an enum but currently are not!  
+  name_tables->syscall_names = g_new(GQuark, nb);
+
+  for(i = 0 ; i < nb ; i++) {
+    name_tables->syscall_names[i] = g_quark_from_string(
+        ltt_enum_string_get(t, i));
+  }
+  */
+
+  name_tables->syscall_names = g_new(GQuark, 256);
+  for(i = 0 ; i < 256 ; i++) {
+    g_string_printf(fe_name, "syscall %d", i);
+    name_tables->syscall_names[i] = g_quark_from_string(fe_name->str);
+  }
+
+  if(lttv_trace_find_hook(tcs->parent.t, LTT_FACILITY_KERNEL,
+        LTT_EVENT_TRAP_ENTRY,
+        LTT_FIELD_TRAP_ID, 0, 0,
+        NULL, NULL, &h))
+    return;
+
+  thf = lttv_trace_hook_get_first(&h);
+
+  t = ltt_field_type(thf->f1);
+  nb = ltt_type_element_number(t);
+
+  lttv_trace_hook_destroy(&h);
+
+  /*
+  name_tables->trap_names = g_new(GQuark, nb);
+  for(i = 0 ; i < nb ; i++) {
+    name_tables->trap_names[i] = g_quark_from_string(
+        ltt_enum_string_get(t, i));
+  }
+  */
+
+  name_tables->trap_names = g_new(GQuark, 256);
+  for(i = 0 ; i < 256 ; i++) {
+    g_string_printf(fe_name, "trap %d", i);
+    name_tables->trap_names[i] = g_quark_from_string(fe_name->str);
+  }
+
+  if(lttv_trace_find_hook(tcs->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
+        LTT_FIELD_IRQ_ID, 0, 0,
+        NULL, NULL, &h))
+    return;
+  
+  thf = lttv_trace_hook_get_first(&h);
+  
+  t = ltt_field_type(thf->f1);
+  nb = ltt_type_element_number(t);
+
+  lttv_trace_hook_destroy(&h);
+
+  /*
+  name_tables->irq_names = g_new(GQuark, nb);
+  for(i = 0 ; i < nb ; i++) {
+    name_tables->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
+  }
+  */
+
+  name_tables->irq_names = g_new(GQuark, 256);
+  for(i = 0 ; i < 256 ; i++) {
+    g_string_printf(fe_name, "irq %d", i);
+    name_tables->irq_names[i] = g_quark_from_string(fe_name->str);
+  }
+
+  g_string_free(fe_name, TRUE);
+}
+
+
+static void 
+get_name_tables(LttvTraceState *tcs) 
+{
+  LttvNameTables *name_tables;
+
+  LttvAttributeValue v;
+
+  lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, 
+        LTTV_POINTER, &v);
+  g_assert(*(v.v_pointer) != NULL);
+  name_tables = (LttvNameTables *)*(v.v_pointer);
+  //tcs->eventtype_names = name_tables->eventtype_names;
+  tcs->syscall_names = name_tables->syscall_names;
+  tcs->trap_names = name_tables->trap_names;
+  tcs->irq_names = name_tables->irq_names;
+}
+
+
+static void 
+free_name_tables(LttvTraceState *tcs) 
+{
+  LttvNameTables *name_tables;
+
+  LttvAttributeValue v;
+
+  lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, 
+        LTTV_POINTER, &v);
+  name_tables = (LttvNameTables *)*(v.v_pointer);
+  *(v.v_pointer) = NULL;
+
+ // g_free(name_tables->eventtype_names);
+  g_free(name_tables->syscall_names);
+  g_free(name_tables->trap_names);
+  g_free(name_tables->irq_names);
+  g_free(name_tables);
+} 
+
+#ifdef HASH_TABLE_DEBUG
+
+static void test_process(gpointer key, gpointer value, gpointer user_data)
+{
+  LttvProcessState *process = (LttvProcessState *)value;
+  
+  /* Test for process corruption */
+  guint stack_len = process->execution_stack->len;
+}
+
+static void hash_table_check(GHashTable *table)
+{
+  g_hash_table_foreach(table, test_process, NULL);
+}
+
+
+#endif
+
+
+static void push_state(LttvTracefileState *tfs, LttvExecutionMode t, 
+    guint state_id)
+{
+  LttvExecutionState *es;
+  
+  guint cpu = ltt_tracefile_num(tfs->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)tfs->parent.t_context;
+
+#ifdef HASH_TABLE_DEBUG
+  hash_table_check(ts->processes);
+#endif
+  LttvProcessState *process = ts->running_process[cpu];
+
+  guint depth = process->execution_stack->len;
+
+  process->execution_stack = 
+    g_array_set_size(process->execution_stack, depth + 1);
+  /* Keep in sync */
+  process->state =
+    &g_array_index(process->execution_stack, LttvExecutionState, depth - 1);
+    
+  es = &g_array_index(process->execution_stack, LttvExecutionState, depth);
+  es->t = t;
+  es->n = state_id;
+  es->entry = es->change = tfs->parent.timestamp;
+  es->s = process->state->s;
+  process->state = es;
+}
+
+
+static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t)
+{
+  guint cpu = ltt_tracefile_num(tfs->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)tfs->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+
+  guint depth = process->execution_stack->len;
+
+  if(process->state->t != t){
+    g_info("Different execution mode type (%lu.%09lu): ignore it\n",
+        tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
+    g_info("process state has %s when pop_int is %s\n",
+                   g_quark_to_string(process->state->t),
+                   g_quark_to_string(t));
+    g_info("{ %u, %u, %s, %s }\n",
+                   process->pid,
+                   process->ppid,
+                   g_quark_to_string(process->name),
+                   g_quark_to_string(process->state->s));
+    return;
+  }
+
+  if(depth == 1){
+    g_info("Trying to pop last state on stack (%lu.%09lu): ignore it\n",
+        tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
+    return;
+  }
+
+  process->execution_stack = 
+    g_array_set_size(process->execution_stack, depth - 1);
+  process->state = &g_array_index(process->execution_stack, LttvExecutionState,
+      depth - 2);
+  process->state->change = tfs->parent.timestamp;
+}
+
+
+LttvProcessState *
+lttv_state_create_process(LttvTraceState *tcs, LttvProcessState *parent, 
+    guint cpu, guint pid, const LttTime *timestamp)
+{
+  LttvProcessState *process = g_new(LttvProcessState, 1);
+
+  LttvExecutionState *es;
+
+  LttvTraceContext *tc = (LttvTraceContext*)tcs;
+
+  char buffer[128];
+
+  process->pid = pid;
+  process->cpu = cpu;
+  //process->last_cpu = tfs->cpu_name;
+  //process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf);
+  g_info("Process %u, core %p", process->pid, process);
+  g_hash_table_insert(tcs->processes, process, process);
+
+  if(parent) {
+    process->ppid = parent->pid;
+    process->name = parent->name;
+    process->creation_time = *timestamp;
+  }
+
+  /* No parent. This process exists but we are missing all information about
+     its creation. The birth time is set to zero but we remember the time of
+     insertion */
+
+  else {
+    process->ppid = 0;
+    process->name = LTTV_STATE_UNNAMED;
+    process->creation_time = ltt_time_zero;
+  }
+
+  process->insertion_time = *timestamp;
+  sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec, 
+         process->creation_time.tv_nsec);
+  process->pid_time = g_quark_from_string(buffer);
+  process->cpu = cpu;
+  //process->last_cpu = tfs->cpu_name;
+  //process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf);
+  process->execution_stack = g_array_sized_new(FALSE, FALSE, 
+      sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
+  process->execution_stack = g_array_set_size(process->execution_stack, 2);
+  es = process->state = &g_array_index(process->execution_stack, 
+      LttvExecutionState, 0);
+  es->t = LTTV_STATE_USER_MODE;
+  es->n = LTTV_STATE_SUBMODE_NONE;
+  es->entry = *timestamp;
+  //g_assert(timestamp->tv_sec != 0);
+  es->change = *timestamp;
+  es->s = LTTV_STATE_RUN;
+
+  es = process->state = &g_array_index(process->execution_stack, 
+      LttvExecutionState, 1);
+  es->t = LTTV_STATE_SYSCALL;
+  es->n = LTTV_STATE_SUBMODE_NONE;
+  es->entry = *timestamp;
+  //g_assert(timestamp->tv_sec != 0);
+  es->change = *timestamp;
+  es->s = LTTV_STATE_WAIT_FORK;
+
+  return process;
+}
+
+LttvProcessState *lttv_state_find_process(LttvTraceState *ts, guint cpu,
+    guint pid)
+{
+  LttvProcessState key;
+  LttvProcessState *process;
+
+  key.pid = pid;
+  key.cpu = cpu;
+  process = g_hash_table_lookup(ts->processes, &key);
+  return process;
+}
+
+LttvProcessState *
+lttv_state_find_process_or_create(LttvTraceState *ts, guint cpu, guint pid,
+    LttTime *timestamp)
+{
+  LttvProcessState *process = lttv_state_find_process(ts, cpu, pid);
+  
+  /* Put ltt_time_zero creation time for unexisting processes */
+  if(unlikely(process == NULL)) process = lttv_state_create_process(ts,
+                NULL, cpu, pid, timestamp);
+  return process;
+}
+
+/* FIXME : this function should be called when we receive an event telling that
+ * release_task has been called in the kernel. In happens generally when
+ * the parent waits for its child terminaison, but may also happen in special
+ * cases in the child's exit : when the parent ignores its children SIGCCHLD or
+ * has the flag SA_NOCLDWAIT. It can also happen when the child is part
+ * of a killed thread ground, but isn't the leader.
+ */
+static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) 
+{
+  LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context);
+  LttvProcessState key;
+
+  key.pid = process->pid;
+  key.cpu = process->cpu;
+  g_hash_table_remove(ts->processes, &key);
+  g_array_free(process->execution_stack, TRUE);
+  g_free(process);
+}
+
+
+static void free_process_state(gpointer key, gpointer value,gpointer user_data)
+{
+  g_array_free(((LttvProcessState *)value)->execution_stack, TRUE);
+  g_free(value);
+}
+
+
+static void lttv_state_free_process_table(GHashTable *processes)
+{
+  g_hash_table_foreach(processes, free_process_state, NULL);
+  g_hash_table_destroy(processes);
+}
+
+
+static gboolean syscall_entry(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  LttField *f = thf->f1;
+
+  LttvExecutionSubmode submode;
+
+  submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[
+      ltt_event_get_unsigned(e, f)];
+  push_state(s, LTTV_STATE_SYSCALL, submode);
+  return FALSE;
+}
+
+
+static gboolean syscall_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  pop_state(s, LTTV_STATE_SYSCALL);
+  return FALSE;
+}
+
+
+static gboolean trap_entry(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  LttField *f = thf->f1;
+
+  LttvExecutionSubmode submode;
+
+  submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[
+      ltt_event_get_unsigned(e, f)];
+  push_state(s, LTTV_STATE_TRAP, submode);
+  return FALSE;
+}
+
+
+static gboolean trap_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  pop_state(s, LTTV_STATE_TRAP);
+  return FALSE;
+}
+
+
+static gboolean irq_entry(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  guint8 fac_id = ltt_event_facility_id(e);
+  guint8 ev_id = ltt_event_eventtype_id(e);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ // g_assert(lttv_trace_hook_get_first((LttvTraceHook *)hook_data)->f1 != NULL);
+  g_assert(thf->f1 != NULL);
+ // g_assert(thf == lttv_trace_hook_get_first((LttvTraceHook *)hook_data));
+  LttField *f = thf->f1;
+
+  LttvExecutionSubmode submode;
+
+  submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[
+      ltt_event_get_unsigned(e, f)];
+
+  /* Do something with the info about being in user or system mode when int? */
+  push_state(s, LTTV_STATE_IRQ, submode);
+  return FALSE;
+}
+
+
+static gboolean irq_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  pop_state(s, LTTV_STATE_IRQ);
+  return FALSE;
+}
+
+
+static gboolean schedchange(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  guint cpu = ltt_tracefile_num(s->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+  
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  guint pid_in, pid_out;
+  gint state_out;
+
+  pid_out = ltt_event_get_unsigned(e, thf->f1);
+  pid_in = ltt_event_get_unsigned(e, thf->f2);
+  state_out = ltt_event_get_int(e, thf->f3);
+  
+  if(likely(process != NULL)) {
+
+    /* We could not know but it was not the idle process executing.
+       This should only happen at the beginning, before the first schedule
+       event, and when the initial information (current process for each CPU)
+       is missing. It is not obvious how we could, after the fact, compensate
+       the wrongly attributed statistics. */
+
+    //This test only makes sense once the state is known and if there is no
+    //missing events.
+    //if(unlikely(process->pid != pid_out)) {
+    //  g_assert(process->pid == 0);
+    //}
+
+    if(unlikely(process->state->s == LTTV_STATE_EXIT)) {
+      process->state->s = LTTV_STATE_ZOMBIE;
+      process->state->change = s->parent.timestamp;
+    } else {
+      if(unlikely(state_out == 0)) process->state->s = LTTV_STATE_WAIT_CPU;
+      else process->state->s = LTTV_STATE_WAIT;
+      process->state->change = s->parent.timestamp;
+    }
+
+    if(state_out == 32)
+       exit_process(s, process); /* EXIT_DEAD */
+          /* see sched.h for states */
+  }
+  process = ts->running_process[cpu] =
+              lttv_state_find_process_or_create(
+                  (LttvTraceState*)s->parent.t_context,
+                  cpu, pid_in,
+                  &s->parent.timestamp);
+  process->state->s = LTTV_STATE_RUN;
+  process->cpu = cpu;
+ // process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)s)->tf);
+  process->state->change = s->parent.timestamp;
+  return FALSE;
+}
+
+static gboolean process_fork(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  LttField *f;
+  guint parent_pid;
+  guint child_pid;
+  LttvProcessState *zombie_process;
+  guint cpu = ltt_tracefile_num(s->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+  LttvProcessState *child_process;
+
+  /* Parent PID */
+  f = thf->f1;
+  parent_pid = ltt_event_get_unsigned(e, f);
+
+  /* Child PID */
+  f = thf->f2;
+  child_pid = ltt_event_get_unsigned(e, f);
+
+  /* Mathieu : it seems like the process might have been scheduled in before the
+   * fork, and, in a rare case, might be the current process. This might happen
+   * in a SMP case where we don't have enough precision on the clocks.
+   *
+   * Test reenabled after precision fixes on time. (Mathieu) */
+#if 0 
+  zombie_process = lttv_state_find_process(ts, ANY_CPU, child_pid);
+
+  if(unlikely(zombie_process != NULL)) {
+    /* Reutilisation of PID. Only now we are sure that the old PID
+     * has been released. FIXME : should know when release_task happens instead.
+     */
+    guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
+    guint i;
+    for(i=0; i< num_cpus; i++) {
+      g_assert(zombie_process != ts->running_process[i]);
+    }
+
+    exit_process(s, zombie_process);
+  }
+#endif //0
+  g_assert(process->pid != child_pid);
+  // FIXME : Add this test in the "known state" section
+  // g_assert(process->pid == parent_pid);
+  child_process = lttv_state_find_process(ts, ANY_CPU, child_pid);
+  if(child_process == NULL) {
+    lttv_state_create_process(ts, process, cpu,
+                              child_pid, &s->parent.timestamp);
+  } else {
+    /* The process has already been created :  due to time imprecision between
+     * multiple CPUs : it has been scheduled in before creation. Note that we
+     * shouldn't have this kind of imprecision.
+     *
+     * Simply put a correct parent.
+     */
+    g_assert(0); /* This is a problematic case : the process has been created
+                    before the fork event */
+    child_process->ppid = process->pid;
+  }
+
+  return FALSE;
+}
+
+
+static gboolean process_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  LttField *f;
+  guint pid;
+  guint cpu = ltt_tracefile_num(s->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+
+  pid = ltt_event_get_unsigned(e, thf->f1);
+
+  // FIXME : Add this test in the "known state" section
+  // g_assert(process->pid == pid);
+
+  if(likely(process != NULL)) {
+    process->state->s = LTTV_STATE_EXIT;
+  }
+  return FALSE;
+}
+
+static gboolean process_free(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  guint release_pid;
+  LttvProcessState *process;
+
+  /* PID of the process to release */
+  release_pid = ltt_event_get_unsigned(e, thf->f1);
+  
+  g_assert(release_pid != 0);
+
+  process = lttv_state_find_process(ts, ANY_CPU, release_pid);
+
+  if(likely(process != NULL)) {
+    /* release_task is happening at kernel level : we can now safely release
+     * the data structure of the process */
+    //This test is fun, though, as it may happen that 
+    //at time t : CPU 0 : process_free
+    //at time t+150ns : CPU 1 : schedule out
+    //Clearly due to time imprecision, we disable it. (Mathieu)
+    //If this weird case happen, we have no choice but to put the 
+    //Currently running process on the cpu to 0.
+    //I re-enable it following time precision fixes. (Mathieu)
+    //Well, in the case where an process is freed by a process on another CPU
+    //and still scheduled, it happens that this is the schedchange that will
+    //drop the last reference count. Do not free it here!
+    guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
+    guint i;
+    for(i=0; i< num_cpus; i++) {
+      //g_assert(process != ts->running_process[i]);
+      if(process == ts->running_process[i]) {
+        //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
+        break;
+      }
+    }
+    if(i == num_cpus) /* process is not scheduled */
+      exit_process(s, process);
+  }
+
+  return FALSE;
+}
+
+
+static gboolean process_exec(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+  gchar *name;
+  guint cpu = ltt_tracefile_num(s->parent.tf);
+  LttvProcessState *process = ts->running_process[cpu];
+
+  /* PID of the process to release */
+  name = ltt_event_get_string(e, thf->f1);
+
+  process->name = g_quark_from_string(name);
+
+  return FALSE;
+}
+
+
+
+
+gint lttv_state_hook_add_event_hooks(void *hook_data, void *call_data)
+{
+  LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+  lttv_state_add_event_hooks(tss);
+
+  return 0;
+}
+
+void lttv_state_add_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, k, l, nb_trace, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  GArray *hooks;
+
+  LttvTraceHookByFacility *thf;
+  
+  LttvTraceHook *hook;
+
+  LttvAttributeValue val;
+
+  gint ret;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceState *)self->parent.traces[i];
+
+    /* Find the eventtype id for the following events and register the
+       associated by id hooks. */
+
+    hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 11);
+    hooks = g_array_set_size(hooks, 11);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+        LTT_FIELD_SYSCALL_ID, 0, 0,
+        syscall_entry, NULL, &g_array_index(hooks, LttvTraceHook, 0));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_EXIT,
+        0, 0, 0,
+        syscall_exit, NULL, &g_array_index(hooks, LttvTraceHook, 1));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
+        LTT_FIELD_TRAP_ID, 0, 0,
+        trap_entry, NULL, &g_array_index(hooks, LttvTraceHook, 2));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
+        0, 0, 0, 
+        trap_exit, NULL, &g_array_index(hooks, LttvTraceHook, 3));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
+        LTT_FIELD_IRQ_ID, 0, 0,
+        irq_entry, NULL, &g_array_index(hooks, LttvTraceHook, 4));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
+        0, 0, 0, 
+        irq_exit, NULL, &g_array_index(hooks, LttvTraceHook, 5));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
+        LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
+        schedchange, NULL, &g_array_index(hooks, LttvTraceHook, 6));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
+        LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
+        process_fork, NULL, &g_array_index(hooks, LttvTraceHook, 7));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
+        LTT_FIELD_PID, 0, 0,
+        process_exit, NULL, &g_array_index(hooks, LttvTraceHook, 8));
+    g_assert(!ret);
+    
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
+        LTT_FIELD_PID, 0, 0,
+        process_free, NULL, &g_array_index(hooks, LttvTraceHook, 9));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.t,
+        LTT_FACILITY_FS, LTT_EVENT_EXEC,
+        LTT_FIELD_FILENAME, 0, 0,
+        process_exec, NULL, &g_array_index(hooks, LttvTraceHook, 10));
+    g_assert(!ret);
+
+
+
+    /* Add these hooks to each event_by_id hooks list */
+
+    nb_tracefile = ts->parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = 
+          LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+                                          LttvTracefileContext*, j));
+
+      for(k = 0 ; k < hooks->len ; k++) {
+        hook = &g_array_index(hooks, LttvTraceHook, k);
+        for(l=0;l<hook->fac_list->len;l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_add(
+            lttv_hooks_by_id_find(tfs->parent.event_by_id, thf->id),
+            thf->h,
+            thf,
+            LTTV_PRIO_STATE);
+        }
+      }
+    }
+    lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
+    *(val.v_pointer) = hooks;
+  }
+}
+
+gint lttv_state_hook_remove_event_hooks(void *hook_data, void *call_data)
+{
+  LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+  lttv_state_remove_event_hooks(tss);
+
+  return 0;
+}
+
+void lttv_state_remove_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, k, l, nb_trace, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  GArray *hooks;
+
+  LttvTraceHook *hook;
+  
+  LttvTraceHookByFacility *thf;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = LTTV_TRACE_STATE(self->parent.traces[i]);
+    lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
+    hooks = *(val.v_pointer);
+
+    /* Remove these hooks from each event_by_id hooks list */
+
+    nb_tracefile = ts->parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = 
+          LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+                                          LttvTracefileContext*, j));
+
+      for(k = 0 ; k < hooks->len ; k++) {
+        hook = &g_array_index(hooks, LttvTraceHook, k);
+        for(l=0;l<hook->fac_list->len;l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          
+          lttv_hooks_remove_data(
+            lttv_hooks_by_id_find(tfs->parent.event_by_id, thf->id),
+                    thf->h,
+                    thf);
+        }
+      }
+    }
+    for(k = 0 ; k < hooks->len ; k++)
+      lttv_trace_hook_destroy(&g_array_index(hooks, LttvTraceHook, k));
+    g_array_free(hooks, TRUE);
+  }
+}
+
+static gboolean state_save_event_hook(void *hook_data, void *call_data)
+{
+  guint *event_count = (guint*)hook_data;
+
+  /* Only save at LTTV_STATE_SAVE_INTERVAL */
+  if(likely((*event_count)++ < LTTV_STATE_SAVE_INTERVAL))
+    return FALSE;
+  else
+    *event_count = 0;
+  
+  LttvTracefileState *self = (LttvTracefileState *)call_data;
+
+  LttvTracefileState *tfcs;
+
+  LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context);
+
+  LttEventPosition *ep;
+
+  guint i;
+
+  LttTracefile *tf;
+
+  LttvAttribute *saved_states_tree, *saved_state_tree;
+
+  LttvAttributeValue value;
+
+  saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, 
+      LTTV_STATE_SAVED_STATES);
+  saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  value = lttv_attribute_add(saved_states_tree, 
+      lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT);
+  *(value.v_gobject) = (GObject *)saved_state_tree;
+  value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
+  *(value.v_time) = self->parent.timestamp;
+  lttv_state_save(tcs, saved_state_tree);
+  g_debug("Saving state at time %lu.%lu", self->parent.timestamp.tv_sec,
+    self->parent.timestamp.tv_nsec);
+
+  *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp;
+
+  return FALSE;
+}
+
+static gboolean state_save_after_trace_hook(void *hook_data, void *call_data)
+{
+  LttvTraceState *tcs = (LttvTraceState *)(call_data);
+  
+  *(tcs->max_time_state_recomputed_in_seek) = tcs->parent.time_span.end_time;
+
+  return FALSE;
+}
+
+#if 0
+static gboolean block_start(void *hook_data, void *call_data)
+{
+  LttvTracefileState *self = (LttvTracefileState *)call_data;
+
+  LttvTracefileState *tfcs;
+
+  LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context);
+
+  LttEventPosition *ep;
+
+  guint i, nb_block, nb_event, nb_tracefile;
+
+  LttTracefile *tf;
+
+  LttvAttribute *saved_states_tree, *saved_state_tree;
+
+  LttvAttributeValue value;
+
+  ep = ltt_event_position_new();
+
+  nb_tracefile = tcs->parent.tracefiles->len;
+
+  /* Count the number of events added since the last block end in any
+     tracefile. */
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfcs = 
+          LTTV_TRACEFILE_STATE(&g_array_index(tcs->parent.tracefiles,
+                                          LttvTracefileContext, i));
+    ltt_event_position(tfcs->parent.e, ep);
+    ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
+    tcs->nb_event += nb_event - tfcs->saved_position;
+    tfcs->saved_position = nb_event;
+  }
+  g_free(ep);
+
+  if(tcs->nb_event >= tcs->save_interval) {
+    saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, 
+        LTTV_STATE_SAVED_STATES);
+    saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    value = lttv_attribute_add(saved_states_tree, 
+        lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT);
+    *(value.v_gobject) = (GObject *)saved_state_tree;
+    value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
+    *(value.v_time) = self->parent.timestamp;
+    lttv_state_save(tcs, saved_state_tree);
+    tcs->nb_event = 0;
+    g_debug("Saving state at time %lu.%lu", self->parent.timestamp.tv_sec,
+           self->parent.timestamp.tv_nsec);
+  }
+  *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp;
+  return FALSE;
+}
+#endif //0
+
+#if 0
+static gboolean block_end(void *hook_data, void *call_data)
+{
+  LttvTracefileState *self = (LttvTracefileState *)call_data;
+
+  LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context);
+
+  LttTracefile *tf;
+
+  LttEventPosition *ep;
+
+  guint nb_block, nb_event;
+
+  ep = ltt_event_position_new();
+  ltt_event_position(self->parent.e, ep);
+  ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
+  tcs->nb_event += nb_event - self->saved_position + 1;
+  self->saved_position = 0;
+  *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp;
+  g_free(ep);
+
+  return FALSE;
+}
+#endif //0
+#if 0
+void lttv_state_save_add_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  LttvTraceHook hook_start, hook_end;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceState *)self->parent.traces[i];
+
+    lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL, 
+       NULL, NULL, block_start, &hook_start);
+    lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, 
+       NULL, NULL, block_end, &hook_end);
+
+    nb_tracefile = ts->parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = 
+          LTTV_TRACEFILE_STATE(&g_array_index(ts->parent.tracefiles,
+                                          LttvTracefileContext, j));
+      lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.event_by_id, 
+               hook_start.id), hook_start.h, NULL, LTTV_PRIO_STATE);
+      lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.event_by_id, 
+                     hook_end.id), hook_end.h, NULL, LTTV_PRIO_STATE);
+    }
+  }
+}
+#endif //0
+
+void lttv_state_save_add_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+
+    ts = (LttvTraceState *)self->parent.traces[i];
+    nb_tracefile = ts->parent.tracefiles->len;
+
+    guint *event_count = g_new(guint, 1);
+    *event_count = 0;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = 
+          LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+                                          LttvTracefileContext*, j));
+      lttv_hooks_add(tfs->parent.event,
+                     state_save_event_hook,
+                     event_count,
+                     LTTV_PRIO_STATE);
+
+    }
+  }
+  
+  lttv_process_traceset_begin(&self->parent,
+                NULL, NULL, NULL, NULL, NULL);
+  
+}
+
+gint lttv_state_save_hook_add_event_hooks(void *hook_data, void *call_data)
+{
+  LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+  lttv_state_save_add_event_hooks(tss);
+
+  return 0;
+}
+
+
+#if 0
+void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  LttvTraceHook hook_start, hook_end;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = LTTV_TRACE_STATE(self->parent.traces[i]);
+
+    lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL, 
+       NULL, NULL, block_start, &hook_start);
+
+    lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, 
+       NULL, NULL, block_end, &hook_end);
+
+    nb_tracefile = ts->parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = 
+          LTTV_TRACEFILE_STATE(&g_array_index(ts->parent.tracefiles,
+                                          LttvTracefileContext, j));
+      lttv_hooks_remove_data(lttv_hooks_by_id_find(
+          tfs->parent.event_by_id, hook_start.id), hook_start.h, NULL);
+      lttv_hooks_remove_data(lttv_hooks_by_id_find(
+          tfs->parent.event_by_id, hook_end.id), hook_end.h, NULL);
+    }
+  }
+}
+#endif //0
+
+void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  LttvHooks *after_trace = lttv_hooks_new();
+  
+  lttv_hooks_add(after_trace,
+                 state_save_after_trace_hook,
+                 NULL,
+                 LTTV_PRIO_STATE);
+
+  
+  lttv_process_traceset_end(&self->parent,
+                NULL, after_trace, NULL, NULL, NULL);
+  lttv_hooks_destroy(after_trace);
+  
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+
+    ts = (LttvTraceState *)self->parent.traces[i];
+    nb_tracefile = ts->parent.tracefiles->len;
+
+    guint *event_count = NULL;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = 
+          LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+                                          LttvTracefileContext*, j));
+      event_count = lttv_hooks_remove(tfs->parent.event,
+                        state_save_event_hook);
+    }
+    if(event_count) g_free(event_count);
+  }
+}
+
+gint lttv_state_save_hook_remove_event_hooks(void *hook_data, void *call_data)
+{
+  LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+  lttv_state_save_remove_event_hooks(tss);
+
+  return 0;
+}
+
+void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, nb_trace;
+
+  int min_pos, mid_pos, max_pos;
+
+  guint call_rest = 0;
+
+  LttvTraceState *tcs;
+
+  LttvAttributeValue value;
+
+  LttvAttributeType type;
+
+  LttvAttributeName name;
+
+  LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree;
+
+  //g_tree_destroy(self->parent.pqueue);
+  //self->parent.pqueue = g_tree_new(compare_tracefile);
+  
+  g_info("Entering seek_time_closest for time %lu.%lu", t.tv_sec, t.tv_nsec);
+  
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceState *)self->parent.traces[i];
+
+    if(ltt_time_compare(t, *(tcs->max_time_state_recomputed_in_seek)) < 0) {
+      saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
+          LTTV_STATE_SAVED_STATES);
+      min_pos = -1;
+
+      if(saved_states_tree) {
+        max_pos = lttv_attribute_get_number(saved_states_tree) - 1;
+        mid_pos = max_pos / 2;
+        while(min_pos < max_pos) {
+          type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value);
+          g_assert(type == LTTV_GOBJECT);
+          saved_state_tree = *((LttvAttribute **)(value.v_gobject));
+          type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME, 
+              &value);
+          g_assert(type == LTTV_TIME);
+          if(ltt_time_compare(*(value.v_time), t) < 0) {
+            min_pos = mid_pos;
+            closest_tree = saved_state_tree;
+          }
+          else max_pos = mid_pos - 1;
+
+          mid_pos = (min_pos + max_pos + 1) / 2;
+        }
+      }
+
+      /* restore the closest earlier saved state */
+      if(min_pos != -1) {
+        lttv_state_restore(tcs, closest_tree);
+        call_rest = 1;
+      }
+
+      /* There is no saved state, yet we want to have it. Restart at T0 */
+      else {
+        restore_init_state(tcs);
+        lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
+      }
+    }
+    /* We want to seek quickly without restoring/updating the state */
+    else {
+      restore_init_state(tcs);
+      lttv_process_trace_seek_time(&(tcs->parent), t);
+    }
+  }
+  if(!call_rest) g_info("NOT Calling restore");
+}
+
+
+static void
+traceset_state_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+traceset_state_finalize (LttvTracesetState *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+traceset_state_class_init (LttvTracesetContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) traceset_state_finalize;
+  klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
+  klass->fini = (void (*)(LttvTracesetContext *self))fini;
+  klass->new_traceset_context = new_traceset_context;
+  klass->new_trace_context = new_trace_context;
+  klass->new_tracefile_context = new_tracefile_context;
+}
+
+
+GType 
+lttv_traceset_state_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracesetStateClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) traceset_state_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracesetState),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) traceset_state_instance_init,    /* instance_init */
+      NULL    /* value handling */
+    };
+
+    type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+trace_state_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+trace_state_finalize (LttvTraceState *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_CONTEXT_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+trace_state_class_init (LttvTraceStateClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) trace_state_finalize;
+  klass->state_save = state_save;
+  klass->state_restore = state_restore;
+  klass->state_saved_free = state_saved_free;
+}
+
+
+GType 
+lttv_trace_state_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTraceStateClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) trace_state_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTraceState),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) trace_state_instance_init,    /* instance_init */
+      NULL    /* value handling */
+    };
+
+    type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE, 
+        "LttvTraceStateType", &info, 0);
+  }
+  return type;
+}
+
+
+static void
+tracefile_state_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+tracefile_state_finalize (LttvTracefileState *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_CONTEXT_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+tracefile_state_class_init (LttvTracefileStateClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) tracefile_state_finalize;
+}
+
+
+GType 
+lttv_tracefile_state_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracefileStateClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) tracefile_state_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracefileState),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) tracefile_state_instance_init,    /* instance_init */
+      NULL    /* value handling */
+    };
+
+    type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE, 
+        "LttvTracefileStateType", &info, 0);
+  }
+  return type;
+}
+
+
+static void module_init()
+{
+  LTTV_STATE_UNNAMED = g_quark_from_string("unnamed");
+  LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("unknown execution mode");
+  LTTV_STATE_USER_MODE = g_quark_from_string("user mode");
+  LTTV_STATE_WAIT_FORK = g_quark_from_string("wait fork");
+  LTTV_STATE_SYSCALL = g_quark_from_string("system call");
+  LTTV_STATE_TRAP = g_quark_from_string("trap");
+  LTTV_STATE_IRQ = g_quark_from_string("irq");
+  LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("unknown submode");
+  LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)");
+  LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu");
+  LTTV_STATE_EXIT = g_quark_from_string("exiting");
+  LTTV_STATE_ZOMBIE = g_quark_from_string("zombie");
+  LTTV_STATE_WAIT = g_quark_from_string("wait for I/O");
+  LTTV_STATE_RUN = g_quark_from_string("running");
+  LTTV_STATE_DEAD = g_quark_from_string("dead");
+  LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
+  LTTV_STATE_PROCESSES = g_quark_from_string("processes");
+  LTTV_STATE_PROCESS = g_quark_from_string("process");
+  LTTV_STATE_RUNNING_PROCESS = g_quark_from_string("running_process");
+  LTTV_STATE_EVENT = g_quark_from_string("event");
+  LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states");
+  LTTV_STATE_SAVED_STATES_TIME = g_quark_from_string("saved states time");
+  LTTV_STATE_TIME = g_quark_from_string("time");
+  LTTV_STATE_HOOKS = g_quark_from_string("saved state hooks");
+  LTTV_STATE_NAME_TABLES = g_quark_from_string("name tables");
+  LTTV_STATE_TRACE_STATE_USE_COUNT = 
+      g_quark_from_string("trace_state_use_count");
+
+  
+  LTT_FACILITY_KERNEL     = g_quark_from_string("kernel");
+  LTT_FACILITY_PROCESS    = g_quark_from_string("process");
+  LTT_FACILITY_FS    = g_quark_from_string("fs");
+
+  
+  LTT_EVENT_SYSCALL_ENTRY = g_quark_from_string("syscall_entry");
+  LTT_EVENT_SYSCALL_EXIT  = g_quark_from_string("syscall_exit");
+  LTT_EVENT_TRAP_ENTRY    = g_quark_from_string("trap_entry");
+  LTT_EVENT_TRAP_EXIT     = g_quark_from_string("trap_exit");
+  LTT_EVENT_IRQ_ENTRY     = g_quark_from_string("irq_entry");
+  LTT_EVENT_IRQ_EXIT      = g_quark_from_string("irq_exit");
+  LTT_EVENT_SCHEDCHANGE   = g_quark_from_string("schedchange");
+  LTT_EVENT_FORK          = g_quark_from_string("fork");
+  LTT_EVENT_EXIT          = g_quark_from_string("exit");
+  LTT_EVENT_FREE          = g_quark_from_string("free");
+  LTT_EVENT_EXEC          = g_quark_from_string("exec");
+
+
+  LTT_FIELD_SYSCALL_ID    = g_quark_from_string("syscall_id");
+  LTT_FIELD_TRAP_ID       = g_quark_from_string("trap_id");
+  LTT_FIELD_IRQ_ID        = g_quark_from_string("irq_id");
+  LTT_FIELD_OUT           = g_quark_from_string("out");
+  LTT_FIELD_IN            = g_quark_from_string("in");
+  LTT_FIELD_OUT_STATE     = g_quark_from_string("out_state");
+  LTT_FIELD_PARENT_PID    = g_quark_from_string("parent_pid");
+  LTT_FIELD_CHILD_PID     = g_quark_from_string("child_pid");
+  LTT_FIELD_PID           = g_quark_from_string("pid");
+  LTT_FIELD_FILENAME      = g_quark_from_string("filename");
+  
+}
+
+static void module_destroy() 
+{
+}
+
+
+LTTV_MODULE("state", "State computation", \
+    "Update the system state, possibly saving it at intervals", \
+    module_init, module_destroy)
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/state.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/state.h
new file mode 100644 (file)
index 0000000..69f35ed
--- /dev/null
@@ -0,0 +1,304 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef STATE_H
+#define STATE_H
+
+#include <glib.h>
+#include <lttv/tracecontext.h>
+#include <stdio.h>
+
+/* The operating system state, kept during the trace analysis,
+   contains a subset of the real operating system state, 
+   sufficient for the analysis, and possibly organized quite differently.
+
+   The state information is added to LttvTracesetContext, LttvTraceContext 
+   and LttvTracefileContext objects, used by process_traceset, through
+   subtyping. The context objects already reflect the multiple tracefiles
+   (one per cpu) per trace and multiple traces per trace set. The state
+   objects defined here simply add fields to the relevant context objects. 
+
+   There is no traceset specific state yet. It may eventually contains such
+   things as clock differences over time.
+
+   The trace state currently consists in a process table. 
+
+   The tracefile level state relates to the associated cpu. It contains the
+   position of the current event in the tracefile (since the state depends on
+   which events have been processed) and a pointer to the current process,
+   in the process table, being run on that cpu.
+
+   For each process in the process table, various informations such as exec 
+   file name, pid, ppid and creation time are stored. Each process state also
+   contains an execution mode stack (e.g. irq within system call, called
+   from user mode). */
+
+/* Priority of state hooks */
+#define LTTV_PRIO_STATE 25
+
+#define LTTV_STATE_SAVE_INTERVAL 50000
+
+/* Facilities Quarks */
+
+extern GQuark
+    LTT_FACILITY_KERNEL,
+    LTT_FACILITY_PROCESS,
+    LTT_FACILITY_FS;
+
+/* Events Quarks */
+
+extern GQuark 
+    LTT_EVENT_SYSCALL_ENTRY,
+    LTT_EVENT_SYSCALL_EXIT,
+    LTT_EVENT_TRAP_ENTRY,
+    LTT_EVENT_TRAP_EXIT,
+    LTT_EVENT_IRQ_ENTRY,
+    LTT_EVENT_IRQ_EXIT,
+    LTT_EVENT_SCHEDCHANGE,
+    LTT_EVENT_FORK,
+    LTT_EVENT_EXIT,
+    LTT_EVENT_FREE,
+    LTT_EVENT_EXEC;
+
+/* Fields Quarks */
+
+extern GQuark 
+    LTT_FIELD_SYSCALL_ID,
+    LTT_FIELD_TRAP_ID,
+    LTT_FIELD_IRQ_ID,
+    LTT_FIELD_OUT,
+    LTT_FIELD_IN,
+    LTT_FIELD_OUT_STATE,
+    LTT_FIELD_PARENT_PID,
+    LTT_FIELD_CHILD_PID,
+    LTT_FIELD_PID,
+    LTT_FIELD_NAME;
+
+extern GQuark LTT_EVENT_SYSCALL_ENTRY;
+
+typedef struct _LttvTracesetState LttvTracesetState;
+typedef struct _LttvTracesetStateClass LttvTracesetStateClass;
+
+typedef struct _LttvTraceState LttvTraceState;
+typedef struct _LttvTraceStateClass LttvTraceStateClass;
+
+typedef struct _LttvTracefileState LttvTracefileState;
+typedef struct _LttvTracefileStateClass LttvTracefileStateClass;
+
+gint lttv_state_hook_add_event_hooks(void *hook_data, void *call_data);
+void lttv_state_add_event_hooks(LttvTracesetState *self);
+
+gint lttv_state_hook_remove_event_hooks(void *hook_data, void *call_data);
+void lttv_state_remove_event_hooks(LttvTracesetState *self);
+
+void lttv_state_save_add_event_hooks(LttvTracesetState *self);
+// Hook wrapper. call_data is a trace context.
+gint lttv_state_save_hook_add_event_hooks(void *hook_data, void *call_data);
+
+void lttv_state_save_remove_event_hooks(LttvTracesetState *self);
+// Hook wrapper. call_data is a trace context.
+gint lttv_state_save_hook_remove_event_hooks(void *hook_data, void *call_data);
+
+void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t);
+
+/* The LttvProcessState structure defines the current state for each process.
+   A process can make system calls (in some rare cases nested) and receive
+   interrupts/faults. For instance, a process may issue a system call,
+   generate a page fault while reading an argument from user space, and
+   get caught by an interrupt. To represent these nested states, an
+   execution mode stack is maintained. The stack bottom is normal user mode 
+   and the top of stack is the current execution mode.
+
+   The execution mode stack tells about the process status, execution mode and
+   submode (interrupt, system call or IRQ number). All these could be 
+   defined as enumerations but may need extensions (e.g. new process state). 
+   GQuark are thus used. They are as easy to manipulate as integers but have
+   a string associated, just like enumerations.
+
+   The execution mode is one of "user mode", "kernel thread", "system call",
+   "interrupt request", "fault". */
+
+typedef GQuark LttvExecutionMode;
+
+extern LttvExecutionMode
+  LTTV_STATE_USER_MODE,
+  LTTV_STATE_SYSCALL,
+  LTTV_STATE_TRAP,
+  LTTV_STATE_IRQ,
+  LTTV_STATE_MODE_UNKNOWN;
+
+
+/* The submode number depends on the execution mode. For user mode or kernel
+   thread, which are the normal mode (execution mode stack bottom), 
+   it is set to "none". For interrupt requests, faults and system calls, 
+   it is set respectively to the interrupt name (e.g. "timer"), fault name 
+   (e.g. "page fault"), and system call name (e.g. "select"). */
+typedef GQuark LttvExecutionSubmode;
+
+extern LttvExecutionSubmode
+  LTTV_STATE_SUBMODE_NONE,
+  LTTV_STATE_SUBMODE_UNKNOWN;
+
+/* The process status is one of "running", "wait-cpu" (runnable), or "wait-*"
+   where "*" describes the resource waited for (e.g. timer, process, 
+   disk...). */
+
+typedef GQuark LttvProcessStatus;
+
+extern LttvProcessStatus
+  LTTV_STATE_UNNAMED,
+  LTTV_STATE_WAIT_FORK,
+  LTTV_STATE_WAIT_CPU,
+  LTTV_STATE_EXIT,
+  LTTV_STATE_ZOMBIE,
+  LTTV_STATE_WAIT,
+  LTTV_STATE_RUN,
+  LTTV_STATE_DEAD;
+
+
+typedef struct _LttvExecutionState {
+  LttvExecutionMode t;
+  LttvExecutionSubmode n;
+  LttTime entry;
+  LttTime change;
+  LttvProcessStatus s;
+} LttvExecutionState;
+
+
+typedef struct _LttvProcessState {
+  guint pid;
+  guint ppid;
+  LttTime creation_time;
+  LttTime insertion_time;
+  GQuark name;
+  GQuark pid_time;
+  GArray *execution_stack;         /* Array of LttvExecutionState */
+  LttvExecutionState *state;       /* Top of interrupt stack */
+      /* WARNING : each time the execution_stack size is modified, the state
+       * must be reget : g_array_set_size can have to move the array.
+       * (Mathieu) */
+  guint cpu;                /* CPU where process is scheduled (being either in
+                               the active or inactive runqueue)*/
+//  guint  last_tracefile_index;    /* index in the trace for cpu tracefile */
+  /* opened file descriptors, address map?... */
+} LttvProcessState;
+
+#define ANY_CPU 0 /* For clarity sake : a call to lttv_state_find_process for
+                     a PID != 0 will search on any cpu automatically. */
+
+LttvProcessState *
+lttv_state_find_process(LttvTraceState *ts, guint cpu, guint pid);
+
+LttvProcessState *
+lttv_state_find_process_or_create(LttvTraceState *ts, guint cpu, guint pid,
+    LttTime *timestamp);
+
+LttvProcessState *
+lttv_state_create_process(LttvTraceState *ts, LttvProcessState *parent, 
+    guint cpu, guint pid, const LttTime *timestamp);
+
+void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp);
+
+/* The LttvTracesetState, LttvTraceState and LttvTracefileState types
+   inherit from the corresponding Context objects defined in processTrace. */
+
+#define LTTV_TRACESET_STATE_TYPE  (lttv_traceset_state_get_type ())
+#define LTTV_TRACESET_STATE(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATE_TYPE, LttvTracesetState))
+#define LTTV_TRACESET_STATE_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass))
+#define LTTV_IS_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATE_TYPE))
+#define LTTV_IS_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATE_TYPE))
+#define LTTV_TRACESET_STATE_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass))
+
+struct _LttvTracesetState {
+  LttvTracesetContext parent;
+};
+
+struct _LttvTracesetStateClass {
+  LttvTracesetContextClass parent;
+};
+
+GType lttv_traceset_state_get_type (void);
+
+
+#define LTTV_TRACE_STATE_TYPE  (lttv_trace_state_get_type ())
+#define LTTV_TRACE_STATE(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATE_TYPE, LttvTraceState))
+#define LTTV_TRACE_STATE_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass))
+#define LTTV_IS_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATE_TYPE))
+#define LTTV_IS_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATE_TYPE))
+#define LTTV_TRACE_STATE_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass))
+
+struct _LttvTraceState {
+  LttvTraceContext parent;
+
+  GHashTable *processes;  /* LttvProcessState objects indexed by pid and
+                             last_cpu */
+  guint nb_event, save_interval;
+  /* Block/char devices, locks, memory pages... */
+  GQuark *eventtype_names;
+  GQuark *syscall_names;
+  GQuark *trap_names;
+  GQuark *irq_names;
+  LttTime *max_time_state_recomputed_in_seek;
+
+  /* Array of per cpu running process */
+  LttvProcessState **running_process;
+  
+};
+
+struct _LttvTraceStateClass {
+  LttvTraceContextClass parent;
+
+  void (*state_save) (LttvTraceState *self, LttvAttribute *container);
+  void (*state_restore) (LttvTraceState *self, LttvAttribute *container);
+  void (*state_saved_free) (LttvTraceState *self, LttvAttribute *container);
+};
+
+GType lttv_trace_state_get_type (void);
+
+void lttv_state_save(LttvTraceState *self, LttvAttribute *container);
+
+void lttv_state_restore(LttvTraceState *self, LttvAttribute *container);
+
+void lttv_state_state_saved_free(LttvTraceState *self, 
+    LttvAttribute *container);
+
+
+#define LTTV_TRACEFILE_STATE_TYPE  (lttv_tracefile_state_get_type ())
+#define LTTV_TRACEFILE_STATE(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileState))
+#define LTTV_TRACEFILE_STATE_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass))
+#define LTTV_IS_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATE_TYPE))
+#define LTTV_IS_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATE_TYPE))
+#define LTTV_TRACEFILE_STATE_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass))
+
+struct _LttvTracefileState {
+  LttvTracefileContext parent;
+
+  //LttvProcessState *process;
+  GQuark tracefile_name;
+//  guint saved_position;
+};
+
+struct _LttvTracefileStateClass {
+  LttvTracefileContextClass parent;
+};
+
+GType lttv_tracefile_state_get_type (void);
+
+
+#endif // STATE_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/stats.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/stats.c
new file mode 100644 (file)
index 0000000..6416e30
--- /dev/null
@@ -0,0 +1,1085 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <lttv/module.h>
+#include <lttv/stats.h>
+#include <lttv/lttv.h>
+#include <lttv/attribute.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+
+#define BUF_SIZE 256
+
+GQuark
+  LTTV_STATS_PROCESS_UNKNOWN,
+  LTTV_STATS_PROCESSES,
+  LTTV_STATS_CPU,
+  LTTV_STATS_MODE_TYPES,
+  LTTV_STATS_MODES,
+  LTTV_STATS_SUBMODES,
+  LTTV_STATS_EVENT_TYPES,
+  LTTV_STATS_CPU_TIME,
+  LTTV_STATS_ELAPSED_TIME,
+  LTTV_STATS_EVENTS,
+  LTTV_STATS_EVENTS_COUNT,
+  LTTV_STATS_USE_COUNT,
+  LTTV_STATS,
+  LTTV_STATS_TRACEFILES,
+  LTTV_STATS_SUMMED,
+  LTTV_STATS_BEFORE_HOOKS,
+  LTTV_STATS_AFTER_HOOKS;
+
+static void
+find_event_tree(LttvTracefileStats *tfcs, GQuark pid_time, GQuark cpu,
+    GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, 
+    LttvAttribute **event_types_tree);
+
+
+static void lttv_stats_init(LttvTracesetStats *self)
+{
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTraceStats *tcs;
+
+  LttvTracefileContext *tfc;
+
+  LttvTracefileContext **tfs;
+  LttvTracefileStats *tfcs;
+  
+  LttTime timestamp = {0,0};
+
+  LttvAttributeValue v;
+
+  LttvAttribute
+    *stats_tree,
+    *tracefiles_stats;
+
+  LttvTraceset *ts = self->parent.parent.ts;
+
+  self->stats = lttv_attribute_find_subdir(
+                      lttv_traceset_attribute(self->parent.parent.ts),
+                      LTTV_STATS);
+  lttv_attribute_find(lttv_traceset_attribute(self->parent.parent.ts),
+                      LTTV_STATS_USE_COUNT, 
+                      LTTV_UINT, &v);
+
+  (*(v.v_uint))++;
+  if(*(v.v_uint) == 1) { 
+    g_assert(lttv_attribute_get_number(self->stats) == 0);
+  }
+
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->parent.parent.traces[i];
+    tcs = LTTV_TRACE_STATS(tc);
+
+    tcs->stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS);
+    tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a, 
+          LTTV_STATS_TRACEFILES);
+    lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT, 
+        LTTV_UINT, &v);
+
+    (*(v.v_uint))++;
+    if(*(v.v_uint) == 1) { 
+      g_assert(lttv_attribute_get_number(tcs->stats) == 0);
+    }
+
+    nb_tracefile = tc->tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = &g_array_index(tc->tracefiles,
+                      LttvTracefileContext*, j);
+      tfcs = LTTV_TRACEFILE_STATS(*tfs);
+      tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats, 
+          ltt_tracefile_long_name(tfcs->parent.parent.tf));
+      find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
+          ltt_tracefile_long_name(tfcs->parent.parent.tf),
+          LTTV_STATE_MODE_UNKNOWN, 
+          LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
+          &tfcs->current_event_types_tree);
+    }
+  }
+
+}
+
+static void lttv_stats_fini(LttvTracesetStats *self)
+{
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceset *ts;
+
+  LttvTraceContext *tc;
+
+  LttvTraceStats *tcs;
+
+  LttvTracefileContext *tfc;
+
+  LttvTracefileStats *tfcs;
+  
+  LttTime timestamp = {0,0};
+
+  LttvAttributeValue v;
+
+  LttvAttribute *tracefiles_stats;
+
+  lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT, 
+        LTTV_UINT, &v);
+  (*(v.v_uint))--;
+
+  if(*(v.v_uint) == 0) {
+    lttv_attribute_remove_by_name(self->parent.parent.ts_a, LTTV_STATS);
+  }
+  self->stats = NULL;
+
+  ts = self->parent.parent.ts;
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)(tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]));
+
+    lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT, 
+        LTTV_UINT, &v);
+    (*(v.v_uint))--;
+
+    if(*(v.v_uint) == 0) { 
+      lttv_attribute_remove_by_name(tcs->parent.parent.t_a,LTTV_STATS);
+      tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a, 
+          LTTV_STATS_TRACEFILES);
+      lttv_attribute_remove_by_name(tcs->parent.parent.t_a,
+          LTTV_STATS_TRACEFILES);
+    }
+    tcs->stats = NULL;
+
+    nb_tracefile = tc->tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfc = g_array_index(tc->tracefiles,
+                                  LttvTracefileContext*, j);
+      tfcs = (LttvTracefileStats *)tfc;
+      tfcs->stats = NULL;
+      tfcs->current_events_tree = NULL;
+      tfcs->current_event_types_tree = NULL;
+    }
+  }
+}
+
+
+void lttv_stats_reset(LttvTracesetStats *self)
+{
+  lttv_stats_fini(self);
+  lttv_stats_init(self);
+}
+
+
+
+static void
+init(LttvTracesetStats *self, LttvTraceset *ts)
+{
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
+      init((LttvTracesetContext *)self, ts);
+  
+  lttv_stats_init(self);
+}
+
+
+static void
+fini(LttvTracesetStats *self)
+{
+  lttv_stats_fini(self);
+
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
+      fini((LttvTracesetContext *)self);
+}
+
+
+static LttvTracesetContext *
+new_traceset_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL));
+}
+
+
+static LttvTraceContext * 
+new_trace_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL));
+}
+
+
+static LttvTracefileContext *
+new_tracefile_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL));
+}
+
+
+static void
+traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+traceset_stats_finalize (LttvTracesetStats *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+traceset_stats_class_init (LttvTracesetContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize;
+  klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
+  klass->fini = (void (*)(LttvTracesetContext *self))fini;
+  klass->new_traceset_context = new_traceset_context;
+  klass->new_trace_context = new_trace_context;
+  klass->new_tracefile_context = new_tracefile_context;
+}
+
+
+GType 
+lttv_traceset_stats_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracesetStatsClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) traceset_stats_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracesetStats),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) traceset_stats_instance_init,    /* instance_init */
+      NULL    /* Value handling */
+    };
+
+    type = g_type_register_static (LTTV_TRACESET_STATE_TYPE,
+                                   "LttvTracesetStatsType", 
+                                   &info, 0);
+  }
+  return type;
+}
+
+
+static void
+trace_stats_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+trace_stats_finalize (LttvTraceStats *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+trace_stats_class_init (LttvTraceContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize;
+}
+
+
+GType 
+lttv_trace_stats_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTraceStatsClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) trace_stats_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTraceStats),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) trace_stats_instance_init,    /* instance_init */
+      NULL    /* Value handling */
+    };
+
+    type = g_type_register_static (LTTV_TRACE_STATE_TYPE, 
+        "LttvTraceStatsType", &info, 0);
+  }
+  return type;
+}
+
+
+static void
+tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+tracefile_stats_finalize (LttvTracefileStats *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+tracefile_stats_class_init (LttvTracefileStatsClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize;
+}
+
+
+GType 
+lttv_tracefile_stats_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracefileStatsClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) tracefile_stats_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracefileStats),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) tracefile_stats_instance_init,    /* instance_init */
+      NULL    /* Value handling */
+    };
+
+    type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE, 
+        "LttvTracefileStatsType", &info, 0);
+  }
+  return type;
+}
+
+
+static void
+find_event_tree(LttvTracefileStats *tfcs,
+                GQuark pid_time,
+                GQuark cpu,
+                GQuark mode,
+                GQuark sub_mode,
+                LttvAttribute **events_tree, 
+                LttvAttribute **event_types_tree)
+{
+  LttvAttribute *a;
+
+  LttvTraceStats *tcs = (LttvTraceStats*)tfcs->parent.parent.t_context;
+  a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES);
+  a = lttv_attribute_find_subdir(a, pid_time);
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU);
+  a = lttv_attribute_find_subdir(a, cpu);
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES);
+  a = lttv_attribute_find_subdir(a, mode);
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES);
+  a = lttv_attribute_find_subdir(a, sub_mode);
+  *events_tree = a;
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES);
+  *event_types_tree = a;
+}
+
+
+static void update_event_tree(LttvTracefileStats *tfcs) 
+{
+  LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
+  guint cpu = ltt_tracefile_num(tfcs->parent.parent.tf);
+  LttvProcessState *process = ts->running_process[cpu];
+  LttvExecutionState *es = process->state;
+
+  find_event_tree(tfcs, process->pid_time,
+      ltt_tracefile_long_name(tfcs->parent.parent.tf), 
+      es->t, es->n, &(tfcs->current_events_tree), 
+      &(tfcs->current_event_types_tree));
+}
+
+
+static void mode_change(LttvTracefileStats *tfcs)
+{
+  LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
+  guint cpu = ltt_tracefile_num(tfcs->parent.parent.tf);
+  LttvProcessState *process = ts->running_process[cpu];
+  LttvAttributeValue cpu_time; 
+
+  LttTime delta;
+
+  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, 
+      LTTV_TIME, &cpu_time);
+  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
+      process->state->change);
+  *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
+}
+
+
+static void mode_end(LttvTracefileStats *tfcs)
+{
+  LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
+  guint cpu = ltt_tracefile_num(tfcs->parent.parent.tf);
+  LttvProcessState *process = ts->running_process[cpu];
+  LttvAttributeValue elapsed_time, cpu_time; 
+
+  LttTime delta;
+
+  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME, 
+      LTTV_TIME, &elapsed_time);
+  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
+      process->state->entry);
+  *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
+
+  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, 
+      LTTV_TIME, &cpu_time);
+  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
+      process->state->change);
+  *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
+}
+
+
+static gboolean before_syscall_entry(void *hook_data, void *call_data)
+{
+  mode_change((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+static gboolean after_syscall_entry(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_syscall_exit(void *hook_data, void *call_data)
+{
+  mode_end((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+static gboolean after_syscall_exit(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_trap_entry(void *hook_data, void *call_data)
+{
+  mode_change((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+static gboolean after_trap_entry(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_trap_exit(void *hook_data, void *call_data)
+{
+  mode_end((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean after_trap_exit(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_irq_entry(void *hook_data, void *call_data)
+{
+  mode_change((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean after_irq_entry(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_irq_exit(void *hook_data, void *call_data)
+{
+  mode_end((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean after_irq_exit(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_schedchange(void *hook_data, void *call_data)
+{
+  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
+
+  LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
+
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+
+  guint pid_in, pid_out;
+    
+  gint state_out;
+
+  LttvProcessState *process;
+
+  pid_out = ltt_event_get_unsigned(e, thf->f1);
+  pid_in = ltt_event_get_unsigned(e, thf->f2);
+  state_out = ltt_event_get_int(e, thf->f3);
+
+  /* compute the time for the process to schedule out */
+
+  mode_change(tfcs);
+
+  /* get the information for the process scheduled in */
+
+  process = lttv_state_find_process_or_create(ts, 
+      ANY_CPU, pid_in, &tfcs->parent.parent.timestamp);
+
+  find_event_tree(tfcs, process->pid_time,
+      ltt_tracefile_long_name(tfcs->parent.parent.tf), 
+      process->state->t, process->state->n, &(tfcs->current_events_tree), 
+      &(tfcs->current_event_types_tree));
+
+  /* compute the time waiting for the process to schedule in */
+
+  mode_change(tfcs);
+  return FALSE;
+}
+
+
+gboolean process_fork(void *hook_data, void *call_data)
+{
+  /* nothing to do for now */
+  return FALSE;
+}
+
+
+gboolean process_exit(void *hook_data, void *call_data)
+{
+  /* We should probably exit all modes here or we could do that at 
+     schedule out. */
+  return FALSE;
+}
+
+gboolean process_free(void *hook_data, void *call_data)
+{
+  return FALSE;
+}
+
+gboolean every_event(void *hook_data, void *call_data)
+{
+  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+
+  LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
+
+  LttvAttributeValue v;
+
+  /* The current branch corresponds to the tracefile/process/interrupt state.
+     Statistics are added within it, to count the number of events of this
+     type occuring in this context. A quark has been pre-allocated for each
+     event type and is used as name. */
+
+  lttv_attribute_find(tfcs->current_event_types_tree, 
+      ltt_eventtype_name(ltt_event_eventtype(e)), 
+      LTTV_UINT, &v);
+  (*(v.v_uint))++;
+  return FALSE;
+}
+
+
+void
+lttv_stats_sum_trace(LttvTraceStats *self)
+{
+  LttvAttribute *sum_container = self->stats;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  unsigned sum;
+
+  int i, j, k, l, m, nb_process, nb_cpu, nb_mode_type, nb_submode,
+      nb_event_type;
+
+  LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
+      *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
+      *submode_tree, *event_types_tree, *mode_events_tree,
+      *cpu_events_tree, *process_modes_tree, *trace_cpu_tree, 
+      *trace_modes_tree;
+
+  main_tree = sum_container;
+
+  lttv_attribute_find(sum_container,
+                      LTTV_STATS_SUMMED, 
+                      LTTV_UINT, &value);
+  if(*(value.v_uint) != 0) return;
+  *(value.v_uint) = 1;
+
+  processes_tree = lttv_attribute_find_subdir(main_tree, 
+                                              LTTV_STATS_PROCESSES);
+  trace_modes_tree = lttv_attribute_find_subdir(main_tree,
+                                                LTTV_STATS_MODES);
+  nb_process = lttv_attribute_get_number(processes_tree);
+
+  for(i = 0 ; i < nb_process ; i++) {
+    type = lttv_attribute_get(processes_tree, i, &name, &value);
+    process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+    cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
+    process_modes_tree = lttv_attribute_find_subdir(process_tree,
+        LTTV_STATS_MODES);
+    nb_cpu = lttv_attribute_get_number(cpus_tree);
+
+    for(j = 0 ; j < nb_cpu ; j++) {
+      type = lttv_attribute_get(cpus_tree, j, &name, &value);
+      cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+      mode_types_tree = lttv_attribute_find_subdir(cpu_tree, 
+          LTTV_STATS_MODE_TYPES);
+      cpu_events_tree = lttv_attribute_find_subdir(cpu_tree,
+          LTTV_STATS_EVENTS);
+      trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU);
+      trace_cpu_tree = lttv_attribute_find_subdir(trace_cpu_tree, name);
+      nb_mode_type = lttv_attribute_get_number(mode_types_tree);
+
+      for(k = 0 ; k < nb_mode_type ; k++) {
+        type = lttv_attribute_get(mode_types_tree, k, &name, &value);
+        mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+        submodes_tree = lttv_attribute_find_subdir(mode_tree, 
+            LTTV_STATS_SUBMODES);
+        mode_events_tree = lttv_attribute_find_subdir(mode_tree,
+            LTTV_STATS_EVENTS);
+        nb_submode = lttv_attribute_get_number(submodes_tree);
+
+        for(l = 0 ; l < nb_submode ; l++) {
+          type = lttv_attribute_get(submodes_tree, l, &name, &value);
+          submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+          event_types_tree = lttv_attribute_find_subdir(submode_tree, 
+            LTTV_STATS_EVENT_TYPES);
+          nb_event_type = lttv_attribute_get_number(event_types_tree);
+
+          sum = 0;
+          for(m = 0 ; m < nb_event_type ; m++) {
+            type = lttv_attribute_get(event_types_tree, m, &name, &value);
+            sum += *(value.v_uint);
+          }
+          lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT, 
+              LTTV_UINT, &value);
+          *(value.v_uint) = sum;
+          lttv_attribute_recursive_add(mode_events_tree, submode_tree);
+        }
+        lttv_attribute_recursive_add(cpu_events_tree, mode_events_tree);
+      }
+      lttv_attribute_recursive_add(process_modes_tree, cpu_tree);
+      lttv_attribute_recursive_add(trace_cpu_tree, cpu_tree);
+    }
+    lttv_attribute_recursive_add(trace_modes_tree, process_modes_tree);
+  }
+}
+
+
+gboolean lttv_stats_sum_traceset_hook(void *hook_data, void *call_data)
+{
+  lttv_stats_sum_traceset((LttvTracesetStats *)call_data);
+  return 0;
+}
+
+void
+lttv_stats_sum_traceset(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+  LttvAttribute *sum_container = self->stats;
+
+  LttvTraceStats *tcs;
+
+  int i, nb_trace;
+
+  LttvAttribute *main_tree, *trace_modes_tree, *traceset_modes_tree;
+
+  LttvAttributeValue value;
+
+  lttv_attribute_find(sum_container, LTTV_STATS_SUMMED, 
+      LTTV_UINT, &value);
+  if(*(value.v_uint) != 0) return;
+  *(value.v_uint) = 1;
+
+  traceset_modes_tree = lttv_attribute_find_subdir(sum_container, 
+      LTTV_STATS_MODES);
+  nb_trace = lttv_traceset_number(traceset);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)(self->parent.parent.traces[i]);
+    lttv_stats_sum_trace(tcs);
+    main_tree = tcs->stats;
+    trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES);
+    lttv_attribute_recursive_add(traceset_modes_tree, trace_modes_tree);
+  }
+}
+
+
+// Hook wrapper. call_data is a traceset context.
+gboolean lttv_stats_hook_add_event_hooks(void *hook_data, void *call_data)
+{
+   LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
+
+   lttv_stats_add_event_hooks(tss);
+
+   return 0;
+}
+
+void lttv_stats_add_event_hooks(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+
+  guint i, j, k, l, nb_trace, nb_tracefile;
+
+  LttvTraceStats *ts;
+
+  LttvTracefileStats *tfs;
+
+  GArray *hooks, *before_hooks, *after_hooks;
+
+  LttvTraceHook *hook;
+
+  LttvTraceHookByFacility *thf;
+
+  LttvAttributeValue val;
+
+  gint ret;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceStats *)self->parent.parent.traces[i];
+
+    /* Find the eventtype id for the following events and register the
+       associated by id hooks. */
+
+    hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 7);
+    g_array_set_size(hooks, 7);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+        LTT_FIELD_SYSCALL_ID, 0, 0,
+        before_syscall_entry, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 0));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_EXIT,
+        0, 0, 0,
+        before_syscall_exit, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 1));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
+        LTT_FIELD_TRAP_ID, 0, 0,
+        before_trap_entry, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 2));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
+        0, 0, 0,
+        before_trap_exit, NULL,
+        &g_array_index(hooks, LttvTraceHook, 3));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
+        LTT_FIELD_IRQ_ID, 0, 0,
+        before_irq_entry, NULL,
+        &g_array_index(hooks, LttvTraceHook, 4));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
+        0, 0, 0,
+        before_irq_exit, NULL,
+        &g_array_index(hooks, LttvTraceHook, 5));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
+        LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
+        before_schedchange, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 6));
+    g_assert(!ret);
+
+    before_hooks = hooks;
+
+    hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 9);
+    g_array_set_size(hooks, 9);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+        LTT_FIELD_SYSCALL_ID, 0, 0,
+        after_syscall_entry, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 0));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_EXIT,
+        0, 0, 0,
+        after_syscall_exit, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 1));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY, 
+        LTT_FIELD_TRAP_ID, 0, 0,
+        after_trap_entry, NULL,
+        &g_array_index(hooks, LttvTraceHook, 2));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
+        0, 0, 0,
+        after_trap_exit, NULL,
+        &g_array_index(hooks, LttvTraceHook, 3));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY, 
+        LTT_FIELD_IRQ_ID, 0, 0,
+        after_irq_entry, NULL,
+        &g_array_index(hooks, LttvTraceHook, 4));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
+        0, 0, 0,
+        after_irq_exit, NULL,
+        &g_array_index(hooks, LttvTraceHook, 5));
+    g_assert(!ret);
+
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_FORK, 
+        LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
+        process_fork, NULL, 
+        &g_array_index(hooks, LttvTraceHook, 6));
+    g_assert(!ret);
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
+        LTT_FIELD_PID, 0, 0,
+        process_exit, NULL,
+        &g_array_index(hooks, LttvTraceHook, 7));
+    g_assert(!ret);
+    
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
+        LTT_FIELD_PID, 0, 0,
+        process_free, NULL,
+        &g_array_index(hooks, LttvTraceHook, 8));
+    g_assert(!ret);
+
+
+    after_hooks = hooks;
+
+    /* Add these hooks to each event_by_id hooks list */
+
+    nb_tracefile = ts->parent.parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
+                                  LttvTracefileContext*, j));
+      lttv_hooks_add(tfs->parent.parent.event, every_event, NULL, 
+                     LTTV_PRIO_DEFAULT);
+
+      for(k = 0 ; k < before_hooks->len ; k++) {
+        hook = &g_array_index(before_hooks, LttvTraceHook, k);
+        for(l = 0; l<hook->fac_list->len;l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_add(
+              lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
+              thf->h,
+              thf,
+              LTTV_PRIO_STATS_BEFORE_STATE);
+        }
+      }
+      for(k = 0 ; k < after_hooks->len ; k++) {
+        hook = &g_array_index(after_hooks, LttvTraceHook, k);
+        for(l = 0; l<hook->fac_list->len;l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_add(
+              lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
+              thf->h,
+              thf,
+              LTTV_PRIO_STATS_AFTER_STATE);
+        }
+      }
+    }
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
+        LTTV_POINTER, &val);
+    *(val.v_pointer) = before_hooks;
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, 
+        LTTV_POINTER, &val);
+    *(val.v_pointer) = after_hooks;
+  }
+}
+
+// Hook wrapper. call_data is a traceset context.
+gboolean lttv_stats_hook_remove_event_hooks(void *hook_data, void *call_data)
+{
+   LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
+
+   lttv_stats_remove_event_hooks(tss);
+
+   return 0;
+}
+
+void lttv_stats_remove_event_hooks(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+
+  guint i, j, k, l, nb_trace, nb_tracefile;
+
+  LttvTraceStats *ts;
+
+  LttvTracefileStats *tfs;
+
+  void *hook_data;
+
+  GArray *before_hooks, *after_hooks;
+
+  LttvTraceHook *hook;
+  
+  LttvTraceHookByFacility *thf;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceStats*)self->parent.parent.traces[i];
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
+        LTTV_POINTER, &val);
+    before_hooks = *(val.v_pointer);
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, 
+        LTTV_POINTER, &val);
+    after_hooks = *(val.v_pointer);
+
+    /* Remove these hooks from each event_by_id hooks list */
+
+    nb_tracefile = ts->parent.parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
+                                  LttvTracefileContext*, j));
+      lttv_hooks_remove_data(tfs->parent.parent.event, every_event, 
+          NULL);
+
+      for(k = 0 ; k < before_hooks->len ; k++) {
+        hook = &g_array_index(before_hooks, LttvTraceHook, k);
+        for(l = 0 ; l < hook->fac_list->len ; l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_remove_data(
+              lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
+              thf->h,
+              thf);
+        }
+      }
+      for(k = 0 ; k < after_hooks->len ; k++) {
+        hook = &g_array_index(after_hooks, LttvTraceHook, k);
+        for(l = 0 ; l < hook->fac_list->len ; l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_remove_data(
+              lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
+              thf->h,
+              thf);
+        }
+      }
+    }
+    g_debug("lttv_stats_remove_event_hooks()");
+    g_array_free(before_hooks, TRUE);
+    g_array_free(after_hooks, TRUE);
+  }
+}
+
+
+static void module_init()
+{
+  LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process");
+  LTTV_STATS_PROCESSES = g_quark_from_string("processes");
+  LTTV_STATS_CPU = g_quark_from_string("cpu");
+  LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types");
+  LTTV_STATS_MODES = g_quark_from_string("modes");
+  LTTV_STATS_SUBMODES = g_quark_from_string("submodes");
+  LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types");
+  LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time");
+  LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time");
+  LTTV_STATS_EVENTS = g_quark_from_string("events");
+  LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count");
+  LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks");
+  LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks");
+  LTTV_STATS_USE_COUNT = g_quark_from_string("stats_use_count");
+  LTTV_STATS = g_quark_from_string("statistics");
+  LTTV_STATS_TRACEFILES = g_quark_from_string("tracefiles statistics");
+  LTTV_STATS_SUMMED = g_quark_from_string("statistics summed");
+}
+
+static void module_destroy() 
+{
+}
+
+
+LTTV_MODULE("stats", "Compute processes statistics", \
+    "Accumulate statistics for event types, processes and CPUs", \
+    module_init, module_destroy, "state");
+
+/* Change the places where stats are called (create/read/write stats)
+
+   Check for options in batchtest.c to reduce writing and see what tests are
+   best candidates for performance analysis. Once OK, commit, move to main
+   and run tests. Update the gui for statistics. */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/stats.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/stats.h
new file mode 100644 (file)
index 0000000..090cbe5
--- /dev/null
@@ -0,0 +1,237 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef STATS_H
+#define STATS_H
+
+#include <glib.h>
+#include <lttv/state.h>
+
+/* The statistics are for a complete time interval. These structures differ
+   from the system state since they relate to static components of the 
+   system (all processes which existed instead of just the currently 
+   existing processes). 
+
+   The basic attributes tree to gather for several different execution modes 
+   (e.g., user mode, syscall, irq), thereafter called the "events tree", 
+   contains the following attributes: the number of events of each type, 
+   the total number of events, the number of bytes written, the time spent 
+   executing, waiting for a resource, waiting for a cpu, and possibly many 
+   others. The name "facility-event_type" below is to be replaced
+   by specific event types (e.g., core-schedchange, code-syscall_entry...).
+
+   event_types/
+     "facility-event_type"
+   events_count
+   cpu_time
+   elapsed_time
+   wait_time
+   bytes_written
+   packets_sent
+   ...
+
+   The events for several different execution modes are joined together to 
+   form the "execution modes tree". The name "execution mode" is to be replaced
+   by "system call", "trap", "irq", "user mode" or "kernel thread".
+   The name "submode" is to be replaced by the specific system call, trap or
+   irq name. The "submode" is an empty string if none is applicable, which is
+   the case for "user mode" and "kernel thread".
+
+   An "events tree" for each "execution mode" contains the sum for all its 
+   different submodes. An "events tree" in the "execution modes tree" contains
+   the sum for all its different execution modes.
+
+   mode_types/
+     "execution mode"/
+       submodes/
+         "submode"/
+           Events Tree
+       events/
+         Event Tree
+   events/
+     Events Tree
+
+   Each trace set contains an "execution modes tree". While the traces
+   come from possibly different systems, which may differ in their system
+   calls..., most of the system calls will have the same name, even if their
+   actual internal numeric id differs. Categories such as cpu id and process
+   id are not kept since these are specific to each system. When several
+   traces are taken from the same system, these categories may make sense and
+   could eventually be considered.
+
+   Each trace contains a global "execution modes tree", one for each
+   cpu and process, and one for each process/cpu combination. The name
+   "cpu number" stands for the cpu identifier, and "process_id-start_time"
+   is a unique process identifier composed of the process id
+   (unique at any given time but which may be reused over time) concatenated
+   with the process start time.
+
+   modes/
+     Execution Modes Tree
+   cpu/
+     "cpu number"/
+       Execution Modes Tree
+   processes/
+     "process_id-start_time"/
+       exec_file_name
+       parent
+       start_time
+       end_time
+       modes/
+         Execution Modes Tree
+       cpu/
+         "cpu number"/
+           Execution Modes Tree
+
+   All the events and derived values (cpu, elapsed and wait time) are
+   added during the trace analysis in the relevant 
+   trace / processes / * / cpu / * / mode_types / * /submodes / * 
+   "events tree". To achieve this efficiently, each tracefile context 
+   contains a pointer to the current relevant "events tree" and "event_types" 
+   tree within it.
+
+   Once all the events are processed, the total number of events is computed
+   within each trace / processes / * / cpu / * / mode_types / * / submodes / *.
+   Then, the "events tree" are summed for all submodes within each mode type 
+   and for all mode types within a processes / * / cpu / * 
+   "execution modes tree".
+
+   Finally, the "execution modes trees" for all cpu within a process,
+   for all processes, and for all traces are computed. Separately,
+   the "execution modes tree" for each cpu but for all processes within a
+   trace are summed in the trace / cpu / * subtrees.
+
+ */
+
+
+/* The various statistics branch names are GQuarks. They are pre-computed for
+   easy and efficient access */
+
+#define LTTV_PRIO_STATS_BEFORE_STATE LTTV_PRIO_STATE-5
+#define LTTV_PRIO_STATS_AFTER_STATE LTTV_PRIO_STATE+5
+
+extern GQuark
+  LTTV_STATS_PROCESS_UNKNOWN,
+  LTTV_STATS_PROCESSES,
+  LTTV_STATS_CPU,
+  LTTV_STATS_MODE_TYPES,
+  LTTV_STATS_SUBMODES,
+  LTTV_STATS_EVENT_TYPES,
+  LTTV_STATS_CPU_TIME,
+  LTTV_STATS_ELAPSED_TIME,
+  LTTV_STATS_EVENTS,
+  LTTV_STATS_EVENTS_COUNT,
+  LTTV_STATS_BEFORE_HOOKS,
+  LTTV_STATS_AFTER_HOOKS;
+
+
+typedef struct _LttvTracesetStats LttvTracesetStats;
+typedef struct _LttvTracesetStatsClass LttvTracesetStatsClass;
+
+typedef struct _LttvTraceStats LttvTraceStats;
+typedef struct _LttvTraceStatsClass LttvTraceStatsClass;
+
+typedef struct _LttvTracefileStats LttvTracefileStats;
+typedef struct _LttvTracefileStatsClass LttvTracefileStatsClass;
+
+
+
+// Hook wrapper. call_data is a trace context.
+gboolean lttv_stats_hook_add_event_hooks(void *hook_data, void *call_data);
+void lttv_stats_add_event_hooks(LttvTracesetStats *self);
+
+// Hook wrapper. call_data is a trace context.
+gboolean lttv_stats_hook_remove_event_hooks(void *hook_data, void *call_data);
+void lttv_stats_remove_event_hooks(LttvTracesetStats *self);
+
+gboolean lttv_stats_sum_traceset_hook(void *hook_data, void *call_data);
+void lttv_stats_sum_traceset(LttvTracesetStats *self);
+
+void lttv_stats_sum_trace(LttvTraceStats *self);
+
+/* Reset all statistics containers */
+void lttv_stats_reset(LttvTracesetStats *self);
+
+
+/* The LttvTracesetStats, LttvTraceStats and LttvTracefileStats types
+   inherit from the corresponding State objects defined in state.h.. */
+
+#define LTTV_TRACESET_STATS_TYPE  (lttv_traceset_stats_get_type ())
+#define LTTV_TRACESET_STATS(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATS_TYPE, LttvTracesetStats))
+#define LTTV_TRACESET_STATS_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATS_TYPE, LttvTracesetStatsClass))
+#define LTTV_IS_TRACESET_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATS_TYPE))
+#define LTTV_IS_TRACESET_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATS_TYPE))
+#define LTTV_TRACESET_STATS_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATS_TYPE, LttvTracesetStatsClass))
+
+struct _LttvTracesetStats {
+  LttvTracesetState parent;
+
+  LttvAttribute *stats;
+};
+
+struct _LttvTracesetStatsClass {
+  LttvTracesetStateClass parent;
+};
+
+GType lttv_traceset_stats_get_type (void);
+
+
+#define LTTV_TRACE_STATS_TYPE  (lttv_trace_stats_get_type ())
+#define LTTV_TRACE_STATS(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATS_TYPE, LttvTraceStats))
+#define LTTV_TRACE_STATS_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATS_TYPE, LttvTraceStatsClass))
+#define LTTV_IS_TRACE_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATS_TYPE))
+#define LTTV_IS_TRACE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATS_TYPE))
+#define LTTV_TRACE_STATS_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATS_TYPE, LttvTraceStatsClass))
+
+struct _LttvTraceStats {
+  LttvTraceState parent;
+
+  LttvAttribute *stats;
+};
+
+struct _LttvTraceStatsClass {
+  LttvTraceStateClass parent;
+};
+
+GType lttv_trace_stats_get_type (void);
+
+
+#define LTTV_TRACEFILE_STATS_TYPE  (lttv_tracefile_stats_get_type ())
+#define LTTV_TRACEFILE_STATS(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStats))
+#define LTTV_TRACEFILE_STATS_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStatsClass))
+#define LTTV_IS_TRACEFILE_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATS_TYPE))
+#define LTTV_IS_TRACEFILE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATS_TYPE))
+#define LTTV_TRACEFILE_STATS_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStatsClass))
+
+struct _LttvTracefileStats {
+  LttvTracefileState parent;
+
+  LttvAttribute *stats;
+  LttvAttribute *current_events_tree;
+  LttvAttribute *current_event_types_tree;
+};
+
+struct _LttvTracefileStatsClass {
+  LttvTracefileStateClass parent;
+};
+
+GType lttv_tracefile_stats_get_type (void);
+
+
+#endif // STATS_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/tracecontext.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/tracecontext.c
new file mode 100644 (file)
index 0000000..657664b
--- /dev/null
@@ -0,0 +1,1606 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <lttv/lttv.h>
+#include <lttv/tracecontext.h>
+#include <ltt/event.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/type.h>
+#include <lttv/filter.h>
+#include <errno.h>
+
+#define min(a,b) (((a)<(b))?(a):(b))
+
+
+gint compare_tracefile(gconstpointer a, gconstpointer b)
+{
+  gint comparison = 0;
+
+  const LttvTracefileContext *trace_a = (const LttvTracefileContext *)a;
+  const LttvTracefileContext *trace_b = (const LttvTracefileContext *)b;
+
+  if(likely(trace_a != trace_b)) {
+    comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp);
+    if(unlikely(comparison == 0)) {
+      if(trace_a->index < trace_b->index) comparison = -1;
+      else if(trace_a->index > trace_b->index) comparison = 1;
+      else if(trace_a->t_context->index < trace_b->t_context->index) 
+        comparison = -1;
+      else if(trace_a->t_context->index > trace_b->t_context->index)
+        comparison = 1;
+    }
+  }
+  return comparison;
+}
+
+typedef struct _LttvTracefileContextPosition {
+  LttEventPosition *event;
+  LttvTracefileContext *tfc;
+  gboolean used; /* Tells if the tfc is at end of traceset position */
+} LttvTracefileContextPosition;
+
+
+struct _LttvTracesetContextPosition {
+  GArray *tfcp;                      /* Array of LttvTracefileContextPosition */
+  LttTime timestamp;                 /* Current time at the saved position */ 
+                                     /* If ltt_time_infinite : no position is
+                                      * set, else, a position is set (may be end
+                                      * of trace, with ep->len == 0) */
+};
+
+void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
+{
+  LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
+}
+
+
+void lttv_context_fini(LttvTracesetContext *self)
+{
+  LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
+}
+
+
+LttvTracesetContext *
+lttv_context_new_traceset_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
+}
+
+
+
+
+LttvTraceContext * 
+lttv_context_new_trace_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
+}
+
+
+LttvTracefileContext *
+lttv_context_new_tracefile_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
+}
+
+/****************************************************************************
+ * lttv_traceset_context_compute_time_span
+ *
+ * Keep the time span is sync with on the fly addition and removal of traces
+ * in a trace set. It must be called each time a trace is added/removed from
+ * the traceset. It could be more efficient to call it only once a bunch
+ * of traces are loaded, but the calculation is not long, so it's not
+ * critical.
+ *
+ * Author : Xang Xiu Yang
+ ***************************************************************************/
+static void lttv_traceset_context_compute_time_span(
+                                          LttvTracesetContext *self,
+                                                                 TimeInterval *time_span)
+{
+  LttvTraceset * traceset = self->ts;
+  int numTraces = lttv_traceset_number(traceset);
+  int i;
+  LttTime s, e;
+  LttvTraceContext *tc;
+  LttTrace * trace;
+
+  time_span->start_time.tv_sec = 0;
+  time_span->start_time.tv_nsec = 0;
+  time_span->end_time.tv_sec = 0;
+  time_span->end_time.tv_nsec = 0;
+  
+  for(i=0; i<numTraces;i++){
+    tc = self->traces[i];
+    trace = tc->t;
+
+    ltt_trace_time_span_get(trace, &s, &e);
+    tc->time_span.start_time = s;
+    tc->time_span.end_time = e;
+
+    if(i==0){
+      time_span->start_time = s;
+      time_span->end_time   = e;
+    }else{
+      if(s.tv_sec < time_span->start_time.tv_sec 
+          || (s.tv_sec == time_span->start_time.tv_sec 
+               && s.tv_nsec < time_span->start_time.tv_nsec))
+             time_span->start_time = s;
+      if(e.tv_sec > time_span->end_time.tv_sec
+          || (e.tv_sec == time_span->end_time.tv_sec 
+               && e.tv_nsec > time_span->end_time.tv_nsec))
+        time_span->end_time = e;      
+    }
+  }
+}
+
+static void init_tracefile_context(LttTracefile *tracefile,
+                                    LttvTraceContext *tc)
+{
+  LttvTracefileContext *tfc;
+  LttvTracesetContext *tsc = tc->ts_context;
+  
+  tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->new_tracefile_context(tsc);
+
+  tfc->index = tc->tracefiles->len;
+  tc->tracefiles = g_array_append_val(tc->tracefiles, tfc);
+
+  tfc->tf = tracefile;
+
+  tfc->t_context = tc;
+  tfc->event = lttv_hooks_new();
+  tfc->event_by_id = lttv_hooks_by_id_new();
+  tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+}
+
+
+static void
+init(LttvTracesetContext *self, LttvTraceset *ts)
+{
+  guint i, nb_trace;
+
+  LttvTraceContext *tc;
+
+  GData **tracefiles_groups;
+
+  struct compute_tracefile_group_args args;
+
+  nb_trace = lttv_traceset_number(ts);
+  self->ts = ts;
+  self->traces = g_new(LttvTraceContext *, nb_trace);
+  self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  self->ts_a = lttv_traceset_attribute(ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
+    self->traces[i] = tc;
+
+    tc->ts_context = self;
+    tc->index = i;
+    tc->vt = lttv_traceset_get(ts, i);
+    tc->t = lttv_trace(tc->vt);
+    tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    tc->t_a = lttv_trace_attribute(tc->vt);
+    tc->tracefiles = g_array_sized_new(FALSE, TRUE,
+                        sizeof(LttvTracefileContext*), 10);
+
+    tracefiles_groups = ltt_trace_get_tracefiles_groups(tc->t);
+    if(tracefiles_groups != NULL) {
+      args.func = (ForEachTraceFileFunc)init_tracefile_context;
+      args.func_args = tc;
+
+      g_datalist_foreach(tracefiles_groups, 
+                            (GDataForeachFunc)compute_tracefile_group,
+                            &args);
+    }
+      
+#if 0
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    tc->tracefiles = g_new(LttvTracefileContext *, nb_tracefile);
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
+      tc->tracefiles[j] = tfc;
+      tfc->index = j;
+
+      if(j < nb_control) {
+        tfc->control = TRUE;
+        tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
+      }
+      else {
+        tfc->control = FALSE;
+        tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
+      }
+
+      tfc->t_context = tc;
+      tfc->e = ltt_event_new();
+      tfc->event = lttv_hooks_new();
+      tfc->event_by_id = lttv_hooks_by_id_new();
+      tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    }
+#endif //0
+
+  }
+  self->sync_position = lttv_traceset_context_position_new(self);
+  self->pqueue = g_tree_new(compare_tracefile);
+  lttv_process_traceset_seek_time(self, ltt_time_zero);
+  lttv_traceset_context_compute_time_span(self, &self->time_span);
+
+}
+
+
+void fini(LttvTracesetContext *self)
+{
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTracefileContext **tfc;
+
+  LttvTraceset *ts = self->ts;
+
+  g_tree_destroy(self->pqueue);
+  g_object_unref(self->a);
+  lttv_traceset_context_position_destroy(self->sync_position);
+
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+
+    g_object_unref(tc->a);
+
+    nb_tracefile = tc->tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfc = &g_array_index(tc->tracefiles, LttvTracefileContext*, j);
+      lttv_hooks_destroy((*tfc)->event);
+      lttv_hooks_by_id_destroy((*tfc)->event_by_id);
+      g_object_unref((*tfc)->a);
+      g_object_unref(*tfc);
+    }
+    g_array_free(tc->tracefiles, TRUE);
+    g_object_unref(tc);
+  }
+  g_free(self->traces);
+}
+
+
+void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
+    LttvHooks *before_traceset,
+    LttvHooks *before_trace, 
+    LttvHooks *before_tracefile,
+    LttvHooks *event,
+    LttvHooksById *event_by_id)
+{
+  LttvTraceset *ts = self->ts;
+
+  guint i, nb_trace;
+
+  LttvTraceContext *tc;
+
+  lttv_hooks_call(before_traceset, self);
+
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+    lttv_trace_context_add_hooks(tc,
+                                 before_trace,
+                                 before_tracefile,
+                                 event,
+                                 event_by_id);
+  }
+}
+
+
+void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
+    LttvHooks *after_traceset,
+    LttvHooks *after_trace, 
+    LttvHooks *after_tracefile,
+    LttvHooks *event, 
+    LttvHooksById *event_by_id)
+{
+
+  LttvTraceset *ts = self->ts;
+
+  guint i, nb_trace;
+
+  LttvTraceContext *tc;
+
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+    lttv_trace_context_remove_hooks(tc,
+                                    after_trace,
+                                    after_tracefile,
+                                    event,
+                                    event_by_id);
+  }
+
+  lttv_hooks_call(after_traceset, self);
+
+
+}
+
+void lttv_trace_context_add_hooks(LttvTraceContext *self,
+    LttvHooks *before_trace, 
+    LttvHooks *before_tracefile,
+    LttvHooks *event, 
+    LttvHooksById *event_by_id)
+{
+  guint i, nb_tracefile;
+
+  LttvTracefileContext **tfc;
+
+  lttv_hooks_call(before_trace, self);
+
+  nb_tracefile = self->tracefiles->len;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i);
+    lttv_tracefile_context_add_hooks(*tfc,
+                                     before_tracefile,
+                                     event,
+                                     event_by_id);
+  }
+}
+
+
+
+void lttv_trace_context_remove_hooks(LttvTraceContext *self,
+    LttvHooks *after_trace, 
+    LttvHooks *after_tracefile,
+    LttvHooks *event, 
+    LttvHooksById *event_by_id)
+{
+  guint i, nb_tracefile;
+
+  LttvTracefileContext **tfc;
+
+  nb_tracefile = self->tracefiles->len;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i);
+    lttv_tracefile_context_remove_hooks(*tfc,
+                                        after_tracefile,
+                                        event,
+                                        event_by_id);
+  }
+
+  lttv_hooks_call(after_trace, self);
+}
+
+void lttv_tracefile_context_add_hooks(LttvTracefileContext *self,
+          LttvHooks *before_tracefile,
+          LttvHooks *event, 
+          LttvHooksById *event_by_id)
+{
+  guint i, index;
+
+  LttvHooks *hook;
+  
+  lttv_hooks_call(before_tracefile, self);
+  lttv_hooks_add_list(self->event, event);
+  if(event_by_id != NULL) {
+    for(i = 0; i < event_by_id->array->len; i++) {
+      index = g_array_index(event_by_id->array, guint, i);
+      hook = lttv_hooks_by_id_find(self->event_by_id, index);
+      lttv_hooks_add_list(hook, lttv_hooks_by_id_get(event_by_id, index));
+    }
+  }
+}
+
+void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self,
+           LttvHooks *after_tracefile,
+           LttvHooks *event, 
+           LttvHooksById *event_by_id)
+{
+  guint i, index;
+
+  LttvHooks *hook;
+  
+  lttv_hooks_remove_list(self->event, event);
+  if(event_by_id != NULL) {
+    for(i = 0; i < event_by_id->array->len; i++) {
+      index = g_array_index(event_by_id->array, guint, i);
+      hook = lttv_hooks_by_id_get(self->event_by_id, index);
+      if(hook != NULL)
+        lttv_hooks_remove_list(hook, lttv_hooks_by_id_get(event_by_id, index));
+    }
+  }
+
+  lttv_hooks_call(after_tracefile, self);
+}
+
+
+
+void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
+                                           unsigned i,
+                                           LttvHooks *event_by_id)
+{
+  LttvHooks * h;
+  h = lttv_hooks_by_id_find(tfc->event_by_id, i);
+  lttv_hooks_add_list(h, event_by_id);
+}
+
+void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
+                                              unsigned i)
+{
+  lttv_hooks_by_id_remove(tfc->event_by_id, i);
+}
+
+static LttvTracesetContext *
+new_traceset_context(LttvTracesetContext *self)
+{
+  return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
+}
+
+
+static LttvTraceContext * 
+new_trace_context(LttvTracesetContext *self)
+{
+  return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
+}
+
+
+static LttvTracefileContext *
+new_tracefile_context(LttvTracesetContext *self)
+{
+  return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
+}
+
+
+static void
+traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  /* Be careful of anything which would not work well with shallow copies */
+}
+
+
+static void
+traceset_context_finalize (LttvTracesetContext *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
+      ->finalize(G_OBJECT(self));
+}
+
+
+static void
+traceset_context_class_init (LttvTracesetContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
+  klass->init = init;
+  klass->fini = fini;
+  klass->new_traceset_context = new_traceset_context;
+  klass->new_trace_context = new_trace_context;
+  klass->new_tracefile_context = new_tracefile_context;
+}
+
+
+GType 
+lttv_traceset_context_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracesetContextClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) traceset_context_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracesetContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) traceset_context_instance_init, /* instance_init */
+      NULL    /* Value handling */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  /* Be careful of anything which would not work well with shallow copies */
+}
+
+
+static void
+trace_context_finalize (LttvTraceContext *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+trace_context_class_init (LttvTraceContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
+}
+
+
+GType 
+lttv_trace_context_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTraceContextClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) trace_context_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTraceContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) trace_context_instance_init,    /* instance_init */
+      NULL    /* Value handling */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  /* Be careful of anything which would not work well with shallow copies */
+}
+
+
+static void
+tracefile_context_finalize (LttvTracefileContext *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
+      ->finalize(G_OBJECT(self));
+}
+
+
+static void
+tracefile_context_class_init (LttvTracefileContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
+}
+
+
+GType 
+lttv_tracefile_context_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracefileContextClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) tracefile_context_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracefileContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) tracefile_context_instance_init,    /* instance_init */
+      NULL    /* Value handling */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+
+static gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
+  g_assert(key == value);
+  *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
+  return TRUE;
+}
+
+#ifdef DEBUG
+// Test to see if pqueue is traversed in the right order.
+static LttTime test_time;
+
+static gboolean test_tree(gpointer key, gpointer value, gpointer user_data) {
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)key;
+
+  g_debug("Tracefile name %s, time %lu.%lu, tfi %u, ti %u",
+      g_quark_to_string(ltt_tracefile_name(tfc->tf)),
+      tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec,
+      tfc->index, tfc->t_context->index);
+  
+  if(user_data != NULL) {
+    if(((LttvTracefileContext *)user_data) == (LttvTracefileContext *)value) {
+      g_assert(compare_tracefile(user_data, value) == 0);
+    } else
+      g_assert(compare_tracefile(user_data, value) != 0);
+  }
+  g_assert(ltt_time_compare(test_time, tfc->timestamp) <= 0);
+  test_time.tv_sec = tfc->timestamp.tv_sec;
+  test_time.tv_nsec = tfc->timestamp.tv_nsec;
+
+  
+  //g_assert(((LttvTracefileContext *)user_data) != (LttvTracefileContext *)value);
+  return FALSE;
+}
+#endif //DEBUG
+
+
+
+void lttv_process_traceset_begin(LttvTracesetContext *self,
+                                 LttvHooks       *before_traceset,
+                                 LttvHooks       *before_trace,
+                                 LttvHooks       *before_tracefile,
+                                 LttvHooks       *event,
+                                 LttvHooksById   *event_by_id)
+{
+
+  /* simply add hooks in context. _before hooks are called by add_hooks. */
+  /* It calls all before_traceset, before_trace, and before_tracefile hooks. */
+  lttv_traceset_context_add_hooks(self,
+                                  before_traceset,
+                                  before_trace,
+                                  before_tracefile,
+                                  event,
+                                  event_by_id);
+  
+}
+
+//enum read_state { LAST_NONE, LAST_OK, LAST_EMPTY };
+
+/* Note : a _middle must be preceded from a _seek or another middle */
+guint lttv_process_traceset_middle(LttvTracesetContext *self,
+                              LttTime end,
+                              guint nb_events,
+                              const LttvTracesetContextPosition *end_position)
+{
+  GTree *pqueue = self->pqueue;
+
+  guint fac_id, ev_id, id;
+
+  LttvTracefileContext *tfc;
+
+  LttEvent *e;
+  
+  unsigned count = 0;
+
+  guint read_ret;
+
+  //enum read_state last_read_state = LAST_NONE;
+
+  gint last_ret = 0; /* return value of the last hook list called */
+
+  /* Get the next event from the pqueue, call its hooks, 
+     reinsert in the pqueue the following event from the same tracefile 
+     unless the tracefile is finished or the event is later than the 
+     end time. */
+
+  while(TRUE) {
+    tfc = NULL;
+    g_tree_foreach(pqueue, get_first, &tfc);
+    /* End of traceset : tfc is NULL */
+    if(unlikely(tfc == NULL))
+    {
+      return count;
+    }
+
+    /* Have we reached :
+     * - the maximum number of events specified?
+     * - the end position ?
+     * - the end time ?
+     * then the read is finished. We leave the queue in the same state and
+     * break the loop.
+     */
+
+    if(unlikely(last_ret == TRUE ||
+                ((count >= nb_events) && (nb_events != G_MAXULONG)) ||
+     (end_position!=NULL&&lttv_traceset_context_ctx_pos_compare(self,
+                                                          end_position) == 0)||
+       ltt_time_compare(end, tfc->timestamp) <= 0))
+    {
+      return count;
+    }
+    
+    /* Get the tracefile with an event for the smallest time found. If two
+       or more tracefiles have events for the same time, hope that lookup
+       and remove are consistent. */
+#ifdef DEBUG
+    test_time.tv_sec = 0;
+    test_time.tv_nsec = 0;
+    g_debug("test tree before remove");
+    g_tree_foreach(pqueue, test_tree, tfc);
+#endif //DEBUG
+    g_tree_remove(pqueue, tfc);
+
+#ifdef DEBUG
+    test_time.tv_sec = 0;
+    test_time.tv_nsec = 0;
+    g_debug("test tree after remove");
+    g_tree_foreach(pqueue, test_tree, tfc);
+#endif //DEBUG
+
+
+    e = ltt_tracefile_get_event(tfc->tf);
+
+    //if(last_read_state != LAST_EMPTY) {
+    /* Only call hooks if the last read has given an event or if we are at the
+     * first pass (not if last read returned end of tracefile) */
+    count++;
+    
+    fac_id = ltt_event_facility_id(e);
+    ev_id = ltt_event_eventtype_id(e);
+    id = GET_HOOK_ID(fac_id, ev_id);
+    /* Hooks : 
+     * return values : 0 : continue read, 1 : go to next position and stop read,
+     * 2 : stay at the current position and stop read */
+    last_ret = lttv_hooks_call_merge(tfc->event, tfc,
+                        lttv_hooks_by_id_get(tfc->event_by_id, id), tfc);
+
+#if 0
+    /* This is buggy : it won't work well with state computation */
+   if(unlikely(last_ret == 2)) {
+      /* This is a case where we want to stay at this position and stop read. */
+           g_tree_insert(pqueue, tfc, tfc);
+      return count - 1;
+    }
+#endif //0
+    read_ret = ltt_tracefile_read(tfc->tf);
+    
+   
+    if(likely(!read_ret)) {
+      //g_debug("An event is ready");
+      tfc->timestamp = ltt_event_time(e);
+      g_assert(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0);
+           g_tree_insert(pqueue, tfc, tfc);
+#ifdef DEBUG
+      test_time.tv_sec = 0;
+      test_time.tv_nsec = 0;
+      g_debug("test tree after event ready");
+      g_tree_foreach(pqueue, test_tree, NULL);
+#endif //DEBUG
+
+      //last_read_state = LAST_OK;
+    } else {
+      tfc->timestamp = ltt_time_infinite;
+
+      if(read_ret == ERANGE) {
+      //  last_read_state = LAST_EMPTY;
+        g_debug("End of trace");
+      } else
+        g_error("Error happened in lttv_process_traceset_middle");
+    }
+  }
+}
+
+
+void lttv_process_traceset_end(LttvTracesetContext *self,
+                               LttvHooks           *after_traceset,
+                               LttvHooks           *after_trace,
+                               LttvHooks           *after_tracefile,
+                               LttvHooks           *event,
+                               LttvHooksById       *event_by_id)
+{
+  /* Remove hooks from context. _after hooks are called by remove_hooks. */
+  /* It calls all after_traceset, after_trace, and after_tracefile hooks. */
+  lttv_traceset_context_remove_hooks(self,
+                                     after_traceset,
+                                     after_trace,
+                                     after_tracefile,
+                                     event,
+                                     event_by_id);
+}
+
+/* Subtile modification : 
+ * if tracefile has no event at or after the time requested, it is not put in
+ * the queue, as the next read would fail.
+ *
+ * Don't forget to empty the traceset pqueue before calling this.
+ */
+void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
+{
+  guint i, nb_tracefile;
+
+  gint ret;
+  
+  LttvTracefileContext **tfc;
+
+  nb_tracefile = self->tracefiles->len;
+
+  GTree *pqueue = self->ts_context->pqueue;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i);
+
+    g_tree_remove(pqueue, *tfc);
+    
+    ret = ltt_tracefile_seek_time((*tfc)->tf, start);
+    if(ret == EPERM) g_error("error in lttv_process_trace_seek_time seek");
+
+    if(ret == 0) { /* not ERANGE especially */
+      (*tfc)->timestamp = ltt_event_time(ltt_tracefile_get_event((*tfc)->tf));
+      g_assert(ltt_time_compare((*tfc)->timestamp, ltt_time_infinite) != 0);
+      g_tree_insert(pqueue, (*tfc), (*tfc));
+    } else {
+      (*tfc)->timestamp = ltt_time_infinite;
+    }
+  }
+#ifdef DEBUG
+  test_time.tv_sec = 0;
+  test_time.tv_nsec = 0;
+  g_debug("test tree after seek_time");
+  g_tree_foreach(pqueue, test_tree, NULL);
+#endif //DEBUG
+
+
+
+}
+
+
+void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
+{
+  guint i, nb_trace;
+
+  LttvTraceContext *tc;
+
+  //g_tree_destroy(self->pqueue);
+  //self->pqueue = g_tree_new(compare_tracefile);
+
+  nb_trace = lttv_traceset_number(self->ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+    lttv_process_trace_seek_time(tc, start);
+  }
+}
+
+
+gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, 
+                                        const LttvTracesetContextPosition *pos)
+{
+  guint i;
+   /* If a position is set, seek the traceset to this position */
+  if(ltt_time_compare(pos->timestamp, ltt_time_infinite) != 0) {
+
+    /* Test to see if the traces has been added to the trace set :
+     * It should NEVER happen. Clear all positions if a new trace comes in. */
+    /* FIXME I know this test is not optimal : should keep a number of
+     * tracefiles variable in the traceset.. eventually */
+    guint num_traces = lttv_traceset_number(self->ts);
+    guint tf_count = 0;
+    for(i=0; i<num_traces;i++) {
+      GArray * tracefiles = self->traces[i]->tracefiles;
+      guint j;
+      guint num_tracefiles = tracefiles->len;
+      for(j=0;j<num_tracefiles;j++)
+        tf_count++;
+    }
+    g_assert(tf_count == pos->tfcp->len);
+     
+
+    //g_tree_destroy(self->pqueue);
+    //self->pqueue = g_tree_new(compare_tracefile);
+    
+    for(i=0;i<pos->tfcp->len; i++) {
+      LttvTracefileContextPosition *tfcp = 
+        &g_array_index(pos->tfcp, LttvTracefileContextPosition, i);
+
+      g_tree_remove(self->pqueue, tfcp->tfc);
+      
+      if(tfcp->used == TRUE) {
+        if(ltt_tracefile_seek_position(tfcp->tfc->tf, tfcp->event) != 0)
+          return 1;
+        tfcp->tfc->timestamp =
+          ltt_event_time(ltt_tracefile_get_event(tfcp->tfc->tf));
+        g_assert(ltt_time_compare(tfcp->tfc->timestamp,
+                                  ltt_time_infinite) != 0);
+        g_tree_insert(self->pqueue, tfcp->tfc, tfcp->tfc);
+
+      } else {
+        tfcp->tfc->timestamp = ltt_time_infinite;
+      }
+    }
+  }
+#ifdef DEBUG
+  test_time.tv_sec = 0;
+  test_time.tv_nsec = 0;
+  g_debug("test tree after seek_position");
+  g_tree_foreach(self->pqueue, test_tree, NULL);
+#endif //DEBUG
+
+
+
+  return 0;
+}
+
+
+
+static LttField *
+find_field(LttEventType *et, const GQuark field)
+{
+  LttType *t;
+
+  LttField *f;
+
+  guint i, nb;
+
+  GQuark name;
+
+  /* Field is unset */
+  if(field == 0) return NULL;
+  
+  f = ltt_eventtype_field(et);
+  t = ltt_eventtype_type(et);
+  g_assert(ltt_type_class(t) == LTT_STRUCT);
+  nb = ltt_type_member_number(t);
+  for(i = 0 ; i < nb ; i++) {
+    ltt_type_member_type(t, i, &name);
+    if(name == field) break;
+  }
+  g_assert(i < nb);
+  return ltt_field_member(f, i);
+}
+
+LttvTraceHookByFacility *lttv_trace_hook_get_fac(LttvTraceHook *th, 
+                                                 guint facility_id)
+{
+  return &g_array_index(th->fac_index, LttvTraceHookByFacility, facility_id);
+}
+
+/* Get the first facility corresponding to the name. As the types must be
+ * compatible, it is relevant to use the field name and sizes of the first
+ * facility to create data structures and assume the data will be compatible
+ * thorough the trace */
+LttvTraceHookByFacility *lttv_trace_hook_get_first(LttvTraceHook *th)
+{
+  g_assert(th->fac_list->len > 0);
+  return g_array_index(th->fac_list, LttvTraceHookByFacility*, 0);
+}
+
+
+/* Returns 0 on success, -1 if fails. */
+gint
+lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, 
+    GQuark field1, GQuark field2, GQuark field3, LttvHook h, gpointer hook_data,
+    LttvTraceHook *th)
+{
+  LttFacility *f;
+
+  LttEventType *et, *first_et;
+
+  GArray *facilities;
+
+  guint i, fac_id, ev_id;
+
+  LttvTraceHookByFacility *thf, *first_thf;
+
+  facilities = ltt_trace_facility_get_by_name(t, facility);
+
+  if(unlikely(facilities == NULL)) goto facility_error;
+
+  th->fac_index = g_array_sized_new(FALSE, TRUE,
+             sizeof(LttvTraceHookByFacility),
+             NUM_FACILITIES);
+  th->fac_index = g_array_set_size(th->fac_index, NUM_FACILITIES);
+
+  th->fac_list = g_array_sized_new(FALSE, TRUE,
+             sizeof(LttvTraceHookByFacility*),
+             facilities->len);
+  th->fac_list = g_array_set_size(th->fac_list, facilities->len);
+  
+  fac_id = g_array_index(facilities, guint, 0);
+  f = ltt_trace_get_facility_by_num(t, fac_id);
+
+  et = ltt_facility_eventtype_get_by_name(f, event);
+  if(unlikely(et == NULL)) goto event_error;
+  
+  thf = &g_array_index(th->fac_index, LttvTraceHookByFacility, fac_id);
+  g_array_index(th->fac_list, LttvTraceHookByFacility*, 0) = thf;
+
+  ev_id = ltt_eventtype_id(et);
+  
+  thf->h = h;
+  thf->id = GET_HOOK_ID(fac_id, ev_id);
+  thf->f1 = find_field(et, field1);
+  thf->f2 = find_field(et, field2);
+  thf->f3 = find_field(et, field3);
+  thf->hook_data = hook_data;
+  
+  first_thf = thf;
+  first_et = et;
+
+  /* Check for type compatibility too */
+  for(i=1;i<facilities->len;i++) {
+    fac_id = g_array_index(facilities, guint, i);
+    f = ltt_trace_get_facility_by_num(t, fac_id);
+
+    et = ltt_facility_eventtype_get_by_name(f, event);
+    if(unlikely(et == NULL)) goto event_error;
+    
+    thf = &g_array_index(th->fac_index, LttvTraceHookByFacility, fac_id);
+    g_array_index(th->fac_list, LttvTraceHookByFacility*, i) = thf;
+    ev_id = ltt_eventtype_id(et);
+    thf->h = h;
+    thf->id = GET_HOOK_ID(fac_id, ev_id);
+    thf->f1 = find_field(et, field1);
+    if(check_fields_compatibility(first_et, et,
+        first_thf->f1, thf->f1))
+      goto type_error;
+        
+    thf->f2 = find_field(et, field2);
+    if(check_fields_compatibility(first_et, et,
+        first_thf->f2, thf->f2))
+      goto type_error;
+
+    thf->f3 = find_field(et, field3);
+    if(check_fields_compatibility(first_et, et,
+        first_thf->f3, thf->f3))
+      goto type_error;
+    thf->hook_data = hook_data;
+  }
+
+  return 0;
+
+type_error:
+  goto free;
+event_error:
+  g_error("Event type does not exist for event %s", 
+      g_quark_to_string(event));
+  goto free;
+facility_error:
+  g_error("No %s facility", g_quark_to_string(facility));
+  goto free;
+free:
+  g_array_free(th->fac_index, TRUE);
+  g_array_free(th->fac_list, TRUE);
+  th->fac_index = NULL;
+  th->fac_list = NULL;
+  return -1;
+}
+
+void lttv_trace_hook_destroy(LttvTraceHook *th)
+{
+  g_array_free(th->fac_index, TRUE);
+  g_array_free(th->fac_list, TRUE);
+}
+
+
+
+
+LttvTracesetContextPosition *lttv_traceset_context_position_new(
+                                        const LttvTracesetContext *self)
+{
+  guint num_traces = lttv_traceset_number(self->ts);
+  guint tf_count = 0;
+  guint i;
+  
+  for(i=0; i<num_traces;i++) {
+    GArray * tracefiles = self->traces[i]->tracefiles;
+    guint j;
+    guint num_tracefiles = tracefiles->len;
+    for(j=0;j<num_tracefiles;j++)
+      tf_count++;
+  }
+  LttvTracesetContextPosition *pos =
+          g_new(LttvTracesetContextPosition, 1);
+  pos->tfcp = g_array_sized_new(FALSE, TRUE,
+                                sizeof(LttvTracefileContextPosition),
+                                tf_count);
+  g_array_set_size(pos->tfcp, tf_count);
+  for(i=0;i<pos->tfcp->len;i++) {
+    LttvTracefileContextPosition *tfcp = 
+      &g_array_index(pos->tfcp, LttvTracefileContextPosition, i);
+    tfcp->event = ltt_event_position_new();
+  }
+
+  pos->timestamp = ltt_time_infinite;
+  return pos;
+}
+
+/* Save all positions, the ones with infinite time will have NULL
+ * ep. */
+/* note : a position must be destroyed when a trace is added/removed from a
+ * traceset */
+void lttv_traceset_context_position_save(const LttvTracesetContext *self,
+                                    LttvTracesetContextPosition *pos)
+{
+  guint i;
+  guint num_traces = lttv_traceset_number(self->ts);
+  guint tf_count = 0;
+  
+  pos->timestamp = ltt_time_infinite;
+  
+  for(i=0; i<num_traces;i++) {
+    GArray * tracefiles = self->traces[i]->tracefiles;
+    guint j;
+    guint num_tracefiles = tracefiles->len;
+
+    for(j=0;j<num_tracefiles;j++) {
+      g_assert(tf_count < pos->tfcp->len);
+      LttvTracefileContext **tfc = &g_array_index(tracefiles,
+          LttvTracefileContext*, j);
+      LttvTracefileContextPosition *tfcp = 
+        &g_array_index(pos->tfcp, LttvTracefileContextPosition, tf_count);
+
+      tfcp->tfc = *tfc;
+
+      if(ltt_time_compare((*tfc)->timestamp, ltt_time_infinite) != 0) {
+        LttEvent *event = ltt_tracefile_get_event((*tfc)->tf);
+        ltt_event_position(event, tfcp->event);
+        if(ltt_time_compare((*tfc)->timestamp, pos->timestamp) < 0)
+          pos->timestamp = (*tfc)->timestamp;
+        tfcp->used = TRUE;
+      } else {
+        tfcp->used = FALSE;
+      }
+      
+      //g_array_append_val(pos->tfc, *tfc);
+      //g_array_append_val(pos->ep, ep);
+      tf_count++;
+    }
+
+  }
+}
+
+void lttv_traceset_context_position_destroy(LttvTracesetContextPosition *pos)
+{
+  int i;
+  
+  for(i=0;i<pos->tfcp->len;i++) {
+    LttvTracefileContextPosition *tfcp = 
+      &g_array_index(pos->tfcp, LttvTracefileContextPosition, i);
+    g_free(tfcp->event);
+    tfcp->event = NULL;
+    tfcp->used = FALSE;
+  }
+  g_array_free(pos->tfcp, TRUE);
+  g_free(pos);
+}
+
+void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest,
+                                   const LttvTracesetContextPosition *src)
+{
+  int i;
+  LttvTracefileContextPosition *src_tfcp, *dest_tfcp;
+  
+  g_assert(src->tfcp->len == src->tfcp->len);
+  
+  for(i=0;i<src->tfcp->len;i++) {
+    src_tfcp = 
+      &g_array_index(src->tfcp, LttvTracefileContextPosition, i);
+    dest_tfcp = 
+      &g_array_index(dest->tfcp, LttvTracefileContextPosition, i);
+    
+    dest_tfcp->used = src_tfcp->used;
+    dest_tfcp->tfc = src_tfcp->tfc;
+
+    if(src_tfcp->used) {
+      ltt_event_position_copy(
+          dest_tfcp->event,
+          src_tfcp->event);
+    }
+  }
+  dest->timestamp = src->timestamp;
+}
+
+gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self,
+                                        const LttvTracesetContextPosition *pos)
+{
+  int i;
+  int ret = 0;
+  
+  if(pos->tfcp->len == 0) {
+    if(lttv_traceset_number(self->ts) == 0) return 0;
+    else return 1;
+  }
+  if(lttv_traceset_number(self->ts) == 0)
+    return -1;
+  
+  for(i=0;i<pos->tfcp->len;i++) {
+    LttvTracefileContextPosition *tfcp = 
+      &g_array_index(pos->tfcp, LttvTracefileContextPosition, i);
+    
+    if(tfcp->used == FALSE) {
+      if(ltt_time_compare(tfcp->tfc->timestamp, ltt_time_infinite) < 0) {
+        ret = -1;
+      }
+    } else {
+      if(ltt_time_compare(tfcp->tfc->timestamp, ltt_time_infinite) == 0) {
+        ret = 1;
+      } else {
+        LttEvent *event = ltt_tracefile_get_event(tfcp->tfc->tf);
+
+        ret = ltt_event_position_compare((LttEventPosition*)event, 
+                                          tfcp->event);
+      }
+    }
+    if(ret != 0) return ret;
+
+  }
+  return 0;
+}
+
+
+gint lttv_traceset_context_pos_pos_compare(
+                                  const LttvTracesetContextPosition *pos1,
+                                  const LttvTracesetContextPosition *pos2)
+{
+  int i, j;
+  int ret = 0;
+  
+  if(ltt_time_compare(pos1->timestamp, ltt_time_infinite) == 0) {
+    if(ltt_time_compare(pos2->timestamp, ltt_time_infinite) == 0)
+      return 0;
+    else 
+      return 1;
+  }
+  if(ltt_time_compare(pos2->timestamp, ltt_time_infinite) == 0)
+    return -1;
+  
+  for(i=0;i<pos1->tfcp->len;i++) {
+    LttvTracefileContextPosition *tfcp1 = 
+      &g_array_index(pos1->tfcp, LttvTracefileContextPosition, i);
+    
+    if(tfcp1->used == TRUE) {
+      for(j=0;j<pos2->tfcp->len;j++) {
+        LttvTracefileContextPosition *tfcp2 = 
+          &g_array_index(pos2->tfcp, LttvTracefileContextPosition, j);
+
+        if(tfcp1->tfc == tfcp2->tfc) {
+          if(tfcp2->used == TRUE)
+            ret = ltt_event_position_compare(tfcp1->event, tfcp2->event);
+          else
+            ret = -1;
+
+          if(ret != 0) return ret;
+        }
+      }
+
+    } else {
+      for(j=0;j<pos2->tfcp->len;j++) {
+        LttvTracefileContextPosition *tfcp2 = 
+          &g_array_index(pos2->tfcp, LttvTracefileContextPosition, j);
+
+        if(tfcp1->tfc == tfcp2->tfc)
+          if(tfcp2->used == TRUE) ret = 1;
+        if(ret != 0) return ret;
+      }
+    }
+  }
+  return 0;
+}
+
+
+LttTime lttv_traceset_context_position_get_time(
+                                  const LttvTracesetContextPosition *pos)
+{
+  return pos->timestamp;
+}
+
+
+LttvTracefileContext *lttv_traceset_context_get_current_tfc(LttvTracesetContext *self)
+{
+  GTree *pqueue = self->pqueue;
+  LttvTracefileContext *tfc = NULL;
+
+  g_tree_foreach(pqueue, get_first, &tfc);
+
+  return tfc;
+}
+
+/* lttv_process_traceset_synchronize_tracefiles
+ *
+ * Use the sync_position field of the trace set context to synchronize each
+ * tracefile with the previously saved position.
+ *
+ * If no previous position has been saved, it simply does nothing.
+ */
+void lttv_process_traceset_synchronize_tracefiles(LttvTracesetContext *tsc)
+{
+  g_assert(lttv_process_traceset_seek_position(tsc, tsc->sync_position) == 0);
+}
+
+
+
+
+void lttv_process_traceset_get_sync_data(LttvTracesetContext *tsc)
+{
+  lttv_traceset_context_position_save(tsc, tsc->sync_position);
+}
+
+struct seek_back_data {
+  guint first_event;   /* Index of the first event in the array : we will always
+                         overwrite at this position : this is a circular array. 
+                       */
+  guint events_found;
+  guint n;             /* number of events requested */
+  GPtrArray *array; /* array of LttvTracesetContextPositions pointers */
+  LttvFilter *filter;
+};
+
+static gint seek_back_event_hook(void *hook_data, void* call_data)
+{
+  struct seek_back_data *sd = (struct seek_back_data*)hook_data;
+  LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
+  LttvTracesetContext *tsc = tfc->t_context->ts_context;
+  LttvTracesetContextPosition *pos;
+
+  if(sd->filter != NULL && sd->filter->head != NULL) {
+    if(!lttv_filter_tree_parse(sd->filter->head,
+          ltt_tracefile_get_event(tfc->tf),
+          tfc->tf,
+          tfc->t_context->t,
+          tfc))
+      return FALSE;
+  }
+  
+  pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd->array,
+                                                         sd->first_event);
+
+  lttv_traceset_context_position_save(tsc, pos);
+
+  if(sd->first_event >= sd->array->len - 1) sd->first_event = 0;
+  else sd->first_event++;
+
+  sd->events_found = min(sd->n, sd->events_found + 1);
+
+  return FALSE;
+}
+
+/* Seek back n events back from the current position.
+ *
+ * Parameters :
+ * @self          The trace set context
+ * @n             number of events to jump over
+ * @first_offset  The initial offset value used.
+ *                never put first_offset at ltt_time_zero.
+ * @time_seeker   Function pointer of the function to use to seek time :
+ *                either lttv_process_traceset_seek_time
+ *                    or lttv_state_traceset_seek_time_closest
+ * @filter        The filter to call.
+ *
+ * Return value : the number of events found (might be lower than the number
+ * requested if beginning of traceset is reached).
+ *
+ * The first search will go back first_offset and try to find the last n events
+ * matching the filter. If there are not enough, it will try to go back from the
+ * new trace point from first_offset*2, and so on, until beginning of trace or n
+ * events are found.
+ *
+ * Note : this function does not take in account the LttvFilter : use the
+ * similar function found in state.c instead.
+ *
+ * Note2 : the caller must make sure that the LttvTracesetContext does not
+ * contain any hook, as process_traceset_middle is used in this routine.
+ */
+guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self,
+                                            guint n, LttTime first_offset,
+                                            seek_time_fct time_seeker,
+                                            LttvFilter *filter)
+{
+  if(lttv_traceset_number(self->ts) == 0) return 0;
+  g_assert(ltt_time_compare(first_offset, ltt_time_zero) != 0);
+  
+  guint i;
+  LttvTracesetContextPosition *next_iter_end_pos =
+                                lttv_traceset_context_position_new(self);
+  LttvTracesetContextPosition *end_pos =
+    lttv_traceset_context_position_new(self);
+  LttvTracesetContextPosition *saved_pos =
+    lttv_traceset_context_position_new(self);
+  LttTime time;
+  LttTime asked_time;
+  LttTime time_offset;
+  struct seek_back_data sd;
+  LttvHooks *hooks = lttv_hooks_new();
+  
+  sd.first_event = 0;
+  sd.events_found = 0;
+  sd.array = g_ptr_array_sized_new(n);
+  sd.filter = filter;
+  sd.n = n;
+  g_ptr_array_set_size(sd.array, n);
+  for(i=0;i<n;i++) {
+    g_ptr_array_index (sd.array, i) = lttv_traceset_context_position_new(self);
+  }
+  lttv_traceset_context_position_save(self, next_iter_end_pos);
+  lttv_traceset_context_position_save(self, saved_pos);
+  /* Get the current time from which we will offset */
+  time = lttv_traceset_context_position_get_time(next_iter_end_pos);
+  /* the position saved might be end of traceset... */
+  if(ltt_time_compare(time, self->time_span.end_time) > 0) {
+    time = self->time_span.end_time;
+  }
+  asked_time = time;
+  time_offset = first_offset;
+  lttv_hooks_add(hooks, seek_back_event_hook, &sd, LTTV_PRIO_DEFAULT);
+  
+  lttv_process_traceset_begin(self, NULL, NULL, NULL, hooks, NULL);
+
+  while(1) {
+    /* stop criteria : - n events found
+     *                 - asked_time < beginning of trace */
+    if(ltt_time_compare(asked_time, self->time_span.start_time) < 0) break;
+
+    lttv_traceset_context_position_copy(end_pos, next_iter_end_pos);
+
+    /* We must seek the traceset back to time - time_offset */
+    /* this time becomes the new reference time */
+    time = ltt_time_sub(time, time_offset);
+    asked_time = time;
+    
+    time_seeker(self, time);
+    lttv_traceset_context_position_save(self, next_iter_end_pos);
+    /* Resync the time in case of a seek_closest */
+    time = lttv_traceset_context_position_get_time(next_iter_end_pos);
+    if(ltt_time_compare(time, self->time_span.end_time) > 0) {
+      time = self->time_span.end_time;
+    }
+
+    /* Process the traceset, calling a hook which adds events 
+     * to the array, overwriting the tail. It changes first_event and
+     * events_found too. */
+    /* We would like to have a clean context here : no other hook than our's */
+    
+    lttv_process_traceset_middle(self, ltt_time_infinite,
+        G_MAXUINT, end_pos);
+
+    if(sd.events_found < n) {
+      if(sd.first_event > 0) {
+        /* Save the first position */
+        LttvTracesetContextPosition *pos =
+          (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, 0);
+        lttv_traceset_context_position_copy(saved_pos, pos);
+      }
+      g_assert(n-sd.events_found <= sd.array->len);
+      /* Change array size to n - events_found */
+      for(i=n-sd.events_found;i<sd.array->len;i++) {
+        LttvTracesetContextPosition *pos =
+          (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, i);
+        lttv_traceset_context_position_destroy(pos);
+      }
+      g_ptr_array_set_size(sd.array, n-sd.events_found);
+      sd.first_event = 0;
+      
+    } else break; /* Second end criterion : n events found */
+    
+    time_offset = ltt_time_mul(time_offset, BACKWARD_SEEK_MUL);
+  }
+  
+  lttv_traceset_context_position_destroy(end_pos);
+  lttv_traceset_context_position_destroy(next_iter_end_pos);
+  
+  lttv_process_traceset_end(self, NULL, NULL, NULL, hooks, NULL);
+
+  if(sd.events_found >= n) {
+    /* Seek the traceset to the first event in the circular array */
+    LttvTracesetContextPosition *pos =
+      (LttvTracesetContextPosition*)g_ptr_array_index (sd.array,
+                                                       sd.first_event);
+    g_assert(lttv_process_traceset_seek_position(self, pos) == 0);
+  } else {
+    /* Will seek to the last saved position : in the worst case, it will be the
+     * original position (if events_found is 0) */
+    g_assert(lttv_process_traceset_seek_position(self, saved_pos) == 0);
+  }
+  
+  for(i=0;i<sd.array->len;i++) {
+    LttvTracesetContextPosition *pos =
+      (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, i);
+    lttv_traceset_context_position_destroy(pos);
+  }
+  g_ptr_array_free(sd.array, TRUE);
+
+  lttv_hooks_destroy(hooks);
+
+  lttv_traceset_context_position_destroy(saved_pos);
+
+  return sd.events_found;
+}
+
+
+struct seek_forward_data {
+  guint event_count;  /* event counter */
+  guint n;            /* requested number of events to jump over */
+  LttvFilter *filter;
+};
+
+static gint seek_forward_event_hook(void *hook_data, void* call_data)
+{
+  struct seek_forward_data *sd = (struct seek_forward_data*)hook_data;
+  LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
+
+  if(sd->filter == NULL || lttv_filter_tree_parse(sd->filter->head,
+          ltt_tracefile_get_event(tfc->tf),
+          tfc->tf,
+          tfc->t_context->t,
+          tfc)) {
+    sd->event_count++;
+    if(sd->event_count >= sd->n)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+/* Seek back n events forward from the current position (1 to n)
+ * 0 is ok too, but it will actually do nothing.
+ *
+ * Parameters :
+ * @self   the trace set context
+ * @n      number of events to jump over
+ * @filter filter to call.
+ *
+ * returns : the number of events jumped over (may be less than requested if end
+ * of traceset reached) */
+guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self,
+                                          guint n, LttvFilter *filter)
+{
+  struct seek_forward_data sd;
+  sd.event_count = 0;
+  sd.n = n;
+  sd.filter = filter;
+  
+  if(sd.event_count >= sd.n) return sd.event_count;
+  
+  LttvHooks *hooks = lttv_hooks_new();
+
+  lttv_hooks_add(hooks, seek_forward_event_hook, &sd, LTTV_PRIO_DEFAULT);
+
+  lttv_process_traceset_begin(self, NULL, NULL, NULL, hooks, NULL);
+  
+  /* it will end on the end of traceset, or the fact that the
+   * hook returns TRUE.
+   */
+  lttv_process_traceset_middle(self, ltt_time_infinite,
+        G_MAXUINT, NULL);
+
+  /* Here, our position is either the end of traceset, or the exact position
+   * after n events : leave it like this. This might be placed on an event that
+   * will be filtered out, we don't care : all we know is that the following
+   * event filtered in will be the right one. */
+
+  lttv_process_traceset_end(self, NULL, NULL, NULL, hooks, NULL);
+
+  lttv_hooks_destroy(hooks);
+
+  return sd.event_count;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/tracecontext.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/tracecontext.h
new file mode 100644 (file)
index 0000000..37c4ba1
--- /dev/null
@@ -0,0 +1,366 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef PROCESSTRACE_H
+#define PROCESSTRACE_H
+
+#include <lttv/traceset.h>
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+#include <ltt/ltt.h>
+
+/* This is the generic part of trace processing. All events within a
+   certain time interval are accessed and processing hooks are called for
+   each. The events are examined in monotonically increasing time to more
+   closely follow the traced system behavior. 
+
+   Hooks are called at several different places during the processing:
+   before traceset, after traceset, check trace, before trace, after trace, 
+   check tracefile, before tracefile, after tracefile, 
+   check_event, before_event, before_event_by_id, 
+   after_event, after_event_by_id.
+
+   In each case the "check" hooks are called first to determine if further
+   processing of the trace, tracefile or event is wanted. Then, the before
+   hooks and the after hooks are called. The before hooks for a traceset
+   are called before those for the contained traces, which are called before
+   those for the contained tracefiles. The after hooks are called in reverse
+   order. The event hooks are called after all the before_tracefile hooks
+   and before all the after_tracefile hooks.
+
+   The hooks receive two arguments, the hook_data and call_data. The hook_data
+   is specified when the hook is registered and typically links to the
+   object registering the hook (e.g. a graphical events viewer). The call_data
+   must contain all the context related to the call. The traceset hooks receive
+   the LttvTracesetContext provided by the caller. The trace hooks receive
+   the LttvTraceContext from the traces array in the LttvTracesetContext.
+   The tracefile and event hooks receive the LttvTracefileContext from
+   the tracefiles array in the LttvTraceContext. The LttEvent and LttTime
+   fields in the tracefile context are set to the current event and current
+   event time before calling the event hooks. No other context field is 
+   modified.
+
+   The contexts in the traces and tracefiles arrays must be allocated by 
+   the caller, either before the call or during the before hooks of the 
+   enclosing traceset or trace. The order in the traces array must
+   correspond to the lttv_traceset_get function. The order in the tracefiles
+   arrays must correspond to the ltt_trace_control_tracefile_get and
+   ltt_trace_per_cpu_tracefile_get functions. The traceset, trace and
+   tracefile contexts may be subtyped as needed. Indeed, both the contexts
+   and the hooks are defined by the caller. */
+
+
+typedef struct _LttvTracesetContext LttvTracesetContext;
+typedef struct _LttvTracesetContextClass LttvTracesetContextClass;
+
+typedef struct _LttvTraceContext LttvTraceContext;
+typedef struct _LttvTraceContextClass LttvTraceContextClass;
+
+typedef struct _LttvTracefileContext LttvTracefileContext;
+typedef struct _LttvTracefileContextClass LttvTracefileContextClass;
+
+typedef struct _LttvTracesetContextPosition LttvTracesetContextPosition;
+typedef struct _LttvTraceContextPosition LttvTraceContextPosition;
+
+#ifndef LTTVFILTER_TYPE_DEFINED
+typedef struct _LttvFilter LttvFilter;
+#define LTTVFILTER_TYPE_DEFINED
+#endif
+
+#define LTTV_TRACESET_CONTEXT_TYPE  (lttv_traceset_context_get_type ())
+#define LTTV_TRACESET_CONTEXT(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContext))
+#define LTTV_TRACESET_CONTEXT_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass))
+#define LTTV_IS_TRACESET_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_CONTEXT_TYPE))
+#define LTTV_IS_TRACESET_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_CONTEXT_TYPE))
+#define LTTV_TRACESET_CONTEXT_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass))
+
+struct _LttvTracesetContext {
+  GObject parent;
+
+  LttvTraceset *ts;
+  LttvTraceContext **traces;
+  LttvAttribute *a;
+  LttvAttribute *ts_a;
+  TimeInterval time_span;
+  GTree *pqueue;
+
+  LttvTracesetContextPosition *sync_position;   /* position at which to sync the
+                                                   trace context */
+};
+
+struct _LttvTracesetContextClass {
+  GObjectClass parent;
+
+  void (*init) (LttvTracesetContext *self, LttvTraceset *ts);
+  void (*fini) (LttvTracesetContext *self);
+  LttvTracesetContext* (*new_traceset_context) (LttvTracesetContext *self);
+  LttvTraceContext* (*new_trace_context) (LttvTracesetContext *self);
+  LttvTracefileContext* (*new_tracefile_context) (LttvTracesetContext *self);
+};
+
+GType lttv_traceset_context_get_type (void);
+
+void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts);
+
+void lttv_context_fini(LttvTracesetContext *self);
+
+LttvTracesetContext *
+lttv_context_new_traceset_context(LttvTracesetContext *self);
+
+LttvTraceContext * 
+lttv_context_new_trace_context(LttvTracesetContext *self);
+
+LttvTracefileContext *
+lttv_context_new_tracefile_context(LttvTracesetContext *self);
+
+
+#define LTTV_TRACE_CONTEXT_TYPE  (lttv_trace_context_get_type ())
+#define LTTV_TRACE_CONTEXT(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContext))
+#define LTTV_TRACE_CONTEXT_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContextClass))
+#define LTTV_IS_TRACE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_CONTEXT_TYPE))
+#define LTTV_IS_TRACE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_CONTEXT_TYPE))
+#define LTTV_TRACE_CONTEXT_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContextClass))
+
+struct _LttvTraceContext {
+  GObject parent;
+
+  LttvTracesetContext *ts_context;
+  guint index;                /* in ts_context->traces */
+  LttTrace *t;
+  LttvTrace *vt;
+  //LttvTracefileContext **tracefiles;
+  GArray *tracefiles;
+  LttvAttribute *a;
+  LttvAttribute *t_a;
+  TimeInterval time_span;
+};
+
+struct _LttvTraceContextClass {
+  GObjectClass parent;
+};
+
+GType lttv_trace_context_get_type (void);
+
+#define LTTV_TRACEFILE_CONTEXT_TYPE  (lttv_tracefile_context_get_type ())
+#define LTTV_TRACEFILE_CONTEXT(obj)  (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContext))
+#define LTTV_TRACEFILE_CONTEXT_CLASS(vtable)  (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContextClass))
+#define LTTV_IS_TRACEFILE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_CONTEXT_TYPE))
+#define LTTV_IS_TRACEFILE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_CONTEXT_TYPE))
+#define LTTV_TRACEFILE_CONTEXT_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContextClass))
+
+struct _LttvTracefileContext {
+  GObject parent;
+
+  LttvTraceContext *t_context;
+ // gboolean control;
+  guint index;                /* in ts_context->tracefiles */
+  LttTracefile *tf;
+ // LttEvent *e;
+  LttvHooks *event;
+  LttvHooksById *event_by_id;
+  LttTime timestamp;
+  LttvAttribute *a;
+};
+
+struct _LttvTracefileContextClass {
+  GObjectClass parent;
+};
+
+GType lttv_tracefile_context_get_type (void);
+
+/* Run through the events in a traceset in sorted order calling all the
+   hooks appropriately. It starts at the current time and runs until end or
+   nb_events are processed. */
+
+void lttv_process_traceset(LttvTracesetContext *self, LttTime end, 
+    unsigned nb_events);
+
+/* Process traceset can also be done in smaller pieces calling begin,
+ * then seek and middle repeatedly, and end. The middle function return the
+ * number of events processed. It will be smaller than nb_events if the end time
+ * or end position is reached. */
+
+
+void lttv_process_traceset_begin(LttvTracesetContext *self,
+                                 LttvHooks       *before_traceset,
+                                 LttvHooks       *before_trace,
+                                 LttvHooks       *before_tracefile,
+                                 LttvHooks       *event,
+                                 LttvHooksById   *event_by_id);
+
+
+guint lttv_process_traceset_middle(LttvTracesetContext *self,
+                              LttTime end, 
+                              guint nb_events,
+                              const LttvTracesetContextPosition *end_position);
+
+void lttv_process_traceset_end(LttvTracesetContext *self,
+                               LttvHooks           *after_traceset,
+                               LttvHooks           *after_trace,
+                               LttvHooks           *after_tracefile,
+                               LttvHooks           *event,
+                               LttvHooksById       *event_by_id);
+
+
+void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start);
+
+gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, 
+                                        const LttvTracesetContextPosition *pos);
+
+void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start);
+
+void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
+    LttvHooks *before_traceset,
+    LttvHooks *before_trace, 
+    LttvHooks *before_tracefile,
+    LttvHooks *event,
+    LttvHooksById *event_by_id);
+
+void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
+    LttvHooks *after_traceset,
+    LttvHooks *after_trace, 
+    LttvHooks *after_tracefile,
+    LttvHooks *event, 
+    LttvHooksById *event_by_id);
+
+void lttv_trace_context_add_hooks(LttvTraceContext *self,
+    LttvHooks *before_trace, 
+    LttvHooks *before_tracefile,
+    LttvHooks *event, 
+    LttvHooksById *event_by_id);
+
+void lttv_trace_context_remove_hooks(LttvTraceContext *self,
+    LttvHooks *after_trace, 
+    LttvHooks *after_tracefile,
+    LttvHooks *event, 
+    LttvHooksById *event_by_id);
+
+void lttv_tracefile_context_add_hooks(LttvTracefileContext *self,
+          LttvHooks *before_tracefile,
+          LttvHooks *event, 
+          LttvHooksById *event_by_id);
+
+
+void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self,
+           LttvHooks *after_tracefile,
+           LttvHooks *event, 
+           LttvHooksById *event_by_id);
+
+
+void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *self,
+                                           unsigned i,
+                                           LttvHooks *event_by_id);
+
+void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *self,
+                                              unsigned i);
+
+/* A LttvTraceHook has two arrays of LttvTraceHookByFacility,
+ * indexed by facility ID and a simple array used to walk all the hooks */
+typedef struct _LttvTraceHook {
+  GArray *fac_index;
+  GArray *fac_list;
+} LttvTraceHook;
+
+typedef struct _LttvTraceHookByFacility {
+  LttvHook h;
+  guint id;
+  LttField *f1;
+  LttField *f2;
+  LttField *f3;
+  gpointer hook_data;
+} LttvTraceHookByFacility;
+
+
+/* Get the first facility corresponding to the name. As the types must be
+ * compatible, it is relevant to use the field name and sizes of the first
+ * facility to create data structures and assume the data will be compatible
+ * thorough the trace */
+LttvTraceHookByFacility *lttv_trace_hook_get_first(LttvTraceHook *th);
+
+LttvTraceHookByFacility *lttv_trace_hook_get_fac(
+    LttvTraceHook *th, guint facility_id);
+
+void lttv_trace_hook_destroy(LttvTraceHook *th);
+
+/* Search in the trace for the id of the named event type within the named
+   facility. Then, find the three (if non null) named fields. All that
+   information is then used to fill the LttvTraceHook structure. This
+   is useful to find the specific id for an event within a trace, for
+   registering a hook using this structure as event data;
+   it already contains the (up to three) needed fields handles. */
+gint lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event_type,
+    GQuark field1, GQuark field2, GQuark field3, LttvHook h,
+    gpointer hook_data, LttvTraceHook *th);
+
+LttvTracefileContext *lttv_traceset_context_get_current_tfc(
+                             LttvTracesetContext *self);
+
+
+LttvTracesetContextPosition *lttv_traceset_context_position_new(
+    const LttvTracesetContext *self);
+
+void lttv_traceset_context_position_save(const LttvTracesetContext *self,
+                                    LttvTracesetContextPosition *pos);
+
+void lttv_traceset_context_position_destroy(LttvTracesetContextPosition *pos);
+
+void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest,
+                                   const LttvTracesetContextPosition *src);
+
+gint lttv_traceset_context_pos_pos_compare(
+                          const LttvTracesetContextPosition *pos1,
+                          const LttvTracesetContextPosition *pos2);
+
+gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self,
+                                    const LttvTracesetContextPosition *pos2);
+
+LttTime lttv_traceset_context_position_get_time(
+                                      const LttvTracesetContextPosition *pos);
+
+gint compare_tracefile(gconstpointer a, gconstpointer b);
+
+
+/* Synchronisation helpers : save/restore synchronization between ltt traces and
+ * a traceset context. */
+void lttv_process_traceset_synchronize_tracefiles(LttvTracesetContext *tsc);
+
+void lttv_process_traceset_get_sync_data(LttvTracesetContext *tsc);
+
+/* Seek n events forward and backward (without filtering) : only use these where
+ * necessary : the seek backward is costy. */
+
+#define BACKWARD_SEEK_MUL 2 /* Multiplication factor of time_offset between
+                               backward seek iterations */
+
+static const LttTime seek_back_default_offset = { 1, 0 };
+
+guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self,
+                                           guint n,
+                                           LttvFilter *filter);
+typedef void (*seek_time_fct)(LttvTracesetContext *self, LttTime start);
+
+/* If first_offset is ltt_time_zero, it will choose a default value */
+guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self,
+                                            guint n,
+                                            LttTime first_offset,
+                                            seek_time_fct,
+                                            LttvFilter *filter);
+
+
+#endif // PROCESSTRACE_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/traceset.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/traceset.c
new file mode 100644 (file)
index 0000000..181bdd5
--- /dev/null
@@ -0,0 +1,214 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/traceset.h>
+#include <lttv/iattribute.h>
+#include <stdio.h>
+
+/* A trace is a sequence of events gathered in the same tracing session. The
+   events may be stored in several tracefiles in the same directory. 
+   A trace set is defined when several traces are to be analyzed together,
+   possibly to study the interactions between events in the different traces. 
+*/
+
+struct _LttvTraceset {
+  char * filename;
+  GPtrArray *traces;
+  LttvAttribute *a;
+};
+
+
+struct _LttvTrace {
+  LttTrace *t;
+  LttvAttribute *a;
+  guint ref_count;
+};
+
+
+LttvTraceset *lttv_traceset_new() 
+{
+  LttvTraceset *s;
+
+  s = g_new(LttvTraceset, 1);
+  s->filename = NULL;
+  s->traces = g_ptr_array_new();
+  s->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  return s;
+}
+
+char * lttv_traceset_name(LttvTraceset * s)
+{
+  return s->filename;
+}
+
+LttvTrace *lttv_trace_new(LttTrace *t) 
+{
+  LttvTrace *new_trace;
+
+  new_trace = g_new(LttvTrace, 1);
+  new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  new_trace->t = t;
+  new_trace->ref_count = 0;
+  return new_trace;
+}
+
+
+LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig) 
+{
+  guint i;
+  LttvTraceset *s;
+  LttvTrace * trace;
+
+  s = g_new(LttvTraceset, 1);
+  s->filename = NULL;
+  s->traces = g_ptr_array_new();
+  for(i=0;i<s_orig->traces->len;i++)
+  {
+    trace = g_ptr_array_index(s_orig->traces, i);
+    trace->ref_count++;
+
+    g_ptr_array_add(s->traces,
+                         trace);
+  }
+  s->a = LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig->a)));
+  return s;
+}
+
+
+LttvTraceset *lttv_traceset_load(const gchar *filename)
+{
+  LttvTraceset *s = g_new(LttvTraceset,1);
+  FILE *tf;
+  
+  s->filename = g_strdup(filename);
+  tf = fopen(filename,"r");
+
+  g_critical("NOT IMPLEMENTED : load traceset data from a XML file");
+  
+  fclose(tf);
+  return s;
+}
+
+gint lttv_traceset_save(LttvTraceset *s)
+{
+  FILE *tf;
+
+  tf = fopen(s->filename, "w");
+  
+  g_critical("NOT IMPLEMENTED : save traceset data in a XML file");
+
+  fclose(tf);
+  return 0;
+}
+
+void lttv_traceset_destroy(LttvTraceset *s) 
+{
+  guint i;
+
+  for(i=0;i<s->traces->len;i++) {
+    LttvTrace *trace = g_ptr_array_index(s->traces, i);
+    lttv_trace_unref(trace);
+    if(lttv_trace_get_ref_number(trace) == 0)
+      lttv_trace_destroy(trace);
+  }
+  g_ptr_array_free(s->traces, TRUE);
+  g_object_unref(s->a);
+  g_free(s);
+}
+
+void lttv_trace_destroy(LttvTrace *t) 
+{
+  g_object_unref(t->a);
+  g_free(t);
+}
+
+
+void lttv_traceset_add(LttvTraceset *s, LttvTrace *t) 
+{
+  t->ref_count++;
+  g_ptr_array_add(s->traces, t);
+}
+
+
+unsigned lttv_traceset_number(LttvTraceset *s) 
+{
+  return s->traces->len;
+}
+
+
+LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i) 
+{
+  g_assert(s->traces->len > i);
+  return ((LttvTrace *)s->traces->pdata[i]);
+}
+
+
+void lttv_traceset_remove(LttvTraceset *s, unsigned i) 
+{
+  LttvTrace * t;
+  g_assert(s->traces->len > i);
+  t = (LttvTrace *)s->traces->pdata[i];
+  t->ref_count--;
+  g_ptr_array_remove_index(s->traces, i);
+}
+
+
+/* A set of attributes is attached to each trace set, trace and tracefile
+   to store user defined data as needed. */
+
+LttvAttribute *lttv_traceset_attribute(LttvTraceset *s) 
+{
+  return s->a;
+}
+
+
+LttvAttribute *lttv_trace_attribute(LttvTrace *t)
+{
+  return t->a;
+}
+
+
+LttTrace *lttv_trace(LttvTrace *t)
+{
+  return t->t;
+}
+
+guint lttv_trace_get_ref_number(LttvTrace * t)
+{
+  return t->ref_count;
+}
+
+guint lttv_trace_ref(LttvTrace * t)
+{
+  t->ref_count++;
+  
+  return t->ref_count;
+}
+
+guint lttv_trace_unref(LttvTrace * t)
+{
+  if(likely(t->ref_count > 0))
+    t->ref_count--;
+
+  return t->ref_count;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/traceset.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/lttv/traceset.h
new file mode 100644 (file)
index 0000000..7ef85be
--- /dev/null
@@ -0,0 +1,73 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef TRACESET_H
+#define TRACESET_H
+
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+#include <ltt/ltt.h>
+
+/* A traceset is a set of traces to be analyzed together. */
+
+typedef struct _LttvTraceset LttvTraceset;
+
+typedef struct _LttvTrace LttvTrace;
+
+/* Tracesets may be added to, removed from and their content listed. */
+
+LttvTraceset *lttv_traceset_new();
+
+char * lttv_traceset_name(LttvTraceset * s);
+
+LttvTrace *lttv_trace_new(LttTrace *t);
+
+LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig);
+
+LttvTraceset *lttv_traceset_load(const gchar *filename);
+
+gint lttv_traceset_save(LttvTraceset *s);
+
+void lttv_traceset_destroy(LttvTraceset *s);
+
+void lttv_trace_destroy(LttvTrace *t);
+
+void lttv_traceset_add(LttvTraceset *s, LttvTrace *t);
+
+unsigned lttv_traceset_number(LttvTraceset *s);
+
+LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i);
+
+void lttv_traceset_remove(LttvTraceset *s, unsigned i);
+
+/* An attributes table is attached to the set and to each trace in the set. */
+
+LttvAttribute *lttv_traceset_attribute(LttvTraceset *s);
+
+LttvAttribute *lttv_trace_attribute(LttvTrace *t);
+
+LttTrace *lttv_trace(LttvTrace *t);
+
+guint lttv_trace_get_ref_number(LttvTrace * t);
+
+guint lttv_trace_ref(LttvTrace * t);
+
+guint lttv_trace_unref(LttvTrace * t);
+
+#endif // TRACESET_H
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/Makefile.am
new file mode 100644 (file)
index 0000000..14a4714
--- /dev/null
@@ -0,0 +1,28 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 Mathieu Desnoyers
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+# MA 02111-1307, USA.
+
+
+
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+# the gui subdir comes first : dependency
+SUBDIRS = text gui
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/README b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/README
new file mode 100644 (file)
index 0000000..8dce1b7
--- /dev/null
@@ -0,0 +1,21 @@
+
+|-----------------|
+|Graphical Plugins|
+|-----------------|
+gui/
+
+detailedevents : Display events for time interval into a list.
+controlflow : Display the control flow of the trace for time interval
+                 using gdk and a GtkDrawingArea. Pixmaps for icons are
+                            defined with each event inside the event related
+                            information.
+statistics :  Display statistics computed from the trace.
+
+|---------------------|
+|Text Oriented Plugins|
+|---------------------|
+text/
+
+batchAnalysis : Call processing hooks for every events of the trace.
+textDump : Dump in clear text all data related to events on standard output.
+           It depends on batchAnalysis.
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/Makefile.am
new file mode 100644 (file)
index 0000000..b9f091a
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Makefile for LTT New generation user interface : test plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+libdir = ${lttvplugindir}
+AM_CFLAGS = $(GLIB_CFLAGS) 
+LIBS += $(GLIB_LIBS)
+
+lib_LTLIBRARIES = libsampledep.la libsamplemodule.la libsamplemodule2.la
+libsampledep_la_LDFLAGS = -module
+libsampledep_la_SOURCES = sampledep.c
+libsamplemodule_la_LDFLAGS = -module
+libsamplemodule_la_SOURCES = samplemodule.c
+libsamplemodule2_la_LDFLAGS = -module
+libsamplemodule2_la_SOURCES = samplemodule2.c
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/sampledep.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/sampledep.c
new file mode 100644 (file)
index 0000000..9f0ca61
--- /dev/null
@@ -0,0 +1,25 @@
+/* Sample module for Linux Trace Toolkit new generation User Interface */
+
+/* Created by Mathieu Desnoyers, may 2003 */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+/* Include module.h from lttv headers for module loading */
+#include <lttv/module.h>
+
+static void init() {
+       g_critical("Sample module dependant init()");
+}
+
+static void destroy() {
+       g_critical("Sample module dependant destroy()");
+}
+
+
+LTTV_MODULE("sampledep", "Medium desc...", "Long desc...", init, destroy, \
+           { "samplemodule" })
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/samplemodule.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/samplemodule.c
new file mode 100644 (file)
index 0000000..6e676d5
--- /dev/null
@@ -0,0 +1,22 @@
+/* Sample module for Linux Trace Toolkit new generation User Interface */
+
+/* Created by Mathieu Desnoyers, may 2003 */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <lttv/module.h>
+
+static void init() {
+       g_critical("Sample module init()");
+}
+
+static void destroy() {
+       g_critical("Sample module destroy()");
+}
+
+
+LTTV_MODULE("sampledep", "Medium...", "Long...", init, destroy, {})
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/samplemodule2.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/examples/samplemodule2.c
new file mode 100644 (file)
index 0000000..19a094d
--- /dev/null
@@ -0,0 +1,22 @@
+/* Sample module for Linux Trace Toolkit new generation User Interface */
+
+/* Created by Mathieu Desnoyers, may 2003 */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <lttv/module.h>
+
+static void init() {
+       g_critical("Sample module 2 init()");
+}
+
+static void destroy() {
+       g_critical("Sample module 2 destroy()");
+}
+
+
+LTTV_MODULE("samplemodule2", "Medium...", "Long...", init, destroy, {})
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/Makefile.am
new file mode 100644 (file)
index 0000000..ee483f4
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+# WARNING : subdirs order is important : mainWin depends on API
+
+SUBDIRS = lttvwindow controlflow detailedevents statistics filter tracecontrol interrupts diskperformance
+
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/Makefile.am
new file mode 100644 (file)
index 0000000..b951029
--- /dev/null
@@ -0,0 +1,41 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 Mathieu Desnoyers
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+# MA 02111-1307, USA.
+
+
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on September 27, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libguicontrolflow.la
+libguicontrolflow_la_LDFLAGS = -module
+libguicontrolflow_la_SOURCES =         module.c eventhooks.c cfv.c processlist.c\
+                               drawing.c drawitem.c
+
+noinst_HEADERS =       eventhooks.h cfv.h processlist.h\
+                               drawing.h drawitem.h
+
+EXTRA_DIST = \
+               hGuiControlFlowInsert.xpm hLegendInsert.xpm
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/TODO b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/TODO
new file mode 100644 (file)
index 0000000..ade1832
--- /dev/null
@@ -0,0 +1,64 @@
+TODO list on control flow view by Mathieu Desnoyers
+
+- Make "before hook" update process's info : it creates an inconsistency
+  between state.c process table and process list. Waiting to see if
+  state.c will take first event time as creation time or first schedule.
+
+
+- Split in process view and CPU ciew :
+  - remove process 0 from the process list
+  - add a new viewer to the module :
+    - cfv.c -> new cpuctl.c : core of the view
+    - eventhooks.c -> cpuhooks.c : draw cpu states
+    - processlist.c -> cpulist.c
+
+- Check cfv for stability, modules load/unload, viewer start (many:3+), stop,
+  memory leaks; standardize module unloading : in all cases they should call
+  main window's API for viewer widget removal, and only then the memory should
+  be released (from the call of the main window).
+
+- Add viewer selected signal (call main window's API function)
+- When viewing a big trace, use the fact that the drawing cannot be more
+  precise than the amount of horizontal pixels it has : "jump" from one event
+  to another, converting pixels to time in the trace. It will use efficiently
+  the "saved state" functionnality of underlying state.c.
+
+- Modify widgets'organization so the time bar is not affected by scrolling :
+  it may need to separate process list from the drawing area (not in a
+  scrolled window anymore). The idea would be to use a scrolled window for
+  the drawing area, put it in the right side of a hbox, put the tree view
+  in the left side and then connect the tree view's adjustment to the
+  scrolled window's scroll bar.
+
+- Modify icon, text and arc drawing so they are drawn only on top of the
+  background. They will have to be drawn from the following event or from 
+  closure function in order to respect the priorities.
+
+Wish list
+
+- Tool bar for the viewer so many actions can be done on the screen.
+
+- Ability to select events with the mouse : in a "event selection mode", the
+  mouse click would "redraw" the image virtually and select an event.
+  (just like selectionGL in OpenGL).
+
+- Shown more events if wanted.
+
+- Use filter to show additionnal events. (do not filter schedule events! 
+  The filtering should be applied to the additionnal events only). Note that it
+  require no change to filter : just do not make the filter apply on every
+  incoming events in the viewer's hooks.
+
+- Add vertical lines showing control flow between processes : it may become
+  confusing when working on multiple cpu.
+
+- Add a horizontal line showing the currently selected process. May be a
+  light dotted line, similar to the current time line, but with a different
+  color/pattern.
+
+- Add events customization window : make the user able to select the
+  text/icon/line color/background color/dots linked with any kind of
+  event. The framework is there, it must be completed. (the use of
+  Attributes to call hooks for every event type comes from there)
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/cfv.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/cfv.c
new file mode 100644 (file)
index 0000000..47ad080
--- /dev/null
@@ -0,0 +1,220 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <lttv/lttv.h>
+#include <lttvwindow/lttvwindow.h>
+
+#include "cfv.h"
+#include "drawing.h"
+#include "processlist.h"
+#include "eventhooks.h"
+
+extern GSList *g_control_flow_data_list;
+
+static gboolean
+header_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data)
+{
+  Drawing_t *drawing = (Drawing_t*)user_data;
+
+  gtk_widget_set_size_request(drawing->ruler, -1, allocation->height);
+  //gtk_widget_queue_resize(drawing->padding);
+  //gtk_widget_queue_resize(drawing->ruler);
+  gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
+  return 0;
+}
+
+
+/*****************************************************************************
+ *                     Control Flow Viewer class implementation              *
+ *****************************************************************************/
+/**
+ * Control Flow Viewer's constructor
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the drawing widget.
+ * @param ParentWindow A pointer to the parent window.
+ * @return The widget created.
+ */
+ControlFlowData *
+guicontrolflow(Tab *tab)
+{
+  GtkWidget *process_list_widget, *drawing_widget, *drawing_area;
+
+  ControlFlowData* control_flow_data = g_new(ControlFlowData,1) ;
+
+  control_flow_data->tab = tab;
+
+  control_flow_data->v_adjust = 
+    GTK_ADJUSTMENT(gtk_adjustment_new(  0.0,  /* Value */
+              0.0,  /* Lower */
+              0.0,  /* Upper */
+              0.0,  /* Step inc. */
+              0.0,  /* Page inc. */
+              0.0));  /* page size */
+
+  /* Create the drawing */
+  control_flow_data->drawing = drawing_construct(control_flow_data);
+  
+  drawing_widget = 
+    drawing_get_widget(control_flow_data->drawing);
+  
+  drawing_area = 
+    drawing_get_drawing_area(control_flow_data->drawing);
+
+  control_flow_data->number_of_process = 0;
+  control_flow_data->background_info_waiting = 0;
+
+  /* Create the Process list */
+  control_flow_data->process_list = processlist_construct();
+  
+  process_list_widget = 
+    processlist_get_widget(control_flow_data->process_list);
+  
+  gtk_tree_view_set_vadjustment(GTK_TREE_VIEW(process_list_widget),
+                                GTK_ADJUSTMENT(
+                                   control_flow_data->v_adjust));
+
+  g_signal_connect (G_OBJECT(control_flow_data->process_list->button),
+        "size-allocate",
+        G_CALLBACK(header_size_allocate),
+        (gpointer)control_flow_data->drawing);
+#if 0  /* not ready */
+  g_signal_connect (
+       // G_OBJECT(control_flow_data->process_list->process_list_widget),
+        G_OBJECT(control_flow_data->process_list->list_store),
+        "row-changed",
+        G_CALLBACK (tree_row_activated),
+        (gpointer)control_flow_data);
+#endif //0
+  
+  control_flow_data->h_paned = gtk_hpaned_new();
+  control_flow_data->box = gtk_event_box_new();
+  control_flow_data->top_widget = control_flow_data->box;
+  gtk_container_add(GTK_CONTAINER(control_flow_data->box),
+                    control_flow_data->h_paned);
+      
+  gtk_paned_pack1(GTK_PANED(control_flow_data->h_paned),
+                  process_list_widget, FALSE, TRUE);
+  gtk_paned_pack2(GTK_PANED(control_flow_data->h_paned),
+                  drawing_widget, TRUE, TRUE);
+  
+  gtk_container_set_border_width(GTK_CONTAINER(control_flow_data->box), 1);
+  
+  /* Set the size of the drawing area */
+  //drawing_Resize(drawing, h, w);
+
+  /* Get trace statistics */
+  //control_flow_data->Trace_Statistics = get_trace_statistics(Trace);
+
+  gtk_widget_show(drawing_widget);
+  gtk_widget_show(process_list_widget);
+  gtk_widget_show(control_flow_data->h_paned);
+  gtk_widget_show(control_flow_data->box);
+  
+  g_object_set_data_full(
+      G_OBJECT(control_flow_data->top_widget),
+      "control_flow_data",
+      control_flow_data,
+      (GDestroyNotify)guicontrolflow_destructor);
+    
+  g_object_set_data(
+      G_OBJECT(drawing_area),
+      "control_flow_data",
+      control_flow_data);
+        
+  g_control_flow_data_list = g_slist_append(
+      g_control_flow_data_list,
+      control_flow_data);
+
+  //WARNING : The widget must be 
+  //inserted in the main window before the drawing area
+  //can be configured (and this must happend bedore sending
+  //data)
+  
+  return control_flow_data;
+
+}
+
+/* Destroys widget also */
+void
+guicontrolflow_destructor_full(ControlFlowData *control_flow_data)
+{
+  g_info("CFV.c : guicontrolflow_destructor_full, %p", control_flow_data);
+  /* May already have been done by GTK window closing */
+  if(GTK_IS_WIDGET(guicontrolflow_get_widget(control_flow_data)))
+    gtk_widget_destroy(guicontrolflow_get_widget(control_flow_data));
+  //control_flow_data->mw = NULL;
+  //FIXME guicontrolflow_destructor(control_flow_data);
+}
+
+/* When this destructor is called, the widgets are already disconnected */
+void
+guicontrolflow_destructor(ControlFlowData *control_flow_data)
+{
+  Tab *tab = control_flow_data->tab;
+  
+  g_info("CFV.c : guicontrolflow_destructor, %p", control_flow_data);
+  g_info("%p, %p, %p", update_time_window_hook, control_flow_data, tab);
+  if(GTK_IS_WIDGET(guicontrolflow_get_widget(control_flow_data)))
+    g_info("widget still exists");
+  
+  /* Process List is removed with it's widget */
+  //ProcessList_destroy(control_flow_data->process_list);
+  if(tab != NULL)
+  {
+      /* Delete reading hooks */
+    lttvwindow_unregister_traceset_notify(tab,
+        traceset_notify,
+        control_flow_data);
+    
+    lttvwindow_unregister_time_window_notify(tab,
+        update_time_window_hook,
+        control_flow_data);
+  
+    lttvwindow_unregister_current_time_notify(tab,
+        update_current_time_hook,
+        control_flow_data);
+
+    lttvwindow_unregister_redraw_notify(tab, redraw_notify, control_flow_data);
+    lttvwindow_unregister_continue_notify(tab,
+                                          continue_notify,
+                                          control_flow_data);
+    
+    lttvwindow_events_request_remove_all(control_flow_data->tab,
+                                         control_flow_data);
+
+  }
+  lttvwindowtraces_background_notify_remove(control_flow_data);
+  g_control_flow_data_list = 
+         g_slist_remove(g_control_flow_data_list,control_flow_data);
+
+  g_info("CFV.c : guicontrolflow_destructor end, %p", control_flow_data);
+  g_free(control_flow_data);
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/cfv.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/cfv.h
new file mode 100644 (file)
index 0000000..31c42fd
--- /dev/null
@@ -0,0 +1,86 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+
+#ifndef _CFV_H
+#define _CFV_H
+
+#include <gtk/gtk.h>
+#include <lttvwindow/mainwindow.h>
+#include "processlist.h"
+
+extern GQuark LTT_NAME_CPU;
+
+
+#ifndef TYPE_DRAWING_T_DEFINED
+#define TYPE_DRAWING_T_DEFINED
+typedef struct _Drawing_t Drawing_t;
+#endif //TYPE_DRAWING_T_DEFINED
+
+#ifndef TYPE_CONTROLFLOWDATA_DEFINED
+#define TYPE_CONTROLFLOWDATA_DEFINED
+typedef struct _ControlFlowData ControlFlowData;
+#endif //TYPE_CONTROLFLOWDATA_DEFINED
+
+struct _ControlFlowData {
+
+  GtkWidget *top_widget;
+  Tab *tab;
+
+  GtkWidget *box; /* box that contains the hpaned. necessary for it to work */
+  GtkWidget *h_paned;
+
+  ProcessList *process_list;
+
+  Drawing_t *drawing;
+  GtkAdjustment *v_adjust ;
+
+  /* Shown events information */
+//  TimeWindow time_window;
+//  LttTime current_time;
+  
+  //guint currently_Selected_Event  ;
+  guint number_of_process;
+  guint background_info_waiting; /* Number of background requests waited for
+                                    in order to have all the info ready. */
+
+} ;
+
+/* Control Flow Data constructor */
+ControlFlowData *guicontrolflow(Tab *tab);
+void
+guicontrolflow_destructor_full(ControlFlowData *control_flow_data);
+void
+guicontrolflow_destructor(ControlFlowData *control_flow_data);
+
+static inline GtkWidget *guicontrolflow_get_widget(
+                                     ControlFlowData *control_flow_data)
+{
+  return control_flow_data->top_widget ;
+}
+
+static inline ProcessList *guicontrolflow_get_process_list
+    (ControlFlowData *control_flow_data)
+{
+    return control_flow_data->process_list ;
+}
+
+
+
+#endif // _CFV_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawing.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawing.c
new file mode 100644 (file)
index 0000000..94f8108
--- /dev/null
@@ -0,0 +1,1426 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <string.h>
+
+#include <ltt/trace.h>
+
+#include <lttv/lttv.h>
+#include <lttv/tracecontext.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttv/state.h>
+#include <lttv/hook.h>
+
+#include "drawing.h"
+#include "eventhooks.h"
+#include "cfv.h"
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+
+//FIXME
+#define TRACE_NUMBER 0
+#define EXTRA_ALLOC 1024 // pixels
+
+
+#if 0 /* colors for two lines representation */
+GdkColor drawing_colors[NUM_COLORS] =
+{ /* Pixel, R, G, B */
+  { 0, 0, 0, 0 }, /* COL_BLACK */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
+  { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
+  { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
+  { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
+  { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
+  { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
+  { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
+  { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
+  { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
+  { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
+  { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }  /* COL_MODE_UNKNOWN : white */
+
+};
+#endif //0
+
+
+GdkColor drawing_colors[NUM_COLORS] =
+{ /* Pixel, R, G, B */
+  { 0, 0, 0, 0 }, /* COL_BLACK */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
+  { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
+  { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
+  { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
+  { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : red */
+  { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
+  { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
+  { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
+  { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
+  { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */
+  { 0, 0xFFFF, 0xFFFF, 0xFFFF }  /* COL_UNNAMED : white */
+
+};
+
+/*
+RUN+USER MODE green
+RUN+SYSCALL
+RUN+TRAP
+RUN+IRQ
+WAIT+foncé
+WAIT CPU + WAIT FORK vert foncé ou jaune
+IRQ rouge
+TRAP: orange
+SYSCALL: bleu pâle
+
+ZOMBIE + WAIT EXIT
+*/
+
+
+/*****************************************************************************
+ *                              drawing functions                            *
+ *****************************************************************************/
+
+static gboolean
+expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
+
+static gboolean
+motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
+
+
+/* Function responsible for updating the exposed area.
+ * It must do an events request to the lttvwindow API to ask for this update.
+ * Note : this function cannot clear the background, because it may
+ * erase drawing already present (SAFETY).
+ */
+void drawing_data_request(Drawing_t *drawing,
+      gint x, gint y,
+      gint width,
+      gint height)
+{
+  if(width < 0) return ;
+  if(height < 0) return ;
+
+
+  Tab *tab = drawing->control_flow_data->tab;
+  TimeWindow time_window =
+              lttvwindow_get_time_window(tab);
+
+  ControlFlowData *control_flow_data = drawing->control_flow_data;
+  //    (ControlFlowData*)g_object_get_data(
+  //               G_OBJECT(drawing->drawing_area), "control_flow_data");
+
+  LttTime start, time_end;
+  LttTime window_end = time_window.end_time;
+
+  g_debug("req : window start_time : %lu, %lu", time_window.start_time.tv_sec, 
+                                       time_window.start_time.tv_nsec);
+
+  g_debug("req : window time width : %lu, %lu", time_window.time_width.tv_sec, 
+                                       time_window.time_width.tv_nsec);
+  
+  g_debug("req : window_end : %lu, %lu", window_end.tv_sec, 
+                                       window_end.tv_nsec);
+
+  g_debug("x is : %i, x+width is : %i", x, x+width);
+
+  convert_pixels_to_time(drawing->width, x,
+        time_window,
+        &start);
+
+  convert_pixels_to_time(drawing->width, x+width,
+        time_window,
+        &time_end);
+  time_end = ltt_time_add(time_end, ltt_time_one); // because main window
+                                                   // doesn't deliver end time.
+
+  lttvwindow_events_request_remove_all(tab,
+                                       control_flow_data);
+
+  {
+    /* find the tracehooks */
+    LttvTracesetContext *tsc = lttvwindow_get_traceset_context(tab);
+
+    LttvTraceset *traceset = tsc->ts;
+
+    guint i, k, l, nb_trace;
+
+    LttvTraceState *ts;
+
+    LttvTracefileState *tfs;
+
+    GArray *hooks;
+
+    LttvTraceHook *hook;
+
+    LttvTraceHookByFacility *thf;
+
+    guint ret;
+
+    nb_trace = lttv_traceset_number(traceset);
+    // FIXME : eventually request for more traces
+    // for(i = 0 ; i < nb_trace ; i++) {
+    for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++)
+    {
+      EventsRequest *events_request = g_new(EventsRequest, 1);
+      // Create the hooks
+      //LttvHooks *event = lttv_hooks_new();
+      LttvHooksById *event_by_id = lttv_hooks_by_id_new();
+      LttvHooks *before_chunk_traceset = lttv_hooks_new();
+      LttvHooks *after_chunk_traceset = lttv_hooks_new();
+      LttvHooks *before_request_hook = lttv_hooks_new();
+      LttvHooks *after_request_hook = lttv_hooks_new();
+
+      lttv_hooks_add(before_chunk_traceset,
+                     before_chunk,
+                     events_request,
+                     LTTV_PRIO_DEFAULT);
+
+      lttv_hooks_add(after_chunk_traceset,
+                     after_chunk,
+                     events_request,
+                     LTTV_PRIO_DEFAULT);
+
+      lttv_hooks_add(before_request_hook,
+                     before_request,
+                     events_request,
+                     LTTV_PRIO_DEFAULT);
+
+      lttv_hooks_add(after_request_hook,
+                     after_request,
+                     events_request,
+                     LTTV_PRIO_DEFAULT);
+
+
+      ts = (LttvTraceState *)tsc->traces[i];
+
+      /* Find the eventtype id for the following events and register the
+         associated by id hooks. */
+
+      hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+      hooks = g_array_set_size(hooks, 13);
+
+      /* before hooks */
+      
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+          LTT_FIELD_SYSCALL_ID, 0, 0,
+          before_execmode_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 0));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_EXIT,
+          0, 0, 0,
+          before_execmode_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 1));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
+          LTT_FIELD_TRAP_ID, 0, 0,
+          before_execmode_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 2));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
+          0, 0, 0, 
+          before_execmode_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 3));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
+          LTT_FIELD_IRQ_ID, 0, 0,
+          before_execmode_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 4));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
+          0, 0, 0, 
+          before_execmode_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 5));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
+          LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
+          before_schedchange_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 6));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
+          LTT_FIELD_PID, 0, 0,
+          before_process_exit_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 7));
+      g_assert(!ret);
+      
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
+          LTT_FIELD_PID, 0, 0,
+          before_process_release_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 8));
+      g_assert(!ret);
+
+
+#if 0
+      lttv_trace_find_hook(ts->parent.t,
+          "core", "process", "event_sub_id", 
+          "event_data1", "event_data2", before_process_hook,
+          &g_array_index(hooks, LttvTraceHook, 7));
+#endif //0
+#if 0
+      lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid", 
+          NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
+
+      lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL, 
+          NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
+#endif //0
+
+      /* after hooks */
+      
+#if 0
+      /**** DESACTIVATED ****/
+      lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id", 
+    NULL, NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 8));
+      /**** DESACTIVATED ****/
+      lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL, 
+          NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 9));
+
+      /**** DESACTIVATED ****/
+      lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
+    NULL, NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 10));
+
+      /**** DESACTIVATED ****/
+      lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL, 
+          after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 11));
+
+      /**** DESACTIVATED ****/
+      lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL, 
+          NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 12));
+
+      /**** DESACTIVATED ****/
+      lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL, 
+          after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 13));
+#endif //0
+#if 0
+      lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out", 
+        "out_state", after_schedchange_hook, 
+        &g_array_index(hooks, LttvTraceHook, 8));
+
+      lttv_trace_find_hook(ts->parent.t, "core", "process", "event_sub_id", 
+          "event_data1", "event_data2", after_process_hook,
+          &g_array_index(hooks, LttvTraceHook, 9));
+#endif //0
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
+          LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
+          after_schedchange_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 9));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
+          LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
+          after_process_fork_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 10));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
+          LTT_FIELD_PID, 0, 0,
+          after_process_exit_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 11));
+      g_assert(!ret);
+
+      ret = lttv_trace_find_hook(ts->parent.t,
+          LTT_FACILITY_FS, LTT_EVENT_EXEC,
+          0, 0, 0,
+          after_fs_exec_hook,
+          events_request,
+          &g_array_index(hooks, LttvTraceHook, 12));
+      g_assert(!ret);
+
+
+
+#if 0
+      lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid", 
+          NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
+
+      lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL, 
+          NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
+#endif //0
+
+
+      
+      /* Add these hooks to each event_by_id hooks list */
+      /* add before */
+      for(k = 0 ; k < 9 ; k++) {
+        hook = &g_array_index(hooks, LttvTraceHook, k);
+        for(l=0;l<hook->fac_list->len;l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_add(lttv_hooks_by_id_find(event_by_id, thf->id),
+                          thf->h,
+                          thf,
+                          LTTV_PRIO_STATE-5);
+        }
+      }
+
+      /* add after */
+      for(k = 9 ; k < 13 ; k++) {
+        hook = &g_array_index(hooks, LttvTraceHook, k);
+        for(l=0;l<hook->fac_list->len;l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_add(lttv_hooks_by_id_find(event_by_id, thf->id),
+                         thf->h,
+                         thf,
+                         LTTV_PRIO_STATE+5);
+        }
+      }
+      
+      events_request->hooks = hooks;
+
+      // Fill the events request
+      events_request->owner = control_flow_data;
+      events_request->viewer_data = control_flow_data;
+      events_request->servicing = FALSE;
+      events_request->start_time = start;
+      events_request->start_position = NULL;
+      events_request->stop_flag = FALSE;
+      events_request->end_time = time_end;
+      events_request->num_events = G_MAXUINT;
+      events_request->end_position = NULL;
+      events_request->trace = i;    /* FIXME */
+      events_request->before_chunk_traceset = before_chunk_traceset;
+      events_request->before_chunk_trace = NULL;
+      events_request->before_chunk_tracefile = NULL;
+      events_request->event = NULL;
+      events_request->event_by_id = event_by_id;
+      events_request->after_chunk_tracefile = NULL;
+      events_request->after_chunk_trace = NULL;
+      events_request->after_chunk_traceset = after_chunk_traceset;
+      events_request->before_request = before_request_hook;
+      events_request->after_request = after_request_hook;
+
+      g_debug("req : start : %lu, %lu", start.tv_sec, 
+                                          start.tv_nsec);
+
+      g_debug("req : end : %lu, %lu", time_end.tv_sec, 
+                                         time_end.tv_nsec);
+
+      lttvwindow_events_request(tab, events_request);
+
+    }
+
+  }
+
+#if 0
+  lttv_hooks_add(event,
+                 before_schedchange_hook,
+                 events_request,
+                 LTTV_PRIO_STATE-5);
+  lttv_hooks_add(event,
+                 after_schedchange_hook,
+                 events_request,
+                 LTTV_PRIO_STATE+5);
+  lttv_hooks_add(event,
+                 before_execmode_hook,
+                 events_request,
+                 LTTV_PRIO_STATE-5);
+  lttv_hooks_add(event,
+                 after_execmode_hook,
+                 events_request,
+                 LTTV_PRIO_STATE+5);
+  lttv_hooks_add(event,
+                 before_process_hook,
+                 events_request,
+                 LTTV_PRIO_STATE-5);
+  lttv_hooks_add(event,
+                 after_process_hook,
+                 events_request,
+                 LTTV_PRIO_STATE+5);
+#endif //0
+
+}
+
+static void set_last_start(gpointer key, gpointer value, gpointer user_data)
+{
+  ProcessInfo *process_info = (ProcessInfo*)key;
+  HashedProcessData *hashed_process_data = (HashedProcessData*)value;
+  guint x = (guint)user_data;
+
+  hashed_process_data->x.over = x;
+  hashed_process_data->x.over_used = FALSE;
+  hashed_process_data->x.over_marked = FALSE;
+  hashed_process_data->x.middle = x;
+  hashed_process_data->x.middle_used = FALSE;
+  hashed_process_data->x.middle_marked = FALSE;
+  hashed_process_data->x.under = x;
+  hashed_process_data->x.under_used = FALSE;
+  hashed_process_data->x.under_marked = FALSE;
+  hashed_process_data->next_good_time = ltt_time_zero;
+
+  return;
+}
+
+void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss)
+{
+  g_debug("Begin of data request");
+  ControlFlowData *cfd = events_request->viewer_data;
+  LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
+  TimeWindow time_window = 
+    lttvwindow_get_time_window(cfd->tab);
+
+  guint width = cfd->drawing->width;
+  guint x=0;
+
+  cfd->drawing->last_start = events_request->start_time;
+
+  convert_time_to_pixels(
+          time_window,
+          events_request->start_time,
+          width,
+          &x);
+
+  g_hash_table_foreach(cfd->process_list->process_hash, set_last_start,
+                            (gpointer)x);
+
+}
+
+void drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss)
+{
+  g_debug("Begin of chunk");
+  ControlFlowData *cfd = events_request->viewer_data;
+  LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
+  //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
+  guint num_cpu = 
+    ltt_trace_get_num_cpu(tss->parent.traces[TRACE_NUMBER]->t);
+
+  cfd->process_list->current_hash_data = g_new(HashedProcessData*,num_cpu);
+  memset(cfd->process_list->current_hash_data, 0,
+         sizeof(HashedProcessData*)*num_cpu);
+  //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
+  //                                        events_request->end_time);
+}
+
+
+void drawing_request_expose(EventsRequest *events_request,
+                            LttvTracesetState *tss,
+                            LttTime end_time)
+{
+  gint x, x_end, width;
+
+  ControlFlowData *cfd = events_request->viewer_data;
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+  Drawing_t *drawing = cfd->drawing;
+  
+  TimeWindow time_window = 
+        lttvwindow_get_time_window(cfd->tab);
+
+  g_debug("request expose");
+  
+  convert_time_to_pixels(
+        time_window,
+        end_time,
+        drawing->width,
+        &x_end);
+  x = drawing->damage_begin;
+
+  width = x_end - x;
+
+  drawing->damage_begin = x+width;
+
+  // FIXME ?
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               x, 0,
+                               width, drawing->drawing_area->allocation.height);
+  /* Update directly when scrolling */
+  gdk_window_process_updates(drawing->drawing_area->window,
+      TRUE);
+}
+
+
+/* Callbacks */
+
+
+/* Create a new backing pixmap of the appropriate size */
+/* As the scaling will always change, it's of no use to copy old
+ * pixmap.
+ *
+ * Only change the size if width changes. The height is specified and changed
+ * when process ID are added or removed from the process list.
+ */
+static gboolean
+configure_event( GtkWidget *widget, GdkEventConfigure *event, 
+    gpointer user_data)
+{
+  Drawing_t *drawing = (Drawing_t*)user_data;
+
+
+  /* First, get the new time interval of the main window */
+  /* we assume (see documentation) that the main window
+   * has updated the time interval before this configure gets
+   * executed.
+   */
+  //lttvwindow_get_time_window(drawing->control_flow_data->mw,
+  //      &drawing->control_flow_data->time_window);
+  
+  /* New pixmap, size of the configure event */
+  //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
+  //      widget->allocation.width + SAFETY,
+  //      widget->allocation.height + SAFETY,
+  //      -1);
+  
+  if(widget->allocation.width != drawing->width) {
+    g_debug("drawing configure event");
+    g_debug("New alloc draw size : %i by %i",widget->allocation.width,
+                                    widget->allocation.height);
+  
+    drawing->width = widget->allocation.width;
+    
+    if(drawing->alloc_width < widget->allocation.width) {
+      //if(drawing->pixmap)
+      //  gdk_pixmap_unref(drawing->pixmap);
+
+      //drawing->pixmap = gdk_pixmap_new(widget->window,
+      //                                 drawing->width + SAFETY + EXTRA_ALLOC,
+      //                                 drawing->height + EXTRA_ALLOC,
+      //                                 -1);
+      drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
+      drawing->alloc_height = drawing->height + EXTRA_ALLOC;
+      update_pixmap_size(drawing->control_flow_data->process_list,
+                         drawing->alloc_width);
+      update_index_to_pixmap(drawing->control_flow_data->process_list);
+    }
+    //drawing->height = widget->allocation.height;
+
+    //ProcessList_get_height
+    // (GuiControlFlow_get_process_list(drawing->control_flow_data)),
+    
+
+    // Clear the image
+    //gdk_draw_rectangle (drawing->pixmap,
+    //      widget->style->black_gc,
+    //      TRUE,
+    //      0, 0,
+    //      drawing->width+SAFETY,
+    //      drawing->height);
+
+    //g_info("init data request");
+
+
+    /* Initial data request */
+    /* no, do initial data request in the expose event */
+    // Do not need to ask for data of 1 pixel : not synchronized with
+    // main window time at this moment.
+    //drawing_data_request(drawing, &drawing->pixmap, 0, 0,
+    //    widget->allocation.width,
+    //    widget->allocation.height);
+                          
+    //drawing->width = widget->allocation.width;
+    //drawing->height = widget->allocation.height;
+  
+    drawing->damage_begin = 0;
+    drawing->damage_end = widget->allocation.width;
+
+    if((widget->allocation.width != 1 &&
+        widget->allocation.height != 1)
+        && drawing->damage_begin < drawing->damage_end)
+    {
+
+      rectangle_pixmap (drawing->control_flow_data->process_list,
+        drawing->drawing_area->style->black_gc,
+        TRUE,
+        0, 0,
+        drawing->alloc_width, // do not overlap
+        -1);
+
+
+      drawing_data_request(drawing,
+                           drawing->damage_begin,
+                           0,
+                           drawing->damage_end - drawing->damage_begin,
+                           drawing->height);
+    }
+  }
+  return TRUE;
+}
+
+
+/* Redraw the screen from the backing pixmap */
+static gboolean
+expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  Drawing_t *drawing = (Drawing_t*)user_data;
+
+  ControlFlowData *control_flow_data =
+      (ControlFlowData*)g_object_get_data(
+                G_OBJECT(widget),
+                "control_flow_data");
+#if 0
+  if(unlikely(drawing->gc == NULL)) {
+    drawing->gc = gdk_gc_new(drawing->drawing_area->window);
+    gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc);
+  }
+#endif //0
+  TimeWindow time_window = 
+      lttvwindow_get_time_window(control_flow_data->tab);
+  LttTime current_time = 
+      lttvwindow_get_current_time(control_flow_data->tab);
+
+  guint cursor_x=0;
+
+  LttTime window_end = time_window.end_time;
+
+  /* update the screen from the pixmap buffer */
+#if 0
+  gdk_draw_pixmap(widget->window,
+      widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+      drawing->pixmap,
+      event->area.x, event->area.y,
+      event->area.x, event->area.y,
+      event->area.width, event->area.height);
+#endif //0
+  drawing->height = processlist_get_height(control_flow_data->process_list);
+#if 0
+  copy_pixmap_to_screen(control_flow_data->process_list,
+                        widget->window,
+                        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                        event->area.x, event->area.y,
+                        event->area.width, event->area.height);
+#endif //0
+  copy_pixmap_to_screen(control_flow_data->process_list,
+                        widget->window,
+                        drawing->gc,
+                        event->area.x, event->area.y,
+                        event->area.width, event->area.height);
+                        
+  
+  /* Erase the dotted lines left.. */
+  if(widget->allocation.height > drawing->height)
+  {
+    gdk_draw_rectangle (widget->window,
+      drawing->drawing_area->style->black_gc,
+      TRUE,
+      event->area.x, drawing->height,
+      event->area.width,  // do not overlap
+      widget->allocation.height - drawing->height);
+  }
+  if(ltt_time_compare(time_window.start_time, current_time) <= 0 &&
+           ltt_time_compare(window_end, current_time) >= 0)
+  {
+    /* Draw the dotted lines */
+    convert_time_to_pixels(
+          time_window,
+          current_time,
+          drawing->width,
+          &cursor_x);
+
+#if 0
+    if(drawing->dotted_gc == NULL) {
+
+      drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window);
+      gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc);
+   
+      gint8 dash_list[] = { 1, 2 };
+      gdk_gc_set_line_attributes(drawing->dotted_gc,
+                                 1,
+                                 GDK_LINE_ON_OFF_DASH,
+                                 GDK_CAP_BUTT,
+                                 GDK_JOIN_MITER);
+      gdk_gc_set_dashes(drawing->dotted_gc,
+                        0,
+                        dash_list,
+                        2);
+    }
+#endif //0
+    gint height_tot = MAX(widget->allocation.height, drawing->height);
+    gdk_draw_line(widget->window,
+                  drawing->dotted_gc,
+                  cursor_x, 0,
+                  cursor_x, height_tot);
+  }
+  return FALSE;
+}
+
+static gboolean
+after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  //g_assert(0);
+  g_debug("AFTER EXPOSE");
+
+  return FALSE;
+
+
+}
+
+#if 0
+void
+tree_row_activated(GtkTreeModel *treemodel,
+                   GtkTreePath *arg1,
+                   GtkTreeViewColumn *arg2,
+                   gpointer user_data)
+{
+  ControlFlowData *cfd = (ControlFlowData*)user_data;
+  Drawing_t *drawing = cfd->drawing;
+  GtkTreeView *treeview = cfd->process_list->process_list_widget;
+  gint *path_indices;
+  gint height;
+  
+  path_indices =  gtk_tree_path_get_indices (arg1);
+
+  height = get_cell_height(cfd->process_list,
+        GTK_TREE_VIEW(treeview));
+  drawing->horizontal_sel = height * path_indices[0];
+  g_critical("new hor sel : %i", drawing->horizontal_sel);
+}
+#endif //0
+
+/* mouse click */
+static gboolean
+button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
+{
+  ControlFlowData *control_flow_data =
+      (ControlFlowData*)g_object_get_data(
+                G_OBJECT(widget),
+                "control_flow_data");
+  Drawing_t *drawing = control_flow_data->drawing;
+  TimeWindow time_window =
+               lttvwindow_get_time_window(control_flow_data->tab);
+
+  g_debug("click");
+  if(event->button == 1)
+  {
+    LttTime time;
+
+    /* left mouse button click */
+    g_debug("x click is : %f", event->x);
+
+    convert_pixels_to_time(drawing->width, (guint)event->x,
+        time_window,
+        &time);
+
+    lttvwindow_report_current_time(control_flow_data->tab, time);
+
+  }
+
+  return FALSE;
+}
+
+static gboolean
+scrollbar_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data)
+{
+  Drawing_t *drawing = (Drawing_t*)user_data;
+
+  gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
+  //gtk_widget_queue_resize(drawing->padding);
+  //gtk_widget_queue_resize(drawing->ruler);
+  gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
+  return 0;
+}
+
+
+
+Drawing_t *drawing_construct(ControlFlowData *control_flow_data)
+{
+  Drawing_t *drawing = g_new(Drawing_t, 1);
+  
+  drawing->control_flow_data = control_flow_data;
+
+  drawing->vbox = gtk_vbox_new(FALSE, 1);
+
+  
+  drawing->ruler_hbox = gtk_hbox_new(FALSE, 1);
+  drawing->ruler = gtk_drawing_area_new ();
+  //gtk_widget_set_size_request(drawing->ruler, -1, 27);
+  
+  drawing->padding = gtk_drawing_area_new ();
+  //gtk_widget_set_size_request(drawing->padding, -1, 27);
+  gtk_box_pack_start(GTK_BOX(drawing->ruler_hbox), drawing->ruler, 
+                     TRUE, TRUE, 0);
+  gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->padding, 
+                     FALSE, FALSE, 0);
+  
+
+
+  drawing->drawing_area = gtk_drawing_area_new ();
+  
+  drawing->gc = NULL;
+  
+  drawing->hbox = gtk_hbox_new(FALSE, 1);
+  drawing->viewport = gtk_viewport_new(NULL, control_flow_data->v_adjust);
+  drawing->scrollbar = gtk_vscrollbar_new(control_flow_data->v_adjust);
+  gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport, 
+                     TRUE, TRUE, 0);
+  gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar, 
+                     FALSE, FALSE, 0);
+  
+  //drawing->scrolled_window =
+  //    gtk_scrolled_window_new (NULL,
+  //    control_flow_data->v_adjust);
+  
+  //gtk_scrolled_window_set_policy(
+  //  GTK_SCROLLED_WINDOW(drawing->scrolled_window),
+  //  GTK_POLICY_NEVER,
+  //  GTK_POLICY_AUTOMATIC);
+
+  gtk_container_add(GTK_CONTAINER(drawing->viewport),
+                    drawing->drawing_area);
+  //gtk_scrolled_window_add_with_viewport(
+  //  GTK_SCROLLED_WINDOW(drawing->scrolled_window),
+  //  drawing->drawing_area);
+
+  gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox, 
+                     FALSE, FALSE, 0);
+  gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->hbox,
+                   TRUE, TRUE, 0);
+  
+  drawing->pango_layout =
+    gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
+
+  drawing->height = 1;
+  drawing->width = 1;
+  drawing->depth = 0;
+  drawing->alloc_height = 1;
+  drawing->alloc_width = 1;
+  
+  drawing->damage_begin = 0;
+  drawing->damage_end = 0;
+  drawing->horizontal_sel = -1;
+  
+  //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
+  g_object_set_data_full(
+      G_OBJECT(drawing->drawing_area),
+      "Link_drawing_Data",
+      drawing,
+      (GDestroyNotify)drawing_destroy);
+
+  g_object_set_data(
+      G_OBJECT(drawing->ruler),
+      "drawing",
+      drawing);
+
+
+  //gtk_widget_modify_bg( drawing->drawing_area,
+  //      GTK_STATE_NORMAL,
+  //      &CF_Colors[BLACK]);
+  
+  //gdk_window_get_geometry(drawing->drawing_area->window,
+  //    NULL, NULL,
+  //    &(drawing->width),
+  //    &(drawing->height),
+  //    -1);
+  
+  //drawing->pixmap = gdk_pixmap_new(
+  //    drawing->drawing_area->window,
+  //    drawing->width,
+  //    drawing->height,
+  //    drawing->depth);
+  
+  //drawing->pixmap = NULL;
+
+//  drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+//        drawing->drawing_area->allocation.width,
+//        drawing->drawing_area->allocation.height,
+//        -1);
+
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "configure_event",
+        G_CALLBACK (configure_event),
+        (gpointer)drawing);
+  g_signal_connect (G_OBJECT(drawing->ruler),
+        "expose_event",
+        G_CALLBACK(expose_ruler),
+        (gpointer)drawing);
+
+  gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK);
+
+  g_signal_connect (G_OBJECT(drawing->ruler),
+        "motion-notify-event",
+        G_CALLBACK(motion_notify_ruler),
+        (gpointer)drawing);
+
+
+  g_signal_connect (G_OBJECT(drawing->scrollbar),
+        "size-allocate",
+        G_CALLBACK(scrollbar_size_allocate),
+        (gpointer)drawing);
+
+
+
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "expose_event",
+        G_CALLBACK (expose_event),
+        (gpointer)drawing);
+
+  g_signal_connect_after (G_OBJECT(drawing->drawing_area),
+        "expose_event",
+        G_CALLBACK (after_expose_event),
+        (gpointer)drawing);
+
+  g_signal_connect (G_OBJECT(drawing->drawing_area),
+        "button-press-event",
+        G_CALLBACK (button_press_event),
+        (gpointer)drawing);
+  
+  gtk_widget_show(drawing->ruler);
+  gtk_widget_show(drawing->padding);
+  gtk_widget_show(drawing->ruler_hbox);
+
+  gtk_widget_show(drawing->drawing_area);
+  //gtk_widget_show(drawing->scrolled_window);
+  gtk_widget_show(drawing->viewport);
+  gtk_widget_show(drawing->scrollbar);
+  gtk_widget_show(drawing->hbox);
+
+  /* Allocate the colors */
+  GdkColormap* colormap = gdk_colormap_get_system();
+  gboolean success[NUM_COLORS];
+  gdk_colormap_alloc_colors(colormap, drawing_colors, NUM_COLORS, FALSE,
+                            TRUE, success);
+  
+  drawing->gc =
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
+  drawing->dotted_gc =
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
+
+  gdk_gc_copy(drawing->gc,
+      main_window_get_widget(control_flow_data->tab)->style->black_gc);
+  gdk_gc_copy(drawing->dotted_gc,
+      main_window_get_widget(control_flow_data->tab)->style->white_gc);
+  
+  gint8 dash_list[] = { 1, 2 };
+  gdk_gc_set_line_attributes(drawing->dotted_gc,
+                             1,
+                             GDK_LINE_ON_OFF_DASH,
+                             GDK_CAP_BUTT,
+                             GDK_JOIN_MITER);
+  gdk_gc_set_dashes(drawing->dotted_gc,
+                    0,
+                    dash_list,
+                    2);
+
+  drawing->ruler_gc_butt = 
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
+  gdk_gc_copy(drawing->ruler_gc_butt, 
+      main_window_get_widget(control_flow_data->tab)->style->black_gc);
+  drawing->ruler_gc_round = 
+    gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
+  gdk_gc_copy(drawing->ruler_gc_round, 
+      main_window_get_widget(control_flow_data->tab)->style->black_gc);
+
+
+  gdk_gc_set_line_attributes(drawing->ruler_gc_butt,
+                               2,
+                               GDK_LINE_SOLID,
+                               GDK_CAP_BUTT,
+                               GDK_JOIN_MITER);
+
+  gdk_gc_set_line_attributes(drawing->ruler_gc_round,
+                             2,
+                             GDK_LINE_SOLID,
+                             GDK_CAP_ROUND,
+                             GDK_JOIN_ROUND);
+
+  
+  return drawing;
+}
+
+void drawing_destroy(Drawing_t *drawing)
+{
+  g_info("drawing_destroy %p", drawing);
+
+  /* Free the colors */
+  GdkColormap* colormap = gdk_colormap_get_system();
+
+  gdk_colormap_free_colors(colormap, drawing_colors, NUM_COLORS);
+  
+
+
+  // Do not unref here, Drawing_t destroyed by it's widget.
+  //g_object_unref( G_OBJECT(drawing->drawing_area));
+  if(drawing->gc != NULL)
+    gdk_gc_unref(drawing->gc);
+  
+  g_free(drawing->pango_layout);
+  if(drawing->dotted_gc != NULL) gdk_gc_unref(drawing->dotted_gc);
+  if(drawing->ruler_gc_butt != NULL) gdk_gc_unref(drawing->ruler_gc_butt);
+  if(drawing->ruler_gc_round != NULL) gdk_gc_unref(drawing->ruler_gc_round);
+
+  g_free(drawing);
+  g_info("drawing_destroy end");
+}
+
+GtkWidget *drawing_get_drawing_area(Drawing_t *drawing)
+{
+  return drawing->drawing_area;
+}
+
+GtkWidget *drawing_get_widget(Drawing_t *drawing)
+{
+  return drawing->vbox;
+}
+
+void drawing_draw_line( Drawing_t *drawing,
+      GdkPixmap *pixmap,
+      guint x1, guint y1,
+      guint x2, guint y2,
+      GdkGC *GC)
+{
+  gdk_draw_line (pixmap,
+      GC,
+      x1, y1, x2, y2);
+}
+
+void drawing_clear(Drawing_t *drawing)
+{ 
+  //if (drawing->pixmap)
+  //  gdk_pixmap_unref(drawing->pixmap);
+  ControlFlowData *cfd = drawing->control_flow_data;
+
+  
+  rectangle_pixmap(cfd->process_list,
+      drawing->drawing_area->style->black_gc,
+      TRUE,
+      0, 0,
+      drawing->alloc_width,  // do not overlap
+      -1);
+  
+  //drawing->height = 1;
+  /* Allocate a new pixmap with new height */
+  //drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+  //                                 drawing->width + SAFETY + EXTRA_ALLOC,
+  //                                 drawing->height + EXTRA_ALLOC,
+  //                                   -1);
+  //drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
+  //drawing->alloc_height = drawing->height + EXTRA_ALLOC;
+
+  //gtk_widget_set_size_request(drawing->drawing_area,
+  //                           -1,
+  //                           drawing->height);
+  //gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
+  
+  /* ask for the buffer to be redrawn */
+  gtk_widget_queue_draw ( drawing->drawing_area);
+}
+
+#if 0
+/* Insert a square corresponding to a new process in the list */
+/* Applies to whole drawing->width */
+void drawing_insert_square(Drawing_t *drawing,
+        guint y,
+        guint height)
+{
+  //GdkRectangle update_rect;
+  gboolean reallocate = FALSE;
+  GdkPixmap *new_pixmap;
+
+  /* Allocate a new pixmap with new height */
+  if(drawing->alloc_height < drawing->height + height) {
+
+    new_pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+                                     drawing->width + SAFETY + EXTRA_ALLOC,
+                                     drawing->height + height + EXTRA_ALLOC,
+                                     -1);
+    drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
+    drawing->alloc_height = drawing->height + height + EXTRA_ALLOC;
+    reallocate = TRUE;
+
+    /* Copy the high region */
+    gdk_draw_pixmap (new_pixmap,
+      drawing->drawing_area->style->black_gc,
+      drawing->pixmap,
+      0, 0,
+      0, 0,
+      drawing->width + SAFETY, y);
+
+  } else {
+    new_pixmap = drawing->pixmap;
+  }
+
+  //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
+  //      drawing->width + SAFETY,
+  //      drawing->height + height,
+  //      -1);
+  
+  /* add an empty square */
+  gdk_draw_rectangle (new_pixmap,
+    drawing->drawing_area->style->black_gc,
+    TRUE,
+    0, y,
+    drawing->width + SAFETY,  // do not overlap
+    height);
+
+  /* copy the bottom of the region */
+  gdk_draw_pixmap (new_pixmap,
+    drawing->drawing_area->style->black_gc,
+    drawing->pixmap,
+    0, y,
+    0, y + height,
+    drawing->width+SAFETY, drawing->height - y);
+
+
+  if(reallocate && likely(drawing->pixmap)) {
+    gdk_pixmap_unref(drawing->pixmap);
+    drawing->pixmap = new_pixmap;
+  }
+  
+  if(unlikely(drawing->height==1)) drawing->height = height;
+  else drawing->height += height;
+  
+  gtk_widget_set_size_request(drawing->drawing_area,
+                             -1,
+                             drawing->height);
+  gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
+  
+  /* ask for the buffer to be redrawn */
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               0, y,
+                               drawing->width, drawing->height-y);
+}
+
+
+/* Remove a square corresponding to a removed process in the list */
+void drawing_remove_square(Drawing_t *drawing,
+        guint y,
+        guint height)
+{
+  GdkPixmap *pixmap;
+
+  if(unlikely((guint)drawing->height == height)) {
+    //pixmap = gdk_pixmap_new(
+    //    drawing->drawing_area->window,
+    //    drawing->width + SAFETY,
+    //    1,
+    //    -1);
+    pixmap = drawing->pixmap;
+    drawing->height=1;
+  } else {
+    /* Allocate a new pixmap with new height */
+     //pixmap = gdk_pixmap_new(
+     //   drawing->drawing_area->window,
+     //   drawing->width + SAFETY,
+     //   drawing->height - height,
+     //   -1);
+     /* Keep the same preallocated pixmap */
+    pixmap = drawing->pixmap;
+   
+    /* Copy the high region */
+    gdk_draw_pixmap (pixmap,
+      drawing->drawing_area->style->black_gc,
+      drawing->pixmap,
+      0, 0,
+      0, 0,
+      drawing->width + SAFETY, y);
+
+    /* Copy up the bottom of the region */
+    gdk_draw_pixmap (pixmap,
+      drawing->drawing_area->style->black_gc,
+      drawing->pixmap,
+      0, y + height,
+      0, y,
+      drawing->width, drawing->height - y - height);
+
+    drawing->height-=height;
+  }
+
+  //if(likely(drawing->pixmap))
+  //  gdk_pixmap_unref(drawing->pixmap);
+
+  //drawing->pixmap = pixmap;
+  
+  gtk_widget_set_size_request(drawing->drawing_area,
+                             -1,
+                             drawing->height);
+  gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
+  /* ask for the buffer to be redrawn */
+  gtk_widget_queue_draw_area ( drawing->drawing_area,
+                               0, y,
+                               drawing->width, MAX(drawing->height-y, 1));
+}
+#endif //0
+
+void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window)
+{
+  GtkRequisition req;
+  GdkRectangle rect;
+  
+  req.width = drawing->ruler->allocation.width;
+  req.height = drawing->ruler->allocation.height;
+
+  rect.x = 0;
+  rect.y = 0;
+  rect.width = req.width;
+  rect.height = req.height;
+
+  gtk_widget_queue_draw(drawing->ruler);
+  //gtk_widget_draw( drawing->ruler, &rect);
+}
+
+/* Redraw the ruler */
+static gboolean
+expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
+{
+  Drawing_t *drawing = (Drawing_t*)user_data;
+  TimeWindow time_window = lttvwindow_get_time_window(drawing->control_flow_data->tab);
+  gchar text[255];
+  
+  PangoContext *context;
+  PangoLayout *layout;
+  PangoFontDescription *FontDesc;
+  PangoRectangle ink_rect;
+  gint global_width=0;
+  GdkColor foreground = { 0, 0, 0, 0 };
+  GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
+
+  LttTime window_end = time_window.end_time;
+  LttTime half_width =
+    ltt_time_div(time_window.time_width,2.0);
+  LttTime window_middle =
+    ltt_time_add(half_width,
+                 time_window.start_time);
+  g_debug("ruler expose event");
+  gdk_draw_rectangle (drawing->ruler->window,
+          drawing->ruler->style->white_gc,
+          TRUE,
+          event->area.x, event->area.y,
+          event->area.width,
+          event->area.height);
+
+  gdk_draw_line (drawing->ruler->window,
+                  drawing->ruler_gc_butt,
+                  event->area.x, 1,
+                  event->area.x + event->area.width, 1);
+
+
+  snprintf(text, 255, "%lus\n%luns",
+    time_window.start_time.tv_sec,
+    time_window.start_time.tv_nsec);
+
+  layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
+
+  context = pango_layout_get_context(layout);
+  FontDesc = pango_context_get_font_description(context);
+
+  pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
+  pango_layout_context_changed(layout);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_width += ink_rect.width;
+
+  gdk_draw_layout_with_colors(drawing->ruler->window,
+      drawing->ruler_gc_butt,
+      0,
+      6,
+      layout, &foreground, &background);
+
+  gdk_draw_line (drawing->ruler->window,
+                   drawing->ruler_gc_round,
+                   1, 1,
+                   1, 7);
+
+
+  snprintf(text, 255, "%lus\n%luns", window_end.tv_sec,
+                                     window_end.tv_nsec);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_width += ink_rect.width;
+
+  if(global_width <= drawing->ruler->allocation.width)
+  {
+    gdk_draw_layout_with_colors(drawing->ruler->window,
+      drawing->ruler_gc_butt,
+      drawing->ruler->allocation.width - ink_rect.width,
+      6,
+      layout, &foreground, &background);
+
+    gdk_draw_line (drawing->ruler->window,
+                   drawing->ruler_gc_butt,
+                   drawing->ruler->allocation.width-1, 1,
+                   drawing->ruler->allocation.width-1, 7);
+  }
+
+
+  snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec,
+                                     window_middle.tv_nsec);
+
+  pango_layout_set_text(layout, text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+  global_width += ink_rect.width;
+
+  if(global_width <= drawing->ruler->allocation.width)
+  {
+    gdk_draw_layout_with_colors(drawing->ruler->window,
+      drawing->ruler_gc_butt,
+      (drawing->ruler->allocation.width - ink_rect.width)/2,
+      6,
+      layout, &foreground, &background);
+
+    gdk_draw_line (drawing->ruler->window,
+                   drawing->ruler_gc_butt,
+                   drawing->ruler->allocation.width/2, 1,
+                   drawing->ruler->allocation.width/2, 7);
+
+
+
+
+  }
+
+  g_object_unref(layout);
+   
+  return FALSE;
+}
+
+
+/* notify mouse on ruler */
+static gboolean
+motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
+{
+  //g_debug("motion");
+  //eventually follow mouse and show time here
+}
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawing.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawing.h
new file mode 100644 (file)
index 0000000..9f2b936
--- /dev/null
@@ -0,0 +1,220 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+#ifndef _DRAWING_H
+#define _DRAWING_H
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <ltt/ltt.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttvwindow/lttvwindow.h>
+#include "cfv.h"
+#include "drawitem.h"
+
+
+#define SAFETY 50 // safety pixels at right and bottom of pixmap buffer
+
+typedef enum _draw_color {
+                COL_BLACK,
+                COL_WHITE,
+                COL_RUN_USER_MODE,/* green */
+                COL_RUN_SYSCALL,  /* pale blue */
+                COL_RUN_TRAP,     /* yellow */
+                COL_RUN_IRQ,      /* red */
+                COL_WAIT,         /* dark red */
+                COL_WAIT_CPU,     /* dark yellow */
+                COL_ZOMBIE,       /* dark purple */
+                COL_WAIT_FORK,    /* dark green */
+                COL_EXIT,         /* "less dark" magenta */
+                COL_MODE_UNKNOWN, /* white */
+                COL_UNNAMED,      /* white */
+                NUM_COLORS } draw_color; 
+
+extern GdkColor drawing_colors[NUM_COLORS];
+
+/* This part of the viewer does :
+ * Draw horizontal lines, getting graphic context as arg.
+ * Copy region of the screen into another.
+ * Modify the boundaries to reflect a scale change. (resize)
+ * Refresh the physical screen with the pixmap
+ * A helper function is provided here to convert from time to process
+ * identifier to pixels and the contrary (will be useful for mouse selection).
+ * Insert an empty square in the drawing, moving the bottom part.
+ *
+ * Note: The last point is exactly why it would not be so easy to add the
+ * vertical line functionnality as in the original version of LTT. In order
+ * to do so, we should keep all processes in the list for the duration of
+ * all the trace instead of dynamically adding and removing them when we
+ * scroll. Another possibility is to redraw all the visible area when a new
+ * process is added to the list. The second solution seems more appropriate
+ * to me.
+ * 
+ *
+ * The pixmap used has the width of the physical window, but the height
+ * of the shown processes.
+ */
+
+#ifndef TYPE_DRAWING_T_DEFINED
+#define TYPE_DRAWING_T_DEFINED
+typedef struct _Drawing_t Drawing_t;
+#endif //TYPE_DRAWING_T_DEFINED
+
+#ifndef TYPE_CONTROLFLOWDATA_DEFINED
+#define TYPE_CONTROLFLOWDATA_DEFINED
+typedef struct _ControlFlowData ControlFlowData;
+#endif //TYPE_CONTROLFLOWDATA_DEFINED
+
+struct _Drawing_t {
+  GtkWidget *vbox;
+  GtkWidget *drawing_area;
+  //GtkWidget *scrolled_window;
+  GtkWidget *hbox;
+  GtkWidget *viewport;
+  GtkWidget *scrollbar;
+  
+  GtkWidget *ruler_hbox;
+  GtkWidget *ruler;
+  GtkWidget *padding;
+  //GdkPixmap *pixmap;
+  ControlFlowData *control_flow_data;
+  
+  PangoLayout *pango_layout;
+
+  gint      height, width, depth;
+  /* height and width of allocated buffer pixmap */
+  gint      alloc_height, alloc_width;
+  
+  /* X coordinate of damaged region */
+  gint      damage_begin, damage_end; /* damaged region to be exposed,
+                                         updated per chunk */
+  LttTime   last_start;               
+  GdkGC     *dotted_gc;
+  GdkGC     *gc;
+  GdkGC     *ruler_gc_butt;
+  GdkGC     *ruler_gc_round;
+
+  /* Position of the horizontal selector, -1 for none */
+  gint horizontal_sel;
+};
+
+Drawing_t *drawing_construct(ControlFlowData *control_flow_data);
+void drawing_destroy(Drawing_t *drawing);
+
+GtkWidget *drawing_get_widget(Drawing_t *drawing);
+GtkWidget *drawing_get_drawing_area(Drawing_t *drawing);
+
+
+void drawing_data_request(Drawing_t *drawing,
+      gint x, gint y,
+      gint width,
+      gint height);
+
+void drawing_draw_line( Drawing_t *drawing,
+      GdkPixmap *pixmap,
+      guint x1, guint y1,
+      guint x2, guint y2,
+      GdkGC *GC);
+
+//void drawing_copy( Drawing_t *drawing,
+//    guint xsrc, guint ysrc,
+//    guint xdest, guint ydest,
+//    guint width, guint height);
+
+/* Clear the drawing : make it 1xwidth. */
+void drawing_clear(Drawing_t *drawing);
+
+/* Insert a square corresponding to a new process in the list */
+void drawing_insert_square(Drawing_t *drawing,
+        guint y,
+        guint height);
+
+/* Remove a square corresponding to a removed process in the list */
+void drawing_remove_square(Drawing_t *drawing,
+        guint y,
+        guint height);
+
+void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window);
+
+void drawing_request_expose(EventsRequest *events_request,
+                            LttvTracesetState *tss,
+                            LttTime end_time);
+
+void drawing_data_request_begin(EventsRequest *events_request,
+                                LttvTracesetState *tss);
+void drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss);
+
+
+
+void
+tree_row_activated(GtkTreeModel *treemodel,
+                   GtkTreePath *arg1,
+                   GtkTreeViewColumn *arg2,
+                   gpointer user_data);
+
+
+/* convert_pixels_to_time
+ *
+ * Convert from window pixel and time interval to an absolute time.
+ */
+static inline void convert_pixels_to_time(
+    gint width,
+    guint x,
+    TimeWindow time_window,
+    LttTime *time)
+{
+  double time_d;
+  
+  time_d = time_window.time_width_double;
+  time_d = time_d / (double)width * (double)x;
+  *time = ltt_time_from_double(time_d);
+  *time = ltt_time_add(time_window.start_time, *time);
+}
+
+
+static inline void convert_time_to_pixels(
+    TimeWindow time_window,
+    LttTime time,
+    int width,
+    guint *x)
+{
+  double time_d;
+#ifdef EXTRA_CHECK 
+  g_assert(ltt_time_compare(window_time_begin, time) <= 0 &&
+           ltt_time_compare(window_time_end, time) >= 0);
+#endif //EXTRA_CHECK
+  
+  time = ltt_time_sub(time, time_window.start_time);
+  
+  time_d = ltt_time_to_double(time);
+  
+  if(time_window.time_width_double == 0.0) {
+    g_assert(time_d == 0.0);
+    *x = 0;
+  } else {
+    *x = (guint)(time_d / time_window.time_width_double * (double)width);
+  }
+  
+}
+
+
+
+#endif // _DRAWING_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawitem.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawitem.c
new file mode 100644 (file)
index 0000000..7e1980e
--- /dev/null
@@ -0,0 +1,464 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+
+/******************************************************************************
+ * drawitem.c
+ *
+ * This file contains methods responsible for drawing a generic type of data
+ * in a drawable. Doing this generically will permit user defined drawing
+ * behavior in a later time.
+ *
+ * This file provides an API which is meant to be reusable for all viewers that
+ * need to show information in line, icon, text, background or point form in
+ * a drawable area having time for x axis. The y axis, in the control flow
+ * viewer case, is corresponding to the different processes, but it can be
+ * reused integrally for cpu, and eventually locks, buffers, network
+ * interfaces... What will differ between the viewers is the precise
+ * information which interests us. We may think that the most useful
+ * information for control flow are some specific events, like schedule
+ * change, and processes'states. It may differ for a cpu viewer : the
+ * interesting information could be more the execution mode of each cpu.
+ * This API in meant to make viewer's writers life easier : it will become
+ * a simple choice of icons and line types for the precise information
+ * the viewer has to provide (agremented with keeping supplementary records
+ * and modifying slightly the DrawContext to suit the needs.)
+ *
+ * We keep each data type in attributes, keys to specific information
+ * being formed from the GQuark corresponding to the information received.
+ * (facilities / facility_name / events / eventname.)
+ * (cpus/cpu_name, process_states/ps_name,
+ * execution_modes/em_name, execution_submodes/es_name).
+ * The goal is then to provide a generic way to print information on the
+ * screen for all this different information.
+ *
+ * Information can be printed as
+ *
+ * - text (text + color + size + position (over or under line)
+ * - icon (icon filename, corresponding to a loaded icon, accessible through
+ *   a GQuark. Icons are loaded statically at the guiControlFlow level during
+ *   module initialization and can be added on the fly if not present in the
+ *   GQuark.) The habitual place for xpm icons is in
+ *   ${prefix}/share/LinuxTraceToolkit.) + position (over or under line)
+ * - line (color, width, style)
+ * - Arc (big points) (color, size)
+ * - background color (color)
+ *
+ * An item is a leaf of the attributes tree. It is, in that case, including
+ * all kind of events categories we can have. It then associates each category
+ * with one or more actions (drawing something) or nothing.
+ * 
+ * Each item has an array of hooks (hook list). Each hook represents an
+ * operation to perform. We seek the array each time we want to
+ * draw an item. We execute each operation in order. An operation type
+ * is associated with each hook to permit user listing and modification
+ * of these operations. The operation type is also used to find the
+ * corresponding priority for the sorting. Operation type and priorities
+ * are enum and a static int table.
+ *
+ * The array has to be sorted by priority each time we add a task in it.
+ * A priority is associated with each operation type. It permits
+ * to perform background color selection before line or text drawing. We also
+ * draw lines before text, so the text appears over the lines.
+ *
+ * Executing all the arrays of operations for a specific event (which
+ * implies information for state, event, cpu, execution mode and submode)
+ * has to be done in a same DrawContext. The goal there is to keep the offset
+ * of the text and icons over and under the middle line, so a specific
+ * event could be printed as (  R Si 0 for running, scheduled in, cpu 0  ),
+ * text being easy to replace with icons. The DrawContext is passed as
+ * call_data for the operation hooks.
+ *
+ * We use the lttv global attributes to keep track of the loaded icons.
+ * If we need an icon, we look for it in the icons / icon name pathname.
+ * If found, we use the pointer to it. If not, we load the pixmap in
+ * memory and set the pointer to the GdkPixmap in the attributes. The
+ * structure pointed to contains the pixmap and the mask bitmap.
+ * 
+ * Author : Mathieu Desnoyers, October 2003
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <lttv/hook.h>
+#include <lttv/attribute.h>
+#include <lttv/iattribute.h>
+#include <string.h>
+
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/lttv.h>
+
+#include "drawitem.h"
+
+
+#define MAX_PATH_LEN 256
+
+/* drawing hook functions */
+gboolean draw_text( void *hook_data, void *call_data)
+{
+  PropertiesText *properties = (PropertiesText*)hook_data;
+  DrawContext *draw_context = (DrawContext*)call_data;
+
+  PangoContext *context;
+  PangoLayout *layout;
+  PangoFontDescription *font_desc;// = pango_font_description_new();
+  PangoRectangle ink_rect;
+    
+  layout = draw_context->pango_layout;
+
+  context = pango_layout_get_context(layout);
+  font_desc = pango_context_get_font_description(context);
+
+  pango_font_description_set_size(font_desc, properties->size*PANGO_SCALE);
+  pango_layout_context_changed(layout);
+
+  pango_layout_set_text(layout, properties->text, -1);
+  pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
+
+  gint x=0, y=0;
+  gint *offset=NULL;
+  gboolean enough_space = FALSE;
+  gint width = ink_rect.width;
+
+  switch(properties->position.x) {
+    case POS_START:
+      x = draw_context->drawinfo.start.x;
+      switch(properties->position.y) {
+        case OVER:
+          offset = &draw_context->drawinfo.start.offset.over;
+          x += draw_context->drawinfo.start.offset.over;
+          y = draw_context->drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->drawinfo.start.offset.middle;
+          x += draw_context->drawinfo.start.offset.middle;
+          y = draw_context->drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->drawinfo.start.offset.under;
+          x += draw_context->drawinfo.start.offset.under;
+          y = draw_context->drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x + width <= draw_context->drawinfo.end.x)) {
+        enough_space = TRUE;
+        *offset += width;
+      }
+      break;
+    case POS_END:
+      x = draw_context->drawinfo.end.x;
+      switch(properties->position.y) {
+        case OVER:
+          offset = &draw_context->drawinfo.end.offset.over;
+          x += draw_context->drawinfo.end.offset.over;
+          y = draw_context->drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->drawinfo.end.offset.middle;
+          x += draw_context->drawinfo.end.offset.middle;
+          y = draw_context->drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->drawinfo.end.offset.under;
+          x += draw_context->drawinfo.end.offset.under;
+          y = draw_context->drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x - width >= draw_context->drawinfo.start.x)) {
+        enough_space = TRUE;
+        *offset -= width;
+      }
+      break;
+  }
+
+  if(unlikely(enough_space))
+    gdk_draw_layout_with_colors(draw_context->drawable,
+              draw_context->gc,
+              x,
+              y,
+              layout, properties->foreground, properties->background);
+
+  return 0;
+}
+
+
+/* To speed up the process, search in already loaded icons list first. Only
+ * load it if not present.
+ */
+gboolean draw_icon( void *hook_data, void *call_data)
+{
+  PropertiesIcon *properties = (PropertiesIcon*)hook_data;
+  DrawContext *draw_context = (DrawContext*)call_data;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+  LttvAttributeValue value;
+  gchar icon_name[MAX_PATH_LEN] = "icons/";
+  IconStruct *icon_info;
+
+  strcat(icon_name, properties->icon_name);
+  
+  g_assert(lttv_iattribute_find_by_path(attributes, icon_name,
+      LTTV_POINTER, &value));
+  if(unlikely(*(value.v_pointer) == NULL))
+  {
+    *(value.v_pointer) = icon_info = g_new(IconStruct,1);
+    
+    icon_info->pixmap = gdk_pixmap_create_from_xpm(draw_context->drawable,
+                          &icon_info->mask, NULL, properties->icon_name);
+  }
+  else
+  {
+    icon_info = *(value.v_pointer);
+  }
+  
+  gint x=0, y=0;
+  gint *offset=NULL;
+  gboolean enough_space = FALSE;
+  gint width = properties->width;
+  
+  switch(properties->position.x) {
+    case POS_START:
+      x = draw_context->drawinfo.start.x;
+      switch(properties->position.y) {
+        case OVER:
+          offset = &draw_context->drawinfo.start.offset.over;
+          x += draw_context->drawinfo.start.offset.over;
+          y = draw_context->drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->drawinfo.start.offset.middle;
+          x += draw_context->drawinfo.start.offset.middle;
+          y = draw_context->drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->drawinfo.start.offset.under;
+          x += draw_context->drawinfo.start.offset.under;
+          y = draw_context->drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x + width <= draw_context->drawinfo.end.x)) {
+        enough_space = TRUE;
+        *offset += width;
+      }
+      break;
+    case POS_END:
+      x = draw_context->drawinfo.end.x;
+      switch(properties->position.y) {
+        case OVER:
+          offset = &draw_context->drawinfo.end.offset.over;
+          x += draw_context->drawinfo.end.offset.over;
+          y = draw_context->drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->drawinfo.end.offset.middle;
+          x += draw_context->drawinfo.end.offset.middle;
+          y = draw_context->drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->drawinfo.end.offset.under;
+          x += draw_context->drawinfo.end.offset.under;
+          y = draw_context->drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x - width >= draw_context->drawinfo.start.x)) {
+        enough_space = TRUE;
+        *offset -= width;
+      }
+      break;
+  }
+
+  if(unlikely(enough_space)) {
+    gdk_gc_set_clip_mask(draw_context->gc, icon_info->mask);
+
+    gdk_gc_set_clip_origin(
+        draw_context->gc,
+        x,
+        y);
+    gdk_draw_drawable(draw_context->drawable, 
+        draw_context->gc,
+        icon_info->pixmap,
+        0, 0,
+        x,
+        y,
+        properties->width, properties->height);
+
+    gdk_gc_set_clip_origin(draw_context->gc, 0, 0);
+    gdk_gc_set_clip_mask(draw_context->gc, NULL);
+  }
+  return 0;
+}
+
+gboolean draw_line( void *hook_data, void *call_data)
+{
+  PropertiesLine *properties = (PropertiesLine*)hook_data;
+  DrawContext *draw_context = (DrawContext*)call_data;
+  
+  gdk_gc_set_foreground(draw_context->gc, &properties->color);
+  //gdk_gc_set_rgb_fg_color(draw_context->gc, &properties->color);
+  gdk_gc_set_line_attributes( draw_context->gc,
+                              properties->line_width,
+                              properties->style,
+                              GDK_CAP_BUTT,
+                              GDK_JOIN_MITER);
+  //g_critical("DRAWING LINE : x1: %i, y1: %i, x2:%i, y2:%i", 
+  //    draw_context->previous->middle->x,
+  //    draw_context->previous->middle->y,
+  //    draw_context->drawinfo.middle.x,
+  //    draw_context->drawinfo.middle.y);
+
+  gint x_begin=0, x_end=0, y=0;
+  
+  x_begin = draw_context->drawinfo.start.x;
+  x_end = draw_context->drawinfo.end.x;
+
+  switch(properties->y) {
+    case OVER:
+      y = draw_context->drawinfo.y.over;
+      break;
+    case MIDDLE:
+      y = draw_context->drawinfo.y.middle;
+      break;
+    case UNDER:
+      y = draw_context->drawinfo.y.under;
+      break;
+  }
+
+  drawing_draw_line(
+    NULL, draw_context->drawable,
+    x_begin,
+    y,
+    x_end,
+    y,
+    draw_context->gc);
+  
+  return 0;
+}
+
+gboolean draw_arc( void *hook_data, void *call_data)
+{
+  PropertiesArc *properties = (PropertiesArc*)hook_data;
+  DrawContext *draw_context = (DrawContext*)call_data;
+
+  gdk_gc_set_foreground(draw_context->gc, properties->color);
+  //gdk_gc_set_rgb_fg_color(draw_context->gc, properties->color);
+
+  gint x=0, y=0;
+  gint *offset=NULL;
+  gboolean enough_space = FALSE;
+  gint width = properties->size;
+  
+  switch(properties->position.x) {
+    case POS_START:
+      x = draw_context->drawinfo.start.x;
+      switch(properties->position.y) {
+        case OVER:
+          offset = &draw_context->drawinfo.start.offset.over;
+          x += draw_context->drawinfo.start.offset.over;
+          y = draw_context->drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->drawinfo.start.offset.middle;
+          x += draw_context->drawinfo.start.offset.middle;
+          y = draw_context->drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->drawinfo.start.offset.under;
+          x += draw_context->drawinfo.start.offset.under;
+          y = draw_context->drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x + width <= draw_context->drawinfo.end.x)) {
+        enough_space = TRUE;
+        *offset += width;
+      }
+      break;
+    case POS_END:
+      x = draw_context->drawinfo.end.x;
+      switch(properties->position.y) {
+        case OVER:
+          offset = &draw_context->drawinfo.end.offset.over;
+          x += draw_context->drawinfo.end.offset.over;
+          y = draw_context->drawinfo.y.over;
+          break;
+        case MIDDLE:
+          offset = &draw_context->drawinfo.end.offset.middle;
+          x += draw_context->drawinfo.end.offset.middle;
+          y = draw_context->drawinfo.y.middle;
+          break;
+        case UNDER:
+          offset = &draw_context->drawinfo.end.offset.under;
+          x += draw_context->drawinfo.end.offset.under;
+          y = draw_context->drawinfo.y.under;
+          break;
+      }
+      /* verify if there is enough space to draw */
+      if(unlikely(x - width >= draw_context->drawinfo.start.x)) {
+        enough_space = TRUE;
+        *offset -= width;
+      }
+      break;
+  }
+
+  if(unlikely(enough_space))
+    gdk_draw_arc(draw_context->drawable, draw_context->gc,
+          properties->filled,
+          x,
+          y,
+          properties->size, properties->size, 0, 360*64);
+  
+  return 0;
+}
+
+gboolean draw_bg( void *hook_data, void *call_data)
+{
+  PropertiesBG *properties = (PropertiesBG*)hook_data;
+  DrawContext *draw_context = (DrawContext*)call_data;
+
+  gdk_gc_set_foreground(draw_context->gc, properties->color);
+  //gdk_gc_set_rgb_fg_color(draw_context->gc, properties->color);
+
+  //g_critical("DRAWING RECT : x: %i, y: %i, w:%i, h:%i, val1 :%i, val2:%i ", 
+  //    draw_context->previous->over->x,
+  //    draw_context->previous->over->y,
+  //    draw_context->drawinfo.over.x - draw_context->previous->over->x,
+  //    draw_context->previous->under->y-draw_context->previous->over->y,
+  //    draw_context->drawinfo.over.x,
+  //    draw_context->previous->over->x);
+  gdk_draw_rectangle(draw_context->drawable, draw_context->gc,
+          TRUE,
+          draw_context->drawinfo.start.x,
+          draw_context->drawinfo.y.over,
+          draw_context->drawinfo.end.x - draw_context->drawinfo.start.x,
+          draw_context->drawinfo.y.under - draw_context->drawinfo.y.over);
+
+  return 0;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawitem.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/drawitem.h
new file mode 100644 (file)
index 0000000..28fdc18
--- /dev/null
@@ -0,0 +1,279 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+#ifndef _DRAW_ITEM_H
+#define _DRAW_ITEM_H
+
+#include <lttv/state.h>
+
+typedef struct _DrawContext DrawContext;
+typedef struct _DrawInfo DrawInfo;
+typedef struct _ItemInfo ItemInfo;
+
+typedef struct _IconStruct IconStruct;
+
+typedef struct _DrawOperation DrawOperation;
+
+
+typedef struct _PropertiesText PropertiesText;
+typedef struct _PropertiesIcon PropertiesIcon;
+typedef struct _PropertiesLine PropertiesLine;
+typedef struct _PropertiesArc PropertiesArc;
+typedef struct _PropertiesBG PropertiesBG;
+
+typedef enum _DrawableItems DrawableItems;
+enum _DrawableItems {
+    ITEM_TEXT, ITEM_ICON, ITEM_LINE, ITEM_POINT, ITEM_BACKGROUND
+};
+
+typedef enum _RelPosX {
+  POS_START, POS_END
+} RelPosX;
+
+typedef enum _RelPosY {
+  OVER, MIDDLE, UNDER
+} RelPosY;
+
+
+/* The DrawContext keeps information about the current drawing position and
+ * the previous one, so we can use both to draw lines.
+ *
+ * over : position for drawing over the middle line.
+ * middle : middle line position.
+ * under : position for drawing under the middle line.
+ *
+ * the modify_* are used to take into account that we should go forward
+ * when we draw a text, an arc or an icon, while it's unneeded when we
+ * draw a line or background.
+ *
+ * The modify_* positions are altered by the draw item functions.
+ *
+ */
+
+
+struct _DrawContext {
+  GdkDrawable *drawable;
+  GdkGC   *gc;
+  PangoLayout *pango_layout;
+
+  struct {
+    struct {
+      gint x;
+      struct {
+        gint over;
+        gint middle;
+        gint under;
+      } offset;
+    } start;
+
+    struct {
+      gint x;
+      struct {
+        gint over;
+        gint middle;
+        gint under;
+      } offset;
+    } end;
+
+    struct {
+      gint over;
+      gint middle;
+      gint under;
+    } y;
+
+  } drawinfo;
+};
+
+
+
+
+/*
+ * Structure used to keep information about icons.
+ */
+struct _IconStruct {
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+};
+
+
+/*
+ * The Item element is only used so the DrawOperation is modifiable by users.
+ * During drawing, only the Hook is needed.
+ */
+struct _DrawOperation {
+  DrawableItems item;
+  LttvHooks *hook;
+};
+#if 0
+/*
+ * We define here each items that can be drawn, together with their
+ * associated priority. Many item types can have the same priority,
+ * it's only used for quicksorting the operations when we add a new one
+ * to the array of operations to perform. Lower priorities are executed
+ * first. So, for example, we may want to give background color a value
+ * of 10 while a line would have 20, so the background color, which
+ * is in fact a rectangle, does not hide the line.
+ */
+
+static int Items_Priorities[] = {
+  50, /* ITEM_TEXT */
+  40, /* ITEM_ICON */
+  20, /* ITEM_LINE */
+  30, /* ITEM_POINT */
+  10  /* ITEM_BACKGROUND */
+};
+#endif //0
+
+/*
+ * Here are the different structures describing each item type that can be
+ * drawn. They contain the information necessary to draw the item : not the
+ * position (this is provided by the DrawContext), but the text, icon name,
+ * line width, color; all the properties of the specific items.
+ */
+
+struct _PropertiesText {
+  GdkColor  *foreground;
+  GdkColor  *background;
+  gint       size;
+  gchar     *text;
+  struct {
+    RelPosX    x;
+    RelPosY    y;
+  } position;
+};
+
+
+struct _PropertiesIcon {
+  gchar   *icon_name;
+  gint    width;
+  gint    height;
+  struct {
+    RelPosX    x;
+    RelPosY    y;
+  } position;
+};
+
+struct _PropertiesLine {
+  GdkColor  color;
+  gint    line_width;
+  GdkLineStyle  style;
+  RelPosY    y;
+};
+
+struct _PropertiesArc {
+  GdkColor  *color;
+  gint    size; /* We force circle by width = height */
+  gboolean  filled;
+  struct {
+    RelPosX    x;
+    RelPosY    y;
+  } position;
+};
+
+struct _PropertiesBG {
+  GdkColor  *color;
+};
+
+
+
+void draw_item( GdkDrawable *drawable,
+    gint x,
+    gint y,
+    LttvTraceState *ts,
+    LttvTracefileState *tfs,
+    LttvIAttribute *attributes);
+
+/*
+ * The tree of attributes used to store drawing operations goes like this :
+ *
+ * event_types/
+ *   "facility-event_type"
+ * cpus/
+ *   "cpu name"
+ * mode_types/
+ *   "execution mode"/
+ *     submodes/
+ *       "submode"
+ * process_states/
+ *   "state name"
+ * 
+ * So if, for example, we want to add a hook to get called each time we
+ * receive an event that is in state LTTV_STATE_SYSCALL, we put the
+ * pointer to the GArray of DrawOperation in
+ * process_states/ "name associated with LTTV_STATE_SYSCALL"
+ */
+
+
+#if 0
+/* 
+ * The add_operation has to do a quick sort by priority to keep the operations
+ * in the right order.
+ */
+void add_operation( LttvIAttribute *attributes,
+      gchar *pathname,
+      DrawOperation *operation);
+
+/* 
+ * The del_operation seeks the array present at pathname (if any) and
+ * removes the DrawOperation if present. It returns 0 on success, -1
+ * if it fails.
+ */
+gint del_operation( LttvIAttribute *attributes,
+      gchar *pathname,
+      DrawOperation *operation);
+
+/* 
+ * The clean_operations removes all operations present at a pathname.
+ * returns 0 on success, -1 if it fails.
+ */
+gint clean_operations(  LttvIAttribute *attributes,
+      gchar *pathname );
+
+
+/* 
+ * The list_operations gives a pointer to the operation array associated
+ * with the pathname. It will be NULL if no operation is present.
+ */
+void list_operations( LttvIAttribute *attributes,
+      gchar *pathname,
+      GArray **operation);
+
+
+
+/*
+ * exec_operation executes the operations if present in the attributes, or
+ * do nothing if not present.
+ */
+void exec_operations( LttvIAttribute *attributes,
+      gchar *pathname);
+#endif //0
+
+/*
+ * Here follow the prototypes of the hook functions used to draw the
+ * different items.
+ */
+
+gboolean draw_text( void *hook_data, void *call_data);
+gboolean draw_icon( void *hook_data, void *call_data);
+gboolean draw_line( void *hook_data, void *call_data);
+gboolean draw_arc( void *hook_data, void *call_data);
+gboolean draw_bg( void *hook_data, void *call_data);
+
+
+#endif // _DRAW_ITEM_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/eventhooks.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/eventhooks.c
new file mode 100644 (file)
index 0000000..c2b16df
--- /dev/null
@@ -0,0 +1,2385 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+/*****************************************************************************
+ *                       Hooks to be called by the main window               *
+ *****************************************************************************/
+
+
+/* Event hooks are the drawing hooks called during traceset read. They draw the
+ * icons, text, lines and background color corresponding to the events read.
+ *
+ * Two hooks are used for drawing : before_schedchange and after_schedchange hooks. The
+ * before_schedchange is called before the state update that occurs with an event and
+ * the after_schedchange hook is called after this state update.
+ *
+ * The before_schedchange hooks fulfill the task of drawing the visible objects that
+ * corresponds to the data accumulated by the after_schedchange hook.
+ *
+ * The after_schedchange hook accumulates the data that need to be shown on the screen
+ * (items) into a queue. Then, the next before_schedchange hook will draw what that
+ * queue contains. That's the Right Way (TM) of drawing items on the screen,
+ * because we need to draw the background first (and then add icons, text, ...
+ * over it), but we only know the length of a background region once the state
+ * corresponding to it is over, which happens to be at the next before_schedchange
+ * hook.
+ *
+ * We also have a hook called at the end of a chunk to draw the information left
+ * undrawn in each process queue. We use the current time as end of
+ * line/background.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//#define PANGO_ENABLE_BACKEND
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+//#include <pango/pango.h>
+
+#include <ltt/event.h>
+#include <ltt/time.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+
+#include <lttv/lttv.h>
+#include <lttv/hook.h>
+#include <lttv/state.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+#include <lttvwindow/support.h>
+
+
+#include "eventhooks.h"
+#include "cfv.h"
+#include "processlist.h"
+#include "drawing.h"
+
+
+#define MAX_PATH_LEN 256
+
+extern GSList *g_legend_list;
+
+
+/* Action to do when background computation completed.
+ *
+ * Wait for all the awaited computations to be over.
+ */
+
+static gint background_ready(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData *)hook_data;
+  LttvTrace *trace = (LttvTrace*)call_data;
+
+  control_flow_data->background_info_waiting--;
+  
+  if(control_flow_data->background_info_waiting == 0) {
+    g_message("control flow viewer : background computation data ready.");
+
+    drawing_clear(control_flow_data->drawing);
+    processlist_clear(control_flow_data->process_list);
+    gtk_widget_set_size_request(
+      control_flow_data->drawing->drawing_area,
+                -1, processlist_get_height(control_flow_data->process_list));
+    redraw_notify(control_flow_data, NULL);
+  }
+
+  return 0;
+}
+
+
+/* Request background computation. Verify if it is in progress or ready first.
+ * Only for each trace in the tab's traceset.
+ */
+static void request_background_data(ControlFlowData *control_flow_data)
+{
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(control_flow_data->tab);
+  gint num_traces = lttv_traceset_number(tsc->ts);
+  gint i;
+  LttvTrace *trace;
+
+  LttvHooks *background_ready_hook = 
+    lttv_hooks_new();
+  lttv_hooks_add(background_ready_hook, background_ready, control_flow_data,
+      LTTV_PRIO_DEFAULT);
+  control_flow_data->background_info_waiting = 0;
+  
+  for(i=0;i<num_traces;i++) {
+    trace = lttv_traceset_get(tsc->ts, i);
+
+    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+
+      if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
+                                          trace) == FALSE) {
+        /* We first remove requests that could have been done for the same
+         * information. Happens when two viewers ask for it before servicing
+         * starts.
+         */
+        if(!lttvwindowtraces_background_request_find(trace, "state"))
+          lttvwindowtraces_background_request_queue(
+              main_window_get_widget(control_flow_data->tab), trace, "state");
+        lttvwindowtraces_background_notify_queue(control_flow_data,
+                                                 trace,
+                                                 ltt_time_infinite,
+                                                 NULL,
+                                                 background_ready_hook);
+        control_flow_data->background_info_waiting++;
+      } else { /* in progress */
+      
+        lttvwindowtraces_background_notify_current(control_flow_data,
+                                                   trace,
+                                                   ltt_time_infinite,
+                                                   NULL,
+                                                   background_ready_hook);
+        control_flow_data->background_info_waiting++;
+      }
+    } else {
+      /* Data ready. Be its nature, this viewer doesn't need to have
+       * its data ready hook called there, because a background
+       * request is always linked with a redraw.
+       */
+    }
+    
+  }
+
+  lttv_hooks_destroy(background_ready_hook);
+}
+
+
+
+
+/**
+ * Event Viewer's constructor hook
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the list.
+ * @param tab A pointer to the parent tab.
+ * @return The widget created.
+ */
+GtkWidget *
+h_guicontrolflow(Tab *tab)
+{
+  g_info("h_guicontrolflow, %p", tab);
+  ControlFlowData *control_flow_data = guicontrolflow(tab) ;
+  
+  control_flow_data->tab = tab;
+  
+  // Unreg done in the GuiControlFlow_Destructor
+  lttvwindow_register_traceset_notify(tab,
+        traceset_notify,
+        control_flow_data);
+    
+  lttvwindow_register_time_window_notify(tab,
+                                         update_time_window_hook,
+                                         control_flow_data);
+  lttvwindow_register_current_time_notify(tab,
+                                          update_current_time_hook,
+                                          control_flow_data);
+  lttvwindow_register_redraw_notify(tab,
+                                    redraw_notify,
+                                    control_flow_data);
+  lttvwindow_register_continue_notify(tab,
+                                      continue_notify,
+                                      control_flow_data);
+  request_background_data(control_flow_data);
+  
+
+  return guicontrolflow_get_widget(control_flow_data) ;
+  
+}
+
+void legend_destructor(GtkWindow *legend)
+{
+  g_legend_list = g_slist_remove(g_legend_list, legend);
+}
+
+/* Create a popup legend */
+GtkWidget *
+h_legend(Tab *tab)
+{
+  g_info("h_legend, %p", tab);
+
+  GtkWindow *legend = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
+  g_legend_list = g_slist_append(
+      g_legend_list,
+      legend);
+  g_object_set_data_full(
+      G_OBJECT(legend),
+      "legend",
+      legend,
+      (GDestroyNotify)legend_destructor);
+  
+  gtk_window_set_title(legend, "Control Flow View Legend");
+
+  GtkWidget *pixmap = create_pixmap(GTK_WIDGET(legend), "lttv-color-list.png");
+  
+ // GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixmap(
+ //                               GDK_PIXMAP(pixmap), NULL));
+  
+  gtk_container_add(GTK_CONTAINER(legend), GTK_WIDGET(pixmap));
+
+  gtk_widget_show(GTK_WIDGET(pixmap));
+  gtk_widget_show(GTK_WIDGET(legend));
+  
+
+  return NULL; /* This is a popup window */
+}
+
+
+int event_selected_hook(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
+  guint *event_number = (guint*) call_data;
+
+  g_debug("DEBUG : event selected by main window : %u", *event_number);
+  
+  return 0;
+}
+
+/* Function that selects the color of status&exemode line */
+static inline PropertiesLine prepare_s_e_line(LttvProcessState *process)
+{
+  PropertiesLine prop_line;
+  prop_line.line_width = 2;
+  prop_line.style = GDK_LINE_SOLID;
+  prop_line.y = MIDDLE;
+  //GdkColormap *colormap = gdk_colormap_get_system();
+  
+  if(process->state->s == LTTV_STATE_RUN) {
+    if(process->state->t == LTTV_STATE_USER_MODE)
+      prop_line.color = drawing_colors[COL_RUN_USER_MODE];
+    else if(process->state->t == LTTV_STATE_SYSCALL)
+      prop_line.color = drawing_colors[COL_RUN_SYSCALL];
+    else if(process->state->t == LTTV_STATE_TRAP)
+      prop_line.color = drawing_colors[COL_RUN_TRAP];
+    else if(process->state->t == LTTV_STATE_IRQ)
+      prop_line.color = drawing_colors[COL_RUN_IRQ];
+    else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
+      prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
+    else
+      g_assert(FALSE);   /* RUNNING MODE UNKNOWN */
+  } else if(process->state->s == LTTV_STATE_WAIT) {
+    /* We don't show if we wait while in user mode, trap, irq or syscall */
+    prop_line.color = drawing_colors[COL_WAIT];
+  } else if(process->state->s == LTTV_STATE_WAIT_CPU) {
+    /* We don't show if we wait for CPU while in user mode, trap, irq
+     * or syscall */
+    prop_line.color = drawing_colors[COL_WAIT_CPU];
+  } else if(process->state->s == LTTV_STATE_ZOMBIE) {
+    prop_line.color = drawing_colors[COL_ZOMBIE];
+  } else if(process->state->s == LTTV_STATE_WAIT_FORK) {
+    prop_line.color = drawing_colors[COL_WAIT_FORK];
+  } else if(process->state->s == LTTV_STATE_EXIT) {
+    prop_line.color = drawing_colors[COL_EXIT];
+  } else if(process->state->s == LTTV_STATE_UNNAMED) {
+    prop_line.color = drawing_colors[COL_UNNAMED];
+  } else
+    g_assert(FALSE);   /* UNKNOWN STATE */
+  
+  return prop_line;
+
+}
+
+
+/* before_schedchange_hook
+ * 
+ * This function basically draw lines and icons. Two types of lines are drawn :
+ * one small (3 pixels?) representing the state of the process and the second
+ * type is thicker (10 pixels?) representing on which CPU a process is running
+ * (and this only in running state).
+ *
+ * Extremums of the lines :
+ * x_min : time of the last event context for this process kept in memory.
+ * x_max : time of the current event.
+ * y : middle of the process in the process list. The process is found in the
+ * list, therefore is it's position in pixels.
+ *
+ * The choice of lines'color is defined by the context of the last event for this
+ * process.
+ */
+
+
+int before_schedchange_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+  /* we are in a schedchange, before the state update. We must draw the
+   * items corresponding to the state before it changes : now is the right
+   * time to do it.
+   */
+
+  guint pid_out;
+  guint pid_in;
+  {
+    pid_out = ltt_event_get_long_unsigned(e, thf->f1);
+    pid_in = ltt_event_get_long_unsigned(e, thf->f2);
+  }
+  
+  { 
+    /* For the pid_out */
+    /* First, check if the current process is in the state computation
+     * process list. If it is there, that means we must add it right now and
+     * draw items from the beginning of the read for it. If it is not
+     * present, it's a new process and it was not present : it will
+     * be added after the state update.  */
+    guint cpu = ltt_tracefile_num(tfc->tf);
+    LttvProcessState *process = ts->running_process[cpu];
+    /* unknown state, bad current pid */
+    if(process->pid != pid_out)
+      process = lttv_state_find_process(ts,
+          ltt_tracefile_num(tfc->tf), pid_out);
+    
+    if(process != NULL) {
+      /* Well, the process_out existed : we must get it in the process hash
+       * or add it, and draw its items.
+       */
+       /* Add process to process list (if not present) */
+      guint pl_height = 0;
+      HashedProcessData *hashed_process_data = NULL;
+      ProcessList *process_list = control_flow_data->process_list;
+      LttTime birth = process->creation_time;
+      
+      hashed_process_data = processlist_get_process_data(process_list,
+              pid_out,
+              process->cpu,
+              &birth,
+              tfc->t_context->index);
+      if(hashed_process_data == NULL)
+      {
+        g_assert(pid_out == 0 || pid_out != process->ppid);
+        /* Process not present */
+        ProcessInfo *process_info;
+        Drawing_t *drawing = control_flow_data->drawing;
+        processlist_add(process_list,
+            drawing,
+            pid_out,
+            process->cpu,
+            process->ppid,
+            &birth,
+            tfc->t_context->index,
+            process->name,
+            &pl_height,
+            &process_info,
+            &hashed_process_data);
+        gtk_widget_set_size_request(drawing->drawing_area,
+                                    -1,
+                                    pl_height);
+        gtk_widget_queue_draw(drawing->drawing_area);
+
+      }
+  
+      /* Now, the process is in the state hash and our own process hash.
+       * We definitely can draw the items related to the ending state.
+       */
+      
+      if(ltt_time_compare(hashed_process_data->next_good_time,
+                          evtime) > 0)
+      {
+        if(hashed_process_data->x.middle_marked == FALSE) {
+    
+          TimeWindow time_window = 
+            lttvwindow_get_time_window(control_flow_data->tab);
+#ifdef EXTRA_CHECK
+          if(ltt_time_compare(evtime, time_window.start_time) == -1
+                || ltt_time_compare(evtime, time_window.end_time) == 1)
+                    return;
+#endif //EXTRA_CHECK
+          Drawing_t *drawing = control_flow_data->drawing;
+          guint width = drawing->width;
+          guint x;
+          convert_time_to_pixels(
+                    time_window,
+                    evtime,
+                    width,
+                    &x);
+
+          /* Draw collision indicator */
+          gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+          gdk_draw_point(hashed_process_data->pixmap,
+                         drawing->gc,
+                         x,
+                         (hashed_process_data->height/2)-3);
+          hashed_process_data->x.middle_marked = TRUE;
+        }
+      } else {
+        TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+#ifdef EXTRA_CHECK
+        if(ltt_time_compare(evtime, time_window.start_time) == -1
+              || ltt_time_compare(evtime, time_window.end_time) == 1)
+                  return;
+#endif //EXTRA_CHECK
+        Drawing_t *drawing = control_flow_data->drawing;
+        guint width = drawing->width;
+        guint x;
+        convert_time_to_pixels(
+                  time_window,
+                  evtime,
+                  width,
+                  &x);
+
+
+        /* Jump over draw if we are at the same x position */
+        if(x == hashed_process_data->x.middle &&
+             hashed_process_data->x.middle_used)
+        {
+          if(hashed_process_data->x.middle_marked == FALSE) {
+            /* Draw collision indicator */
+            gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+            gdk_draw_point(hashed_process_data->pixmap,
+                           drawing->gc,
+                           x,
+                           (hashed_process_data->height/2)-3);
+            hashed_process_data->x.middle_marked = TRUE;
+          }
+          /* jump */
+        } else {
+          DrawContext draw_context;
+
+          /* Now create the drawing context that will be used to draw
+           * items related to the last state. */
+          draw_context.drawable = hashed_process_data->pixmap;
+          draw_context.gc = drawing->gc;
+          draw_context.pango_layout = drawing->pango_layout;
+          draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+          draw_context.drawinfo.end.x = x;
+
+          draw_context.drawinfo.y.over = 1;
+          draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+          draw_context.drawinfo.y.under = hashed_process_data->height;
+
+          draw_context.drawinfo.start.offset.over = 0;
+          draw_context.drawinfo.start.offset.middle = 0;
+          draw_context.drawinfo.start.offset.under = 0;
+          draw_context.drawinfo.end.offset.over = 0;
+          draw_context.drawinfo.end.offset.middle = 0;
+          draw_context.drawinfo.end.offset.under = 0;
+
+          {
+            /* Draw the line */
+            PropertiesLine prop_line = prepare_s_e_line(process);
+            draw_line((void*)&prop_line, (void*)&draw_context);
+
+          }
+          /* become the last x position */
+          hashed_process_data->x.middle = x;
+          hashed_process_data->x.middle_used = TRUE;
+          hashed_process_data->x.middle_marked = FALSE;
+
+          /* Calculate the next good time */
+          convert_pixels_to_time(width, x+1, time_window,
+                                 &hashed_process_data->next_good_time);
+        }
+      }
+    }
+  }
+
+  {
+    /* For the pid_in */
+    /* First, check if the current process is in the state computation
+     * process list. If it is there, that means we must add it right now and
+     * draw items from the beginning of the read for it. If it is not
+     * present, it's a new process and it was not present : it will
+     * be added after the state update.  */
+    LttvProcessState *process;
+    process = lttv_state_find_process(ts,
+        ltt_tracefile_num(tfc->tf), pid_in);
+    
+    if(process != NULL) {
+      /* Well, the process existed : we must get it in the process hash
+       * or add it, and draw its items.
+       */
+       /* Add process to process list (if not present) */
+      guint pl_height = 0;
+      HashedProcessData *hashed_process_data = NULL;
+      ProcessList *process_list = control_flow_data->process_list;
+      LttTime birth = process->creation_time;
+      
+      hashed_process_data = processlist_get_process_data(process_list,
+              pid_in,
+              ltt_tracefile_num(tfc->tf),
+              &birth,
+              tfc->t_context->index);
+      if(hashed_process_data == NULL)
+      {
+        g_assert(pid_in == 0 || pid_in != process->ppid);
+        /* Process not present */
+        ProcessInfo *process_info;
+        Drawing_t *drawing = control_flow_data->drawing;
+        processlist_add(process_list,
+            drawing,
+            pid_in,
+            ltt_tracefile_num(tfc->tf),
+            process->ppid,
+            &birth,
+            tfc->t_context->index,
+            process->name,
+            &pl_height,
+            &process_info,
+            &hashed_process_data);
+        gtk_widget_set_size_request(drawing->drawing_area,
+                                    -1,
+                                    pl_height);
+        gtk_widget_queue_draw(drawing->drawing_area);
+
+      }
+      //We could set the current process and hash here, but will be done
+      //by after schedchange hook
+    
+      /* Now, the process is in the state hash and our own process hash.
+       * We definitely can draw the items related to the ending state.
+       */
+      
+      if(ltt_time_compare(hashed_process_data->next_good_time,
+                          evtime) > 0)
+      {
+        if(hashed_process_data->x.middle_marked == FALSE) {
+
+          TimeWindow time_window = 
+            lttvwindow_get_time_window(control_flow_data->tab);
+#ifdef EXTRA_CHECK
+          if(ltt_time_compare(evtime, time_window.start_time) == -1
+                || ltt_time_compare(evtime, time_window.end_time) == 1)
+                    return;
+#endif //EXTRA_CHECK
+          Drawing_t *drawing = control_flow_data->drawing;
+          guint width = drawing->width;
+          guint x;
+          convert_time_to_pixels(
+                    time_window,
+                    evtime,
+                    width,
+                    &x);
+
+          /* Draw collision indicator */
+          gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+          gdk_draw_point(hashed_process_data->pixmap,
+                         drawing->gc,
+                         x,
+                         (hashed_process_data->height/2)-3);
+          hashed_process_data->x.middle_marked = TRUE;
+        }
+      } else {
+        TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+#ifdef EXTRA_CHECK
+        if(ltt_time_compare(evtime, time_window.start_time) == -1
+              || ltt_time_compare(evtime, time_window.end_time) == 1)
+                  return;
+#endif //EXTRA_CHECK
+        Drawing_t *drawing = control_flow_data->drawing;
+        guint width = drawing->width;
+        guint x;
+
+        convert_time_to_pixels(
+                  time_window,
+                  evtime,
+                  width,
+                  &x);
+
+
+        /* Jump over draw if we are at the same x position */
+        if(x == hashed_process_data->x.middle &&
+            hashed_process_data->x.middle_used)
+        {
+          if(hashed_process_data->x.middle_marked == FALSE) {
+            /* Draw collision indicator */
+            gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+            gdk_draw_point(hashed_process_data->pixmap,
+                           drawing->gc,
+                           x,
+                           (hashed_process_data->height/2)-3);
+            hashed_process_data->x.middle_marked = TRUE;
+          }
+          /* jump */
+        } else {
+          DrawContext draw_context;
+
+          /* Now create the drawing context that will be used to draw
+           * items related to the last state. */
+          draw_context.drawable = hashed_process_data->pixmap;
+          draw_context.gc = drawing->gc;
+          draw_context.pango_layout = drawing->pango_layout;
+          draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+          draw_context.drawinfo.end.x = x;
+
+          draw_context.drawinfo.y.over = 1;
+          draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+          draw_context.drawinfo.y.under = hashed_process_data->height;
+
+          draw_context.drawinfo.start.offset.over = 0;
+          draw_context.drawinfo.start.offset.middle = 0;
+          draw_context.drawinfo.start.offset.under = 0;
+          draw_context.drawinfo.end.offset.over = 0;
+          draw_context.drawinfo.end.offset.middle = 0;
+          draw_context.drawinfo.end.offset.under = 0;
+
+          {
+            /* Draw the line */
+            PropertiesLine prop_line = prepare_s_e_line(process);
+            draw_line((void*)&prop_line, (void*)&draw_context);
+          }
+
+          
+          /* become the last x position */
+          hashed_process_data->x.middle = x;
+          hashed_process_data->x.middle_used = TRUE;
+          hashed_process_data->x.middle_marked = FALSE;
+
+          /* Calculate the next good time */
+          convert_pixels_to_time(width, x+1, time_window,
+                                 &hashed_process_data->next_good_time);
+        }
+      }
+    } else
+      g_warning("Cannot find pin_in in schedchange %u", pid_in);
+  }
+  return 0;
+
+
+
+
+  /* Text dump */
+#ifdef DONTSHOW
+  GString *string = g_string_new("");;
+  gboolean field_names = TRUE, state = TRUE;
+
+  lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
+  g_string_append_printf(string,"\n");  
+
+  if(state) {
+    g_string_append_printf(string, " %s",
+        g_quark_to_string(tfs->process->state->s));
+  }
+
+  g_info("%s",string->str);
+
+  g_string_free(string, TRUE);
+  
+  /* End of text dump */
+#endif //DONTSHOW
+
+}
+
+/* after_schedchange_hook
+ * 
+ * The draw after hook is called by the reading API to have a
+ * particular event drawn on the screen.
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context.
+ *
+ * This function adds items to be drawn in a queue for each process.
+ * 
+ */
+int after_schedchange_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+  /* Add process to process list (if not present) */
+  LttvProcessState *process_in;
+  LttTime birth;
+  guint pl_height = 0;
+  HashedProcessData *hashed_process_data_in = NULL;
+
+  ProcessList *process_list = control_flow_data->process_list;
+  
+  guint pid_in;
+  {
+    guint pid_out;
+    pid_out = ltt_event_get_long_unsigned(e, thf->f1);
+    pid_in = ltt_event_get_long_unsigned(e, thf->f2);
+  }
+
+
+  /* Find process pid_in in the list... */
+  //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
+  //process_in = tfs->process;
+  guint cpu = ltt_tracefile_num(tfc->tf);
+  process_in = ts->running_process[cpu];
+  /* It should exist, because we are after the state update. */
+#ifdef EXTRA_CHECK
+  g_assert(process_in != NULL);
+#endif //EXTRA_CHECK
+  birth = process_in->creation_time;
+
+  hashed_process_data_in = processlist_get_process_data(process_list,
+          pid_in,
+          process_in->cpu,
+          &birth,
+          tfc->t_context->index);
+  if(hashed_process_data_in == NULL)
+  {
+    g_assert(pid_in == 0 || pid_in != process_in->ppid);
+    ProcessInfo *process_info;
+    Drawing_t *drawing = control_flow_data->drawing;
+    /* Process not present */
+    processlist_add(process_list,
+        drawing,
+        pid_in,
+        process_in->cpu,
+        process_in->ppid,
+        &birth,
+        tfc->t_context->index,
+        process_in->name,
+        &pl_height,
+        &process_info,
+        &hashed_process_data_in);
+        gtk_widget_set_size_request(drawing->drawing_area,
+                                    -1,
+                                    pl_height);
+        gtk_widget_queue_draw(drawing->drawing_area);
+  }
+  /* Set the current process */
+  process_list->current_hash_data[process_in->cpu] =
+                                             hashed_process_data_in;
+
+  if(ltt_time_compare(hashed_process_data_in->next_good_time,
+                          evtime) <= 0)
+  {
+    TimeWindow time_window = 
+    lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+    if(ltt_time_compare(evtime, time_window.start_time) == -1
+        || ltt_time_compare(evtime, time_window.end_time) == 1)
+            return;
+#endif //EXTRA_CHECK
+    Drawing_t *drawing = control_flow_data->drawing;
+    guint width = drawing->width;
+    guint new_x;
+    
+    convert_time_to_pixels(
+        time_window,
+        evtime,
+        width,
+        &new_x);
+
+    if(hashed_process_data_in->x.middle != new_x) {
+      hashed_process_data_in->x.middle = new_x;
+      hashed_process_data_in->x.middle_used = FALSE;
+      hashed_process_data_in->x.middle_marked = FALSE;
+    }
+  }
+  return 0;
+}
+
+
+
+
+/* before_execmode_hook
+ * 
+ * This function basically draw lines and icons. Two types of lines are drawn :
+ * one small (3 pixels?) representing the state of the process and the second
+ * type is thicker (10 pixels?) representing on which CPU a process is running
+ * (and this only in running state).
+ *
+ * Extremums of the lines :
+ * x_min : time of the last event context for this process kept in memory.
+ * x_max : time of the current event.
+ * y : middle of the process in the process list. The process is found in the
+ * list, therefore is it's position in pixels.
+ *
+ * The choice of lines'color is defined by the context of the last event for this
+ * process.
+ */
+
+
+int before_execmode_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+  /* we are in a execmode, before the state update. We must draw the
+   * items corresponding to the state before it changes : now is the right
+   * time to do it.
+   */
+  /* For the pid */
+  //LttvProcessState *process = tfs->process;
+  guint cpu = ltt_tracefile_num(tfc->tf);
+  LttvProcessState *process = ts->running_process[cpu];
+  g_assert(process != NULL);
+
+  guint pid = process->pid;
+
+  /* Well, the process_out existed : we must get it in the process hash
+   * or add it, and draw its items.
+   */
+   /* Add process to process list (if not present) */
+  guint pl_height = 0;
+  HashedProcessData *hashed_process_data = NULL;
+  ProcessList *process_list = control_flow_data->process_list;
+  LttTime birth = process->creation_time;
+  if(likely(process_list->current_hash_data[cpu] != NULL)) {
+    hashed_process_data = process_list->current_hash_data[cpu];
+  } else {
+    hashed_process_data = processlist_get_process_data(process_list,
+            pid,
+            process->cpu,
+            &birth,
+            tfc->t_context->index);
+    if(unlikely(hashed_process_data == NULL))
+    {
+      g_assert(pid == 0 || pid != process->ppid);
+      ProcessInfo *process_info;
+      /* Process not present */
+      Drawing_t *drawing = control_flow_data->drawing;
+      processlist_add(process_list,
+          drawing,
+          pid,
+          process->cpu,
+          process->ppid,
+          &birth,
+          tfc->t_context->index,
+          process->name,
+          &pl_height,
+          &process_info,
+          &hashed_process_data);
+        gtk_widget_set_size_request(drawing->drawing_area,
+                                    -1,
+                                    pl_height);
+        gtk_widget_queue_draw(drawing->drawing_area);
+    }
+    /* Set the current process */
+    process_list->current_hash_data[process->cpu] =
+                                               hashed_process_data;
+  }
+
+  /* Now, the process is in the state hash and our own process hash.
+   * We definitely can draw the items related to the ending state.
+   */
+
+  if(likely(ltt_time_compare(hashed_process_data->next_good_time,
+                      evtime) > 0))
+  {
+    if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+      TimeWindow time_window = 
+        lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+      if(ltt_time_compare(evtime, time_window.start_time) == -1
+            || ltt_time_compare(evtime, time_window.end_time) == 1)
+                return;
+#endif //EXTRA_CHECK
+      Drawing_t *drawing = control_flow_data->drawing;
+      guint width = drawing->width;
+      guint x;
+      convert_time_to_pixels(
+                time_window,
+                evtime,
+                width,
+                &x);
+
+      /* Draw collision indicator */
+      gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+      gdk_draw_point(hashed_process_data->pixmap,
+                     drawing->gc,
+                     x,
+                     (hashed_process_data->height/2)-3);
+      hashed_process_data->x.middle_marked = TRUE;
+    }
+  } else {
+    TimeWindow time_window = 
+      lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+    if(ltt_time_compare(evtime, time_window.start_time) == -1
+          || ltt_time_compare(evtime, time_window.end_time) == 1)
+              return;
+#endif //EXTRA_CHECK
+    Drawing_t *drawing = control_flow_data->drawing;
+    guint width = drawing->width;
+    guint x;
+
+    convert_time_to_pixels(
+        time_window,
+        evtime,
+        width,
+        &x);
+
+
+    /* Jump over draw if we are at the same x position */
+    if(unlikely(x == hashed_process_data->x.middle &&
+             hashed_process_data->x.middle_used))
+    {
+      if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+        /* Draw collision indicator */
+        gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+        gdk_draw_point(hashed_process_data->pixmap,
+                       drawing->gc,
+                       x,
+                       (hashed_process_data->height/2)-3);
+        hashed_process_data->x.middle_marked = TRUE;
+      }
+      /* jump */
+    } else {
+
+      DrawContext draw_context;
+      /* Now create the drawing context that will be used to draw
+       * items related to the last state. */
+      draw_context.drawable = hashed_process_data->pixmap;
+      draw_context.gc = drawing->gc;
+      draw_context.pango_layout = drawing->pango_layout;
+      draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+      draw_context.drawinfo.end.x = x;
+
+      draw_context.drawinfo.y.over = 1;
+      draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+      draw_context.drawinfo.y.under = hashed_process_data->height;
+
+      draw_context.drawinfo.start.offset.over = 0;
+      draw_context.drawinfo.start.offset.middle = 0;
+      draw_context.drawinfo.start.offset.under = 0;
+      draw_context.drawinfo.end.offset.over = 0;
+      draw_context.drawinfo.end.offset.middle = 0;
+      draw_context.drawinfo.end.offset.under = 0;
+
+      {
+        /* Draw the line */
+        PropertiesLine prop_line = prepare_s_e_line(process);
+        draw_line((void*)&prop_line, (void*)&draw_context);
+
+      }
+      /* become the last x position */
+      hashed_process_data->x.middle = x;
+      hashed_process_data->x.middle_used = TRUE;
+      hashed_process_data->x.middle_marked = FALSE;
+
+      /* Calculate the next good time */
+      convert_pixels_to_time(width, x+1, time_window,
+                             &hashed_process_data->next_good_time);
+    }
+  }
+  
+  return 0;
+}
+
+/* before_process_exit_hook
+ * 
+ * Draw lines for process event.
+ *
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context.
+ *
+ * This function adds items to be drawn in a queue for each process.
+ * 
+ */
+
+
+int before_process_exit_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+  /* Add process to process list (if not present) */
+  //LttvProcessState *process = tfs->process;
+  guint cpu = ltt_tracefile_num(tfc->tf);
+  LttvProcessState *process = ts->running_process[cpu];
+  guint pid = process->pid;
+  LttTime birth;
+  guint pl_height = 0;
+  HashedProcessData *hashed_process_data = NULL;
+
+  ProcessList *process_list = control_flow_data->process_list;
+  
+  g_assert(process != NULL);
+
+  birth = process->creation_time;
+
+  if(likely(process_list->current_hash_data[cpu] != NULL)) {
+    hashed_process_data = process_list->current_hash_data[cpu];
+  } else {
+    hashed_process_data = processlist_get_process_data(process_list,
+          pid,
+          process->cpu,
+          &birth,
+          tfc->t_context->index);
+    if(unlikely(hashed_process_data == NULL))
+    {
+      g_assert(pid == 0 || pid != process->ppid);
+      /* Process not present */
+      Drawing_t *drawing = control_flow_data->drawing;
+      ProcessInfo *process_info;
+      processlist_add(process_list,
+          drawing,
+          pid,
+          process->cpu,
+          process->ppid,
+          &birth,
+          tfc->t_context->index,
+          process->name,
+          &pl_height,
+          &process_info,
+          &hashed_process_data);
+      gtk_widget_set_size_request(drawing->drawing_area,
+                                  -1,
+                                  pl_height);
+      gtk_widget_queue_draw(drawing->drawing_area);
+    }
+  }
+
+  /* Now, the process is in the state hash and our own process hash.
+   * We definitely can draw the items related to the ending state.
+   */
+  
+  if(likely(ltt_time_compare(hashed_process_data->next_good_time,
+                      evtime) > 0))
+  {
+    if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+      TimeWindow time_window = 
+        lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+      if(ltt_time_compare(evtime, time_window.start_time) == -1
+            || ltt_time_compare(evtime, time_window.end_time) == 1)
+                return;
+#endif //EXTRA_CHECK
+      Drawing_t *drawing = control_flow_data->drawing;
+      guint width = drawing->width;
+      guint x;
+      convert_time_to_pixels(
+                time_window,
+                evtime,
+                width,
+                &x);
+
+      /* Draw collision indicator */
+      gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+      gdk_draw_point(hashed_process_data->pixmap,
+                     drawing->gc,
+                     x,
+                     (hashed_process_data->height/2)-3);
+      hashed_process_data->x.middle_marked = TRUE;
+    }
+  } else {
+    TimeWindow time_window = 
+      lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+    if(ltt_time_compare(evtime, time_window.start_time) == -1
+          || ltt_time_compare(evtime, time_window.end_time) == 1)
+              return;
+#endif //EXTRA_CHECK
+    Drawing_t *drawing = control_flow_data->drawing;
+    guint width = drawing->width;
+    guint x;
+
+    convert_time_to_pixels(
+        time_window,
+        evtime,
+        width,
+        &x);
+
+
+    /* Jump over draw if we are at the same x position */
+    if(unlikely(x == hashed_process_data->x.middle &&
+           hashed_process_data->x.middle_used))
+    { 
+      if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+        /* Draw collision indicator */
+        gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+        gdk_draw_point(hashed_process_data->pixmap,
+                       drawing->gc,
+                       x,
+                       (hashed_process_data->height/2)-3);
+        hashed_process_data->x.middle_marked = TRUE;
+      }
+      /* jump */
+    } else {
+      DrawContext draw_context;
+
+      /* Now create the drawing context that will be used to draw
+       * items related to the last state. */
+      draw_context.drawable = hashed_process_data->pixmap;
+      draw_context.gc = drawing->gc;
+      draw_context.pango_layout = drawing->pango_layout;
+      draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+      draw_context.drawinfo.end.x = x;
+
+      draw_context.drawinfo.y.over = 1;
+      draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+      draw_context.drawinfo.y.under = hashed_process_data->height;
+
+      draw_context.drawinfo.start.offset.over = 0;
+      draw_context.drawinfo.start.offset.middle = 0;
+      draw_context.drawinfo.start.offset.under = 0;
+      draw_context.drawinfo.end.offset.over = 0;
+      draw_context.drawinfo.end.offset.middle = 0;
+      draw_context.drawinfo.end.offset.under = 0;
+
+      {
+        /* Draw the line */
+        PropertiesLine prop_line = prepare_s_e_line(process);
+        draw_line((void*)&prop_line, (void*)&draw_context);
+
+      }
+      /* become the last x position */
+      hashed_process_data->x.middle = x;
+      hashed_process_data->x.middle_used = TRUE;
+      hashed_process_data->x.middle_marked = FALSE;
+
+      /* Calculate the next good time */
+      convert_pixels_to_time(width, x+1, time_window,
+                             &hashed_process_data->next_good_time);
+    }
+  }
+  
+  return 0;
+
+}
+
+
+
+/* before_process_release_hook
+ * 
+ * Draw lines for process event.
+ *
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context.
+ *
+ * This function adds items to be drawn in a queue for each process.
+ * 
+ */
+
+
+int before_process_release_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+
+  guint pid;
+  {
+    pid = ltt_event_get_long_unsigned(e, thf->f1);
+  }
+
+  /* Add process to process list (if not present) */
+  /* Don't care about the process if it's not in the state hash already :
+   * that means a process that has never done anything in the trace and
+   * unknown suddently gets destroyed : no state meaningful to show. */
+  LttvProcessState *process = lttv_state_find_process(ts, ANY_CPU, pid);
+
+  if(process != NULL) {
+    LttTime birth;
+    guint pl_height = 0;
+    HashedProcessData *hashed_process_data = NULL;
+
+    ProcessList *process_list = control_flow_data->process_list;
+    
+    birth = process->creation_time;
+
+    /* Cannot use current process : this event happens on another process,
+     * action done by the parent. */
+    hashed_process_data = processlist_get_process_data(process_list,
+          pid,
+          process->cpu,
+          &birth,
+          tfc->t_context->index);
+    if(unlikely(hashed_process_data == NULL))
+    {
+      g_assert(pid == 0 || pid != process->ppid);
+      /* Process not present */
+      Drawing_t *drawing = control_flow_data->drawing;
+      ProcessInfo *process_info;
+      processlist_add(process_list,
+          drawing,
+          pid,
+          process->cpu,
+          process->ppid,
+          &birth,
+          tfc->t_context->index,
+          process->name,
+          &pl_height,
+          &process_info,
+          &hashed_process_data);
+      gtk_widget_set_size_request(drawing->drawing_area,
+                                  -1,
+                                  pl_height);
+      gtk_widget_queue_draw(drawing->drawing_area);
+    }
+
+    /* Now, the process is in the state hash and our own process hash.
+     * We definitely can draw the items related to the ending state.
+     */
+    
+    if(likely(ltt_time_compare(hashed_process_data->next_good_time,
+                        evtime) > 0))
+    {
+      if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+        TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+        if(ltt_time_compare(evtime, time_window.start_time) == -1
+              || ltt_time_compare(evtime, time_window.end_time) == 1)
+                  return;
+#endif //EXTRA_CHECK
+        Drawing_t *drawing = control_flow_data->drawing;
+        guint width = drawing->width;
+        guint x;
+        convert_time_to_pixels(
+                  time_window,
+                  evtime,
+                  width,
+                  &x);
+
+        /* Draw collision indicator */
+        gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+        gdk_draw_point(hashed_process_data->pixmap,
+                       drawing->gc,
+                       x,
+                       (hashed_process_data->height/2)-3);
+        hashed_process_data->x.middle_marked = TRUE;
+      }
+    } else {
+      TimeWindow time_window = 
+        lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+      if(ltt_time_compare(evtime, time_window.start_time) == -1
+            || ltt_time_compare(evtime, time_window.end_time) == 1)
+                return;
+#endif //EXTRA_CHECK
+      Drawing_t *drawing = control_flow_data->drawing;
+      guint width = drawing->width;
+      guint x;
+
+      convert_time_to_pixels(
+          time_window,
+          evtime,
+          width,
+          &x);
+
+
+      /* Jump over draw if we are at the same x position */
+      if(unlikely(x == hashed_process_data->x.middle &&
+             hashed_process_data->x.middle_used))
+      { 
+        if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
+          /* Draw collision indicator */
+          gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+          gdk_draw_point(hashed_process_data->pixmap,
+                         drawing->gc,
+                         x,
+                         (hashed_process_data->height/2)-3);
+          hashed_process_data->x.middle_marked = TRUE;
+        }
+        /* jump */
+      } else {
+        DrawContext draw_context;
+
+        /* Now create the drawing context that will be used to draw
+         * items related to the last state. */
+        draw_context.drawable = hashed_process_data->pixmap;
+        draw_context.gc = drawing->gc;
+        draw_context.pango_layout = drawing->pango_layout;
+        draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+        draw_context.drawinfo.end.x = x;
+
+        draw_context.drawinfo.y.over = 1;
+        draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+        draw_context.drawinfo.y.under = hashed_process_data->height;
+
+        draw_context.drawinfo.start.offset.over = 0;
+        draw_context.drawinfo.start.offset.middle = 0;
+        draw_context.drawinfo.start.offset.under = 0;
+        draw_context.drawinfo.end.offset.over = 0;
+        draw_context.drawinfo.end.offset.middle = 0;
+        draw_context.drawinfo.end.offset.under = 0;
+
+        {
+          /* Draw the line */
+          PropertiesLine prop_line = prepare_s_e_line(process);
+          draw_line((void*)&prop_line, (void*)&draw_context);
+
+        }
+        /* become the last x position */
+        hashed_process_data->x.middle = x;
+        hashed_process_data->x.middle_used = TRUE;
+        hashed_process_data->x.middle_marked = FALSE;
+
+        /* Calculate the next good time */
+        convert_pixels_to_time(width, x+1, time_window,
+                               &hashed_process_data->next_good_time);
+      }
+    }
+  }
+
+  return 0;
+}
+
+
+
+
+
+/* after_process_fork_hook
+ * 
+ * Create the processlist entry for the child process. Put the last
+ * position in x at the current time value.
+ *
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context.
+ *
+ * This function adds items to be drawn in a queue for each process.
+ * 
+ */
+int after_process_fork_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+  guint child_pid;
+  {
+    child_pid = ltt_event_get_long_unsigned(e, thf->f2);
+  }
+
+  /* Add process to process list (if not present) */
+  LttvProcessState *process_child;
+  LttTime birth;
+  guint pl_height = 0;
+  HashedProcessData *hashed_process_data_child = NULL;
+
+  ProcessList *process_list = control_flow_data->process_list;
+
+  /* Find child in the list... */
+  process_child = lttv_state_find_process(ts, ANY_CPU, child_pid);
+  /* It should exist, because we are after the state update. */
+  g_assert(process_child != NULL);
+
+  birth = process_child->creation_time;
+
+  /* Cannot use current process, because this action is done by the parent
+   * on its child. */
+  hashed_process_data_child = processlist_get_process_data(process_list,
+          child_pid,
+          process_child->cpu,
+          &birth,
+          tfc->t_context->index);
+  if(likely(hashed_process_data_child == NULL))
+  {
+    g_assert(child_pid == 0 || child_pid != process_child->ppid);
+    /* Process not present */
+    Drawing_t *drawing = control_flow_data->drawing;
+    ProcessInfo *process_info;
+    processlist_add(process_list,
+        drawing,
+        child_pid,
+        process_child->cpu,
+        process_child->ppid,
+        &birth,
+        tfc->t_context->index,
+        process_child->name,
+        &pl_height,
+        &process_info,
+        &hashed_process_data_child);
+      gtk_widget_set_size_request(drawing->drawing_area,
+                                  -1,
+                                  pl_height);
+      gtk_widget_queue_draw(drawing->drawing_area);
+  }
+
+
+  if(likely(ltt_time_compare(hashed_process_data_child->next_good_time,
+                        evtime) <= 0))
+  {
+    TimeWindow time_window = 
+      lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+    if(ltt_time_compare(evtime, time_window.start_time) == -1
+          || ltt_time_compare(evtime, time_window.end_time) == 1)
+              return;
+#endif //EXTRA_CHECK
+    Drawing_t *drawing = control_flow_data->drawing;
+    guint width = drawing->width;
+    guint new_x;
+    convert_time_to_pixels(
+        time_window,
+        evtime,
+        width,
+        &new_x);
+
+    if(likely(hashed_process_data_child->x.over != new_x)) {
+      hashed_process_data_child->x.over = new_x;
+      hashed_process_data_child->x.over_used = FALSE;
+      hashed_process_data_child->x.over_marked = FALSE;
+    }
+    if(likely(hashed_process_data_child->x.middle != new_x)) {
+      hashed_process_data_child->x.middle = new_x;
+      hashed_process_data_child->x.middle_used = FALSE;
+      hashed_process_data_child->x.middle_marked = FALSE;
+    }
+    if(likely(hashed_process_data_child->x.under != new_x)) {
+      hashed_process_data_child->x.under = new_x;
+      hashed_process_data_child->x.under_used = FALSE;
+      hashed_process_data_child->x.under_marked = FALSE;
+    }
+  }
+  return 0;
+}
+
+
+
+/* after_process_exit_hook
+ * 
+ * Create the processlist entry for the child process. Put the last
+ * position in x at the current time value.
+ *
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context.
+ *
+ * This function adds items to be drawn in a queue for each process.
+ * 
+ */
+int after_process_exit_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  LttEvent *e;
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  LttTime evtime = ltt_event_time(e);
+
+  /* Add process to process list (if not present) */
+  //LttvProcessState *process = tfs->process;
+  guint cpu = ltt_tracefile_num(tfc->tf);
+  LttvProcessState *process = ts->running_process[cpu];
+
+  /* It should exist, because we are after the state update. */
+  g_assert(process != NULL);
+
+  guint pid = process->pid;
+  LttTime birth;
+  guint pl_height = 0;
+  HashedProcessData *hashed_process_data = NULL;
+
+  ProcessList *process_list = control_flow_data->process_list;
+
+  birth = process->creation_time;
+
+  if(likely(process_list->current_hash_data[cpu] != NULL) ){
+    hashed_process_data = process_list->current_hash_data[cpu];
+  } else {
+    hashed_process_data = processlist_get_process_data(process_list,
+            pid,
+            process->cpu,
+            &birth,
+            tfc->t_context->index);
+    if(unlikely(hashed_process_data == NULL))
+    {
+      g_assert(pid == 0 || pid != process->ppid);
+      /* Process not present */
+      Drawing_t *drawing = control_flow_data->drawing;
+      ProcessInfo *process_info;
+      processlist_add(process_list,
+          drawing,
+          pid,
+          process->cpu,
+          process->ppid,
+          &birth,
+          tfc->t_context->index,
+          process->name,
+          &pl_height,
+          &process_info,
+          &hashed_process_data);
+      gtk_widget_set_size_request(drawing->drawing_area,
+                                  -1,
+                                  pl_height);
+      gtk_widget_queue_draw(drawing->drawing_area);
+    }
+
+    /* Set the current process */
+    process_list->current_hash_data[process->cpu] =
+                                             hashed_process_data;
+  }
+
+  if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
+                        evtime) <= 0))
+  {
+    TimeWindow time_window = 
+      lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+    if(ltt_time_compare(evtime, time_window.start_time) == -1
+          || ltt_time_compare(evtime, time_window.end_time) == 1)
+              return;
+#endif //EXTRA_CHECK
+    Drawing_t *drawing = control_flow_data->drawing;
+    guint width = drawing->width;
+    guint new_x;
+    convert_time_to_pixels(
+        time_window,
+        evtime,
+        width,
+        &new_x);
+    if(unlikely(hashed_process_data->x.middle != new_x)) {
+      hashed_process_data->x.middle = new_x;
+      hashed_process_data->x.middle_used = FALSE;
+      hashed_process_data->x.middle_marked = FALSE;
+    }
+  }
+
+  return 0;
+}
+
+
+/* Get the filename of the process to print */
+int after_fs_exec_hook(void *hook_data, void *call_data)
+{
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  EventsRequest *events_request = (EventsRequest*)thf->hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
+  guint cpu = ltt_tracefile_num(tfc->tf);
+  LttvProcessState *process = ts->running_process[cpu];
+  g_assert(process != NULL);
+
+  guint pid = process->pid;
+
+  /* Well, the process_out existed : we must get it in the process hash
+   * or add it, and draw its items.
+   */
+   /* Add process to process list (if not present) */
+  guint pl_height = 0;
+  HashedProcessData *hashed_process_data = NULL;
+  ProcessList *process_list = control_flow_data->process_list;
+  LttTime birth = process->creation_time;
+  if(likely(process_list->current_hash_data[cpu] != NULL)) {
+    hashed_process_data = process_list->current_hash_data[cpu];
+  } else {
+    hashed_process_data = processlist_get_process_data(process_list,
+            pid,
+            process->cpu,
+            &birth,
+            tfc->t_context->index);
+    if(unlikely(hashed_process_data == NULL))
+    {
+      g_assert(pid == 0 || pid != process->ppid);
+      ProcessInfo *process_info;
+      /* Process not present */
+      Drawing_t *drawing = control_flow_data->drawing;
+      processlist_add(process_list,
+          drawing,
+          pid,
+          process->cpu,
+          process->ppid,
+          &birth,
+          tfc->t_context->index,
+          process->name,
+          &pl_height,
+          &process_info,
+          &hashed_process_data);
+        gtk_widget_set_size_request(drawing->drawing_area,
+                                    -1,
+                                    pl_height);
+        gtk_widget_queue_draw(drawing->drawing_area);
+    }
+    /* Set the current process */
+    process_list->current_hash_data[process->cpu] =
+                                               hashed_process_data;
+  }
+
+  processlist_set_name(process_list, process->name, hashed_process_data);
+
+  return 0;
+
+}
+
+
+
+
+gint update_time_window_hook(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
+  Drawing_t *drawing = control_flow_data->drawing;
+  ProcessList *process_list = control_flow_data->process_list;
+
+  const TimeWindowNotifyData *time_window_nofify_data = 
+                          ((const TimeWindowNotifyData *)call_data);
+
+  TimeWindow *old_time_window = 
+    time_window_nofify_data->old_time_window;
+  TimeWindow *new_time_window = 
+    time_window_nofify_data->new_time_window;
+  
+  /* Update the ruler */
+  drawing_update_ruler(control_flow_data->drawing,
+                       new_time_window);
+
+
+  /* Two cases : zoom in/out or scrolling */
+  
+  /* In order to make sure we can reuse the old drawing, the scale must
+   * be the same and the new time interval being partly located in the
+   * currently shown time interval. (reuse is only for scrolling)
+   */
+
+  g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
+      old_time_window->start_time.tv_sec,
+      old_time_window->start_time.tv_nsec,
+      old_time_window->time_width.tv_sec,
+      old_time_window->time_width.tv_nsec);
+
+  g_info("New time window HOOK : %lu, %lu to %lu, %lu",
+      new_time_window->start_time.tv_sec,
+      new_time_window->start_time.tv_nsec,
+      new_time_window->time_width.tv_sec,
+      new_time_window->time_width.tv_nsec);
+
+  if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
+  && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
+  {
+    /* Same scale (scrolling) */
+    g_info("scrolling");
+    LttTime *ns = &new_time_window->start_time;
+    LttTime *nw = &new_time_window->time_width;
+    LttTime *os = &old_time_window->start_time;
+    LttTime *ow = &old_time_window->time_width;
+    LttTime old_end = old_time_window->end_time;
+    LttTime new_end = new_time_window->end_time;
+    //if(ns<os+w<ns+w)
+    //if(ns<os+w && os+w<ns+w)
+    //if(ns<old_end && os<ns)
+    if(ltt_time_compare(*ns, old_end) == -1
+        && ltt_time_compare(*os, *ns) == -1)
+    {
+      g_info("scrolling near right");
+      /* Scroll right, keep right part of the screen */
+      guint x = 0;
+      guint width = control_flow_data->drawing->width;
+      convert_time_to_pixels(
+          *old_time_window,
+          *ns,
+          width,
+          &x);
+
+      /* Copy old data to new location */
+      copy_pixmap_region(process_list,
+                  NULL,
+                  control_flow_data->drawing->drawing_area->style->black_gc,
+                  NULL,
+                  x, 0,
+                  0, 0,
+                  control_flow_data->drawing->width-x+SAFETY, -1);
+
+      if(drawing->damage_begin == drawing->damage_end)
+        drawing->damage_begin = control_flow_data->drawing->width-x;
+      else
+        drawing->damage_begin = 0;
+
+      drawing->damage_end = control_flow_data->drawing->width;
+
+      /* Clear the data request background, but not SAFETY */
+      rectangle_pixmap(process_list,
+          control_flow_data->drawing->drawing_area->style->black_gc,
+          TRUE,
+          drawing->damage_begin+SAFETY, 0,
+          drawing->damage_end - drawing->damage_begin,  // do not overlap
+          -1);
+      gtk_widget_queue_draw(drawing->drawing_area);
+      //gtk_widget_queue_draw_area (drawing->drawing_area,
+      //                          0,0,
+      //                          control_flow_data->drawing->width,
+      //                          control_flow_data->drawing->height);
+
+      /* Get new data for the rest. */
+      drawing_data_request(control_flow_data->drawing,
+          drawing->damage_begin, 0,
+          drawing->damage_end - drawing->damage_begin,
+          control_flow_data->drawing->height);
+    } else { 
+      //if(ns<os<ns+w)
+      //if(ns<os && os<ns+w)
+      //if(ns<os && os<new_end)
+      if(ltt_time_compare(*ns,*os) == -1
+          && ltt_time_compare(*os,new_end) == -1)
+      {
+        g_info("scrolling near left");
+        /* Scroll left, keep left part of the screen */
+        guint x = 0;
+        guint width = control_flow_data->drawing->width;
+        convert_time_to_pixels(
+            *new_time_window,
+            *os,
+            width,
+            &x);
+        
+        /* Copy old data to new location */
+        copy_pixmap_region  (process_list,
+            NULL,
+            control_flow_data->drawing->drawing_area->style->black_gc,
+            NULL,
+            0, 0,
+            x, 0,
+            -1, -1);
+  
+        if(drawing->damage_begin == drawing->damage_end)
+          drawing->damage_end = x;
+        else
+          drawing->damage_end = 
+            control_flow_data->drawing->width;
+
+        drawing->damage_begin = 0;
+        
+        rectangle_pixmap (process_list,
+          control_flow_data->drawing->drawing_area->style->black_gc,
+          TRUE,
+          drawing->damage_begin, 0,
+          drawing->damage_end - drawing->damage_begin,  // do not overlap
+          -1);
+
+        gtk_widget_queue_draw(drawing->drawing_area);
+        //gtk_widget_queue_draw_area (drawing->drawing_area,
+        //                        0,0,
+        //                        control_flow_data->drawing->width,
+        //                        control_flow_data->drawing->height);
+
+
+        /* Get new data for the rest. */
+        drawing_data_request(control_flow_data->drawing,
+            drawing->damage_begin, 0,
+            drawing->damage_end - drawing->damage_begin,
+            control_flow_data->drawing->height);
+    
+      } else {
+        if(ltt_time_compare(*ns,*os) == 0)
+        {
+          g_info("not scrolling");
+        } else {
+          g_info("scrolling far");
+          /* Cannot reuse any part of the screen : far jump */
+          
+          
+          rectangle_pixmap (process_list,
+            control_flow_data->drawing->drawing_area->style->black_gc,
+            TRUE,
+            0, 0,
+            control_flow_data->drawing->width+SAFETY, // do not overlap
+            -1);
+
+          //gtk_widget_queue_draw_area (drawing->drawing_area,
+          //                      0,0,
+          //                      control_flow_data->drawing->width,
+          //                      control_flow_data->drawing->height);
+          gtk_widget_queue_draw(drawing->drawing_area);
+
+          drawing->damage_begin = 0;
+          drawing->damage_end = control_flow_data->drawing->width;
+
+          drawing_data_request(control_flow_data->drawing,
+              0, 0,
+              control_flow_data->drawing->width,
+              control_flow_data->drawing->height);
+      
+        }
+      }
+    }
+  } else {
+    /* Different scale (zoom) */
+    g_info("zoom");
+
+    rectangle_pixmap (process_list,
+          control_flow_data->drawing->drawing_area->style->black_gc,
+          TRUE,
+          0, 0,
+          control_flow_data->drawing->width+SAFETY, // do not overlap
+          -1);
+
+    //gtk_widget_queue_draw_area (drawing->drawing_area,
+    //                            0,0,
+    //                            control_flow_data->drawing->width,
+    //                            control_flow_data->drawing->height);
+    gtk_widget_queue_draw(drawing->drawing_area);
+  
+    drawing->damage_begin = 0;
+    drawing->damage_end = control_flow_data->drawing->width;
+
+    drawing_data_request(control_flow_data->drawing,
+        0, 0,
+        control_flow_data->drawing->width,
+        control_flow_data->drawing->height);
+  }
+
+  /* Update directly when scrolling */
+  gdk_window_process_updates(control_flow_data->drawing->drawing_area->window,
+      TRUE);
+
+  return 0;
+}
+
+gint traceset_notify(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
+  Drawing_t *drawing = control_flow_data->drawing;
+
+  if(unlikely(drawing->gc == NULL)) {
+    return FALSE;
+  }
+  if(drawing->dotted_gc == NULL) {
+    return FALSE;
+  }
+
+  drawing_clear(control_flow_data->drawing);
+  processlist_clear(control_flow_data->process_list);
+  gtk_widget_set_size_request(
+      control_flow_data->drawing->drawing_area,
+                -1, processlist_get_height(control_flow_data->process_list));
+  redraw_notify(control_flow_data, NULL);
+
+  request_background_data(control_flow_data);
+  return FALSE;
+}
+
+gint redraw_notify(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
+  Drawing_t *drawing = control_flow_data->drawing;
+  GtkWidget *widget = drawing->drawing_area;
+
+  drawing->damage_begin = 0;
+  drawing->damage_end = drawing->width;
+
+  /* fun feature, to be separated someday... */
+  drawing_clear(control_flow_data->drawing);
+  processlist_clear(control_flow_data->process_list);
+  gtk_widget_set_size_request(
+      control_flow_data->drawing->drawing_area,
+                -1, processlist_get_height(control_flow_data->process_list));
+  // Clear the images
+  rectangle_pixmap (control_flow_data->process_list,
+        widget->style->black_gc,
+        TRUE,
+        0, 0,
+        drawing->alloc_width,
+        -1);
+
+  gtk_widget_queue_draw(drawing->drawing_area);
+  
+  if(drawing->damage_begin < drawing->damage_end)
+  {
+    drawing_data_request(drawing,
+                         drawing->damage_begin,
+                         0,
+                         drawing->damage_end-drawing->damage_begin,
+                         drawing->height);
+  }
+
+  //gtk_widget_queue_draw_area(drawing->drawing_area,
+  //                           0,0,
+  //                           drawing->width,
+  //                           drawing->height);
+  return FALSE;
+
+}
+
+
+gint continue_notify(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
+  Drawing_t *drawing = control_flow_data->drawing;
+
+  //g_assert(widget->allocation.width == drawing->damage_end);
+
+  if(drawing->damage_begin < drawing->damage_end)
+  {
+    drawing_data_request(drawing,
+                         drawing->damage_begin,
+                         0,
+                         drawing->damage_end-drawing->damage_begin,
+                         drawing->height);
+  }
+
+  return FALSE;
+}
+
+
+gint update_current_time_hook(void *hook_data, void *call_data)
+{
+  ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
+  Drawing_t *drawing = control_flow_data->drawing;
+
+  LttTime current_time = *((LttTime*)call_data);
+  
+  TimeWindow time_window =
+            lttvwindow_get_time_window(control_flow_data->tab);
+  
+  LttTime time_begin = time_window.start_time;
+  LttTime width = time_window.time_width;
+  LttTime half_width;
+  {
+    guint64 time_ll = ltt_time_to_uint64(width);
+    time_ll = time_ll >> 1; /* divide by two */
+    half_width = ltt_time_from_uint64(time_ll);
+  }
+  LttTime time_end = ltt_time_add(time_begin, width);
+
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(control_flow_data->tab);
+  
+  LttTime trace_start = tsc->time_span.start_time;
+  LttTime trace_end = tsc->time_span.end_time;
+  
+  g_info("New current time HOOK : %lu, %lu", current_time.tv_sec,
+              current_time.tv_nsec);
+
+
+  
+  /* If current time is inside time interval, just move the highlight
+   * bar */
+
+  /* Else, we have to change the time interval. We have to tell it
+   * to the main window. */
+  /* The time interval change will take care of placing the current
+   * time at the center of the visible area, or nearest possible if we are
+   * at one end of the trace. */
+  
+  
+  if(ltt_time_compare(current_time, time_begin) < 0)
+  {
+    TimeWindow new_time_window;
+
+    if(ltt_time_compare(current_time,
+          ltt_time_add(trace_start,half_width)) < 0)
+      time_begin = trace_start;
+    else
+      time_begin = ltt_time_sub(current_time,half_width);
+  
+    new_time_window.start_time = time_begin;
+    new_time_window.time_width = width;
+    new_time_window.time_width_double = ltt_time_to_double(width);
+    new_time_window.end_time = ltt_time_add(time_begin, width);
+
+    lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
+  }
+  else if(ltt_time_compare(current_time, time_end) > 0)
+  {
+    TimeWindow new_time_window;
+
+    if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
+      time_begin = ltt_time_sub(trace_end,width);
+    else
+      time_begin = ltt_time_sub(current_time,half_width);
+  
+    new_time_window.start_time = time_begin;
+    new_time_window.time_width = width;
+    new_time_window.time_width_double = ltt_time_to_double(width);
+    new_time_window.end_time = ltt_time_add(time_begin, width);
+
+    lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
+    
+  }
+  gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
+  
+  /* Update directly when scrolling */
+  gdk_window_process_updates(control_flow_data->drawing->drawing_area->window,
+      TRUE);
+                             
+  return 0;
+}
+
+typedef struct _ClosureData {
+  EventsRequest *events_request;
+  LttvTracesetState *tss;
+  LttTime end_time;
+  guint x_end;
+} ClosureData;
+  
+
+void draw_closure(gpointer key, gpointer value, gpointer user_data)
+{
+  ProcessInfo *process_info = (ProcessInfo*)key;
+  HashedProcessData *hashed_process_data = (HashedProcessData*)value;
+  ClosureData *closure_data = (ClosureData*)user_data;
+    
+  EventsRequest *events_request = closure_data->events_request;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+
+  LttvTracesetState *tss = closure_data->tss;
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+
+  LttTime evtime = closure_data->end_time;
+
+  { 
+    /* For the process */
+    /* First, check if the current process is in the state computation
+     * process list. If it is there, that means we must add it right now and
+     * draw items from the beginning of the read for it. If it is not
+     * present, it's a new process and it was not present : it will
+     * be added after the state update.  */
+#ifdef EXTRA_CHECK
+    g_assert(lttv_traceset_number(tsc->ts) > 0);
+#endif //EXTRA_CHECK
+    LttvTraceContext *tc = tsc->traces[process_info->trace_num];
+    LttvTraceState *ts = (LttvTraceState*)tc;
+
+#if 0
+    //FIXME : optimize data structures.
+    LttvTracefileState *tfs;
+    LttvTracefileContext *tfc;
+    guint i;
+    for(i=0;i<tc->tracefiles->len;i++) {
+      tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, i);
+      if(ltt_tracefile_name(tfc->tf) == LTT_NAME_CPU
+          && ltt_tracefile_num(tfc->tf) == process_info->cpu)
+        break;
+
+    }
+    g_assert(i<tc->tracefiles->len);
+    tfs = LTTV_TRACEFILE_STATE(tfc);
+#endif //0
+ //   LttvTracefileState *tfs =
+ //    (LttvTracefileState*)tsc->traces[process_info->trace_num]->
+ //                        tracefiles[process_info->cpu];
+    LttvProcessState *process;
+    process = lttv_state_find_process(ts, process_info->cpu,
+                                      process_info->pid);
+
+    if(unlikely(process != NULL)) {
+      
+      /* Only draw for processes that are currently in the trace states */
+
+      ProcessList *process_list = control_flow_data->process_list;
+#ifdef EXTRA_CHECK
+      /* Should be alike when background info is ready */
+      if(control_flow_data->background_info_waiting==0)
+        g_assert(ltt_time_compare(process->creation_time,
+                                  process_info->birth) == 0);
+#endif //EXTRA_CHECK
+    
+      /* Now, the process is in the state hash and our own process hash.
+       * We definitely can draw the items related to the ending state.
+       */
+      
+      if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
+                            evtime) <= 0))
+      {
+        TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+
+#ifdef EXTRA_CHECK
+        if(ltt_time_compare(evtime, time_window.start_time) == -1
+              || ltt_time_compare(evtime, time_window.end_time) == 1)
+                  return;
+#endif //EXTRA_CHECK
+        Drawing_t *drawing = control_flow_data->drawing;
+        guint width = drawing->width;
+
+        guint x = closure_data->x_end;
+
+        DrawContext draw_context;
+
+        /* Now create the drawing context that will be used to draw
+         * items related to the last state. */
+        draw_context.drawable = hashed_process_data->pixmap;
+        draw_context.gc = drawing->gc;
+        draw_context.pango_layout = drawing->pango_layout;
+        draw_context.drawinfo.end.x = x;
+
+        draw_context.drawinfo.y.over = 1;
+        draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
+        draw_context.drawinfo.y.under = hashed_process_data->height;
+
+        draw_context.drawinfo.start.offset.over = 0;
+        draw_context.drawinfo.start.offset.middle = 0;
+        draw_context.drawinfo.start.offset.under = 0;
+        draw_context.drawinfo.end.offset.over = 0;
+        draw_context.drawinfo.end.offset.middle = 0;
+        draw_context.drawinfo.end.offset.under = 0;
+#if 0
+        /* Jump over draw if we are at the same x position */
+        if(x == hashed_process_data->x.over)
+        {
+          /* jump */
+        } else {
+          draw_context.drawinfo.start.x = hashed_process_data->x.over;
+          /* Draw the line */
+          PropertiesLine prop_line = prepare_execmode_line(process);
+          draw_line((void*)&prop_line, (void*)&draw_context);
+
+          hashed_process_data->x.over = x;
+        }
+#endif //0
+
+        if(unlikely(x == hashed_process_data->x.middle &&
+            hashed_process_data->x.middle_used)) {
+#if 0 /* do not mark closure : not missing information */
+          if(hashed_process_data->x.middle_marked == FALSE) {
+            /* Draw collision indicator */
+            gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
+            gdk_draw_point(drawing->pixmap,
+                           drawing->gc,
+                           x,
+                           y+(height/2)-3);
+            hashed_process_data->x.middle_marked = TRUE;
+          }
+#endif //0
+          /* Jump */
+        } else {
+          draw_context.drawinfo.start.x = hashed_process_data->x.middle;
+          /* Draw the line */
+          PropertiesLine prop_line = prepare_s_e_line(process);
+          draw_line((void*)&prop_line, (void*)&draw_context);
+
+           /* become the last x position */
+          if(likely(x != hashed_process_data->x.middle)) {
+            hashed_process_data->x.middle = x;
+            /* but don't use the pixel */
+            hashed_process_data->x.middle_used = FALSE;
+
+            /* Calculate the next good time */
+            convert_pixels_to_time(width, x+1, time_window,
+                                  &hashed_process_data->next_good_time);
+          }
+        }
+      }
+    }
+  }
+  return;
+}
+
+int before_chunk(void *hook_data, void *call_data)
+{
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  LttvTracesetState *tss = (LttvTracesetState*)call_data;
+  ControlFlowData *cfd = (ControlFlowData*)events_request->viewer_data;
+#if 0  
+  /* Desactivate sort */
+  gtk_tree_sortable_set_sort_column_id(
+      GTK_TREE_SORTABLE(cfd->process_list->list_store),
+      TRACE_COLUMN,
+      GTK_SORT_ASCENDING);
+#endif //0
+  drawing_chunk_begin(events_request, tss);
+
+  return 0;
+}
+
+int before_request(void *hook_data, void *call_data)
+{
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  LttvTracesetState *tss = (LttvTracesetState*)call_data;
+  drawing_data_request_begin(events_request, tss);
+
+  return 0;
+}
+
+
+/*
+ * after request is necessary in addition of after chunk in order to draw 
+ * lines until the end of the screen. after chunk just draws lines until
+ * the last event.
+ * 
+ * for each process
+ *    draw closing line
+ *    expose
+ */
+int after_request(void *hook_data, void *call_data)
+{
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+  LttvTracesetState *tss = (LttvTracesetState*)call_data;
+  
+  ProcessList *process_list = control_flow_data->process_list;
+  LttTime end_time = events_request->end_time;
+
+  ClosureData closure_data;
+  closure_data.events_request = (EventsRequest*)hook_data;
+  closure_data.tss = tss;
+  closure_data.end_time = end_time;
+
+  TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+  guint width = control_flow_data->drawing->width;
+  convert_time_to_pixels(
+            time_window,
+            end_time,
+            width,
+            &closure_data.x_end);
+
+
+  /* Draw last items */
+  g_hash_table_foreach(process_list->process_hash, draw_closure,
+                        (void*)&closure_data);
+  
+
+  /* Request expose */
+  drawing_request_expose(events_request, tss, end_time);
+  return 0;
+}
+
+/*
+ * for each process
+ *    draw closing line
+ * expose
+ */
+int after_chunk(void *hook_data, void *call_data)
+{
+  EventsRequest *events_request = (EventsRequest*)hook_data;
+  ControlFlowData *control_flow_data = events_request->viewer_data;
+  LttvTracesetState *tss = (LttvTracesetState*)call_data;
+  LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
+  LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
+  LttTime end_time;
+  
+  ProcessList *process_list = control_flow_data->process_list;
+
+  g_free(process_list->current_hash_data);
+  process_list->current_hash_data = NULL;
+  
+  if(tfc != NULL)
+    end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
+  else /* end of traceset, or position now out of request : end */
+    end_time = events_request->end_time;
+  
+  ClosureData closure_data;
+  closure_data.events_request = (EventsRequest*)hook_data;
+  closure_data.tss = tss;
+  closure_data.end_time = end_time;
+
+  TimeWindow time_window = 
+          lttvwindow_get_time_window(control_flow_data->tab);
+  guint width = control_flow_data->drawing->width;
+  convert_time_to_pixels(
+            time_window,
+            end_time,
+            width,
+            &closure_data.x_end);
+
+  /* Draw last items */
+  g_hash_table_foreach(process_list->process_hash, draw_closure,
+                        (void*)&closure_data);
+#if 0
+  /* Reactivate sort */
+  gtk_tree_sortable_set_sort_column_id(
+      GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
+      GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+      GTK_SORT_ASCENDING);
+
+  update_index_to_pixmap(control_flow_data->process_list);
+  /* Request a full expose : drawing scrambled */
+  gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
+#endif //0
+  /* Request expose (updates damages zone also) */
+  drawing_request_expose(events_request, tss, end_time);
+
+  return 0;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/eventhooks.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/eventhooks.h
new file mode 100644 (file)
index 0000000..6f4fdf0
--- /dev/null
@@ -0,0 +1,121 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+/* eventhooks.h defines the hooks that are given to processTrace as parameter.
+ * These hooks call the drawing API to draw the information on the screen,
+ * using information from Context, but mostly state (running, waiting...).
+ */
+
+
+#ifndef _EVENT_HOOKS_H
+#define _EVENT_HOOKS_H
+
+#include <gtk/gtk.h>
+#include <lttvwindow/mainwindow.h>
+#include <ltt/time.h>
+
+#include "processlist.h"
+#include "drawing.h"
+#include "cfv.h"
+
+
+/* Structure used to store and use information relative to one events refresh
+ * request. Typically filled in by the expose event callback, then passed to the
+ * library call, then used by the drawing hooks. Then, once all the events are
+ * sent, it is freed by the hook called after the reading.
+ */
+//typedef struct _EventRequest
+//{
+//  ControlFlowData *control_flow_data;
+//  LttTime time_begin, time_end;
+//  gint  x_begin, x_end;
+  /* Fill the Events_Context during the initial expose, before calling for
+   * events.
+   */
+  //GArray Events_Context; //FIXME
+//} EventRequest ;
+
+
+
+
+
+void send_test_data(ProcessList *process_list, Drawing_t *drawing);
+
+GtkWidget *h_guicontrolflow(Tab *tab);
+
+GtkWidget *h_legend(Tab *tab);
+
+int event_selected_hook(void *hook_data, void *call_data);
+
+/*
+ * The draw event hook is called by the reading API to have a
+ * particular event drawn on the screen.
+ * @param hook_data ControlFlowData structure of the viewer. 
+ * @param call_data Event context with state.
+ *
+ * This function basically draw lines and icons. Two types of lines are drawn :
+ * one small (3 pixels?) representing the state of the process and the second
+ * type is thicker (10 pixels?) representing on which CPU a process is running
+ * (and this only in running state).
+ *
+ * Extremums of the lines :
+ * x_min : time of the last event context for this process kept in memory.
+ * x_max : time of the current event.
+ * y : middle of the process in the process list. The process is found in the
+ * list, therefore is it's position in pixels.
+ *
+ * The choice of lines'color is defined by the context of the last event for this
+ * process.
+ */
+int before_schedchange_hook(void *hook_data, void *call_data);
+int after_schedchange_hook(void *hook_data, void *call_data);
+int before_execmode_hook(void *hook_data, void *call_data);
+int after_execmode_hook(void *hook_data, void *call_data);
+
+
+int before_process_exit_hook(void *hook_data, void *call_data);
+int before_process_release_hook(void *hook_data, void *call_data);
+int after_process_exit_hook(void *hook_data, void *call_data);
+int after_process_fork_hook(void *hook_data, void *call_data);
+int after_fs_exec_hook(void *hook_data, void *call_data);
+
+
+#if 0
+int before_process_hook(void *hook_data, void *call_data);
+int after_process_hook(void *hook_data, void *call_data);
+#endif //0
+
+void draw_closure(gpointer key, gpointer value, gpointer user_data);
+
+int  before_chunk(void *hook_data, void *call_data);
+int  after_chunk(void *hook_data, void *call_data);
+int  before_request(void *hook_data, void *call_data);
+int  after_request(void *hook_data, void *call_data);
+
+
+
+gint update_time_window_hook(void *hook_data, void *call_data);
+gint update_current_time_hook(void *hook_data, void *call_data);
+gint traceset_notify(void *hook_data, void *call_data);
+gint redraw_notify(void *hook_data, void *call_data);
+gint continue_notify(void *hook_data, void *call_data);
+
+void legend_destructor(GtkWindow *legend);
+
+#endif // _EVENT_HOOKS_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/hGuiControlFlowInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/hGuiControlFlowInsert.xpm
new file mode 100644 (file)
index 0000000..db4b727
--- /dev/null
@@ -0,0 +1,28 @@
+/* XPM */
+static char * hGuiControlFlowInsert_xpm[] = {
+"22 22 3 1",
+"      c None",
+".     c #0DF904",
+"+     c #F90404",
+"                      ",
+"          .           ",
+"          ..          ",
+"          ...         ",
+"          ....        ",
+"          ...         ",
+"          ..          ",
+"          .           ",
+"                      ",
+"++++++++++............",
+"++++++++++............",
+"                      ",
+"          ++++++      ",
+"          ++++++      ",
+"          ++++++      ",
+"          ++++++      ",
+"          ++++++      ",
+"          ++++++      ",
+"                      ",
+"..........++++++++++++",
+"..........++++++++++++",
+"                      "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/hLegendInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/hLegendInsert.xpm
new file mode 100644 (file)
index 0000000..a6ff0f3
--- /dev/null
@@ -0,0 +1,45 @@
+/* XPM */
+static char * hLegendInsert_xpm[] = {
+"22 22 20 1",
+"      c None",
+".     c #0DF904",
+"+     c #000000",
+"@     c #000500",
+"#     c #000B00",
+"$     c #034001",
+"%     c #000200",
+"&     c #0CF403",
+"*     c #0BD603",
+"=     c #034901",
+"-     c #F90404",
+";     c #0AC503",
+">     c #000F00",
+",     c #034601",
+"'     c #0CF503",
+")     c #D60303",
+"!     c #001000",
+"~     c #044E01",
+"{     c #0CF203",
+"]     c #E40303",
+"                      ",
+"          .           ",
+"          ..          ",
+"        ++@#$         ",
+"       ++++++%        ",
+"       +  &*=++       ",
+"          .. ++       ",
+"          .  ++       ",
+"            ++        ",
+"----------;>+,'.......",
+"---------)!+~{........",
+"         +++          ",
+"         ++]----      ",
+"         ++-----      ",
+"         ++-----      ",
+"          ------      ",
+"         ++-----      ",
+"         ++-----      ",
+"                      ",
+"..........------------",
+"..........------------",
+"                      "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/module.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/module.c
new file mode 100644 (file)
index 0000000..14311ef
--- /dev/null
@@ -0,0 +1,133 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+
+/*! \defgroup guiEvents libguiControlFlow: The GUI ControlFlow display plugin */
+/*\@{*/
+
+/*! \file guiControlFlow.c
+ * \brief Graphical plugin for showing control flow of a trace.
+ *
+ * This plugin adds a Control Flow Viewer functionnality to Linux TraceToolkit
+ * GUI when this plugin is loaded. The init and destroy functions add the
+ * viewer's insertion menu item and toolbar icon by calling viewer.h's
+ * API functions. Then, when a viewer's object is created, the constructor
+ * creates ans register through API functions what is needed to interact
+ * with the TraceSet window.
+ *
+ * This plugin uses the gdk library to draw the events and gtk to interact
+ * with the user.
+ *
+ * Author : Mathieu Desnoyers, June 2003
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttvwindow/lttvwindow.h>
+
+#include "cfv.h"
+#include "eventhooks.h"
+
+#include "hGuiControlFlowInsert.xpm"
+#include "hLegendInsert.xpm"
+
+GQuark LTT_NAME_CPU;
+
+/** Array containing instanced objects. Used when module is unloaded */
+GSList *g_control_flow_data_list = NULL ;
+
+GSList *g_legend_list = NULL ;
+
+/*****************************************************************************
+ *                 Functions for module loading/unloading                    *
+ *****************************************************************************/
+/**
+ * plugin's init function
+ *
+ * This function initializes the Control Flow Viewer functionnality through the
+ * gtkTraceSet API.
+ */
+static void init() {
+
+  g_info("GUI ControlFlow Viewer init()");
+
+  /* Register the toolbar insert button and menu entry*/
+  lttvwindow_register_constructor("guicontrolflow",
+                                  "/",
+                                  "Insert Control Flow Viewer",
+                                  hGuiControlFlowInsert_xpm,
+                                  "Insert Control Flow Viewer",
+                                  h_guicontrolflow);
+  
+  lttvwindow_register_constructor("guicontrolflowlegend",
+                                  "/",
+                                  "Popup Control Flow Viewer Legend",
+                                  hLegendInsert_xpm,
+                                  "Popup Control Flow Viewer Legend",
+                                  h_legend);
+
+
+  LTT_NAME_CPU = g_quark_from_string("/cpu");
+}
+
+void destroy_walk(gpointer data, gpointer user_data)
+{
+  g_info("Walk destroy GUI Control Flow Viewer");
+  guicontrolflow_destructor_full((ControlFlowData*)data);
+}
+
+void destroy_legend_walk(gpointer data, gpointer user_data)
+{
+  g_info("Walk destroy GUI Control Flow Viewer");
+  legend_destructor((GtkWindow*)data);
+}
+
+
+
+/**
+ * plugin's destroy function
+ *
+ * This function releases the memory reserved by the module and unregisters
+ * everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+  g_info("GUI Control Flow Viewer destroy()");
+
+  g_slist_foreach(g_control_flow_data_list, destroy_walk, NULL );
+  
+  g_slist_free(g_control_flow_data_list);
+
+  g_slist_foreach(g_legend_list, destroy_legend_walk, NULL );
+  
+  g_slist_free(g_control_flow_data_list);
+  
+  /* Unregister the toolbar insert button and menu entry */
+  lttvwindow_unregister_constructor(h_guicontrolflow);
+  lttvwindow_unregister_constructor(h_legend);
+}
+
+
+LTTV_MODULE("guicontrolflow", "Control flow viewer", \
+    "Graphical module to view processes state and control flow", \
+    init, destroy, "lttvwindow")
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/processlist.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/processlist.c
new file mode 100644 (file)
index 0000000..ce4c092
--- /dev/null
@@ -0,0 +1,687 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "processlist.h"
+#include "drawing.h"
+#include "drawitem.h"
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+
+/* Preallocated Size of the index_to_pixmap array */
+#define ALLOCATE_PROCESSES 1000
+
+/*****************************************************************************
+ *                       Methods to synchronize process list                 *
+ *****************************************************************************/
+
+
+gint process_sort_func  ( GtkTreeModel *model,
+        GtkTreeIter *it_a,
+        GtkTreeIter *it_b,
+        gpointer user_data)
+{
+  gchar *a_name;
+  guint a_pid, a_ppid, a_cpu;
+  gulong a_birth_s, a_birth_ns;
+  gulong a_trace;
+
+  gchar *b_name;
+  guint b_pid, b_ppid, b_cpu;
+  gulong b_birth_s, b_birth_ns;
+  gulong b_trace;
+
+  gtk_tree_model_get(model,
+           it_a,
+           0, &a_name,
+           1, &a_pid,
+           2, &a_ppid,
+           3, &a_cpu,
+           4, &a_birth_s,
+           5, &a_birth_ns,
+           6, &a_trace,
+           -1);
+
+  gtk_tree_model_get(model,
+           it_b,
+           0, &b_name,
+           1, &b_pid,
+           2, &b_ppid,
+           3, &b_cpu,
+           4, &b_birth_s,
+           5, &b_birth_ns,
+           6, &b_trace,
+           -1);
+
+  
+  /* Order by PID */
+  if(a_pid == 0 &&  b_pid == 0) {
+    /* If 0, order by CPU */
+    if(a_cpu > b_cpu) return 1;
+    if(a_cpu < b_cpu) return -1;
+
+  } else { /* if not 0, order by pid */
+
+    if(a_pid > b_pid) return 1;
+    if(a_pid < b_pid) return -1;
+  }
+
+  /* Order by birth second */
+
+  if(a_birth_s > b_birth_s) return 1;
+  if(a_birth_s < b_birth_s) return -1;
+  
+
+  /* Order by birth nanosecond */
+  if(a_birth_ns > b_birth_ns) return 1;
+  if(a_birth_ns < b_birth_ns) return -1;
+  
+  /* Order by trace_num */
+  if(a_trace > b_trace) return 1;
+  if(a_trace < b_trace) return -1;
+
+  return 0;
+
+}
+
+static guint process_list_hash_fct(gconstpointer key)
+{
+  guint pid = ((const ProcessInfo*)key)->pid;
+  return ((pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ^ ((const ProcessInfo*)key)->cpu);
+}
+
+/* If hash is good, should be different */
+static gboolean process_list_equ_fct(gconstpointer a, gconstpointer b)
+{
+  const ProcessInfo *pa = (const ProcessInfo*)a;
+  const ProcessInfo *pb = (const ProcessInfo*)b;
+  
+  gboolean ret = TRUE;
+
+  if(likely(pa->pid != pb->pid))
+    ret = FALSE;
+  if(likely((pa->pid == 0 && (pa->cpu != pb->cpu))))
+    ret = FALSE;
+  if(unlikely(ltt_time_compare(pa->birth, pb->birth) != 0))
+    ret = FALSE;
+  if(unlikely(pa->trace_num != pb->trace_num))
+    ret = FALSE;
+
+  return ret;
+}
+
+void destroy_hash_key(gpointer key);
+
+void destroy_hash_data(gpointer data);
+
+
+static void update_index_to_pixmap_each(ProcessInfo *key,
+                                        HashedProcessData *value,
+                                        ProcessList *process_list)
+{
+  guint array_index = processlist_get_index_from_data(process_list, value);
+  
+  g_assert(array_index < process_list->index_to_pixmap->len);
+
+  GdkPixmap **pixmap = 
+    (GdkPixmap**)&g_ptr_array_index(process_list->index_to_pixmap, array_index);
+
+  *pixmap = value->pixmap;
+}
+
+
+void update_index_to_pixmap(ProcessList *process_list)
+{
+  g_ptr_array_set_size(process_list->index_to_pixmap,
+                       g_hash_table_size(process_list->process_hash));
+  g_hash_table_foreach(process_list->process_hash, 
+                       (GHFunc)update_index_to_pixmap_each,
+                       process_list);
+}
+
+
+static void update_pixmap_size_each(ProcessInfo *key,
+                                    HashedProcessData *value,
+                                    guint width)
+{
+  GdkPixmap *old_pixmap = value->pixmap;
+
+  value->pixmap = 
+        gdk_pixmap_new(old_pixmap,
+                       width,
+                       value->height,
+                       -1);
+
+  gdk_pixmap_unref(old_pixmap);
+}
+
+
+void update_pixmap_size(ProcessList *process_list, guint width)
+{
+  g_hash_table_foreach(process_list->process_hash, 
+                       (GHFunc)update_pixmap_size_each,
+                       (gpointer)width);
+}
+
+
+typedef struct _CopyPixmap {
+  GdkDrawable *dest;
+  GdkGC *gc;
+  GdkDrawable *src;
+  gint xsrc, ysrc, xdest, ydest, width, height;
+} CopyPixmap;
+
+static void copy_pixmap_region_each(ProcessInfo *key,
+                                    HashedProcessData *value,
+                                    CopyPixmap *cp)
+{
+  GdkPixmap *src = cp->src;
+  GdkPixmap *dest = cp->dest;
+  
+  if(dest == NULL)
+    dest = value->pixmap;
+  if(src == NULL)
+    src = value->pixmap;
+
+  gdk_draw_drawable (dest,
+      cp->gc,
+      src,
+      cp->xsrc, cp->ysrc,
+      cp->xdest, cp->ydest,
+      cp->width, cp->height);
+}
+
+
+
+
+void copy_pixmap_region(ProcessList *process_list, GdkDrawable *dest,
+    GdkGC *gc, GdkDrawable *src,
+    gint xsrc, gint ysrc,
+    gint xdest, gint ydest, gint width, gint height)
+{
+  CopyPixmap cp = { dest, gc, src, xsrc, ysrc, xdest, ydest, width, height };
+  
+  g_hash_table_foreach(process_list->process_hash, 
+                       (GHFunc)copy_pixmap_region_each,
+                       &cp);
+}
+
+
+
+typedef struct _RectanglePixmap {
+  gboolean filled;
+  gint x, y, width, height;
+  GdkGC *gc;
+} RectanglePixmap;
+
+static void rectangle_pixmap_each(ProcessInfo *key,
+                                  HashedProcessData *value,
+                                  RectanglePixmap *rp)
+{
+  if(rp->height == -1)
+    rp->height = value->height;
+      
+  gdk_draw_rectangle (value->pixmap,
+      rp->gc,
+      rp->filled,
+      rp->x, rp->y,
+      rp->width, rp->height);
+}
+
+
+
+
+void rectangle_pixmap(ProcessList *process_list, GdkGC *gc,
+    gboolean filled, gint x, gint y, gint width, gint height)
+{
+  RectanglePixmap rp = { filled, x, y, width, height, gc };
+  
+  g_hash_table_foreach(process_list->process_hash, 
+                       (GHFunc)rectangle_pixmap_each,
+                       &rp);
+}
+
+
+/* Renders each pixmaps into on big drawable */
+void copy_pixmap_to_screen(ProcessList *process_list,
+    GdkDrawable *dest,
+    GdkGC *gc,
+    gint x, gint y,
+    gint width, gint height)
+{
+  if(process_list->index_to_pixmap->len == 0) return;
+  guint cell_height = process_list->cell_height;
+
+  /* Get indexes */
+  gint begin = floor(y/(double)cell_height);
+  gint end = MIN(ceil((y+height)/(double)cell_height),
+                 process_list->index_to_pixmap->len);
+  gint i;
+
+  for(i=begin; i<end; i++) {
+    g_assert(i<process_list->index_to_pixmap->len);
+    /* Render the pixmap to the screen */
+    GdkPixmap *pixmap = 
+      //(GdkPixmap*)g_ptr_array_index(process_list->index_to_pixmap, i);
+      GDK_PIXMAP(g_ptr_array_index(process_list->index_to_pixmap, i));
+
+    gdk_draw_drawable (dest,
+        gc,
+        pixmap,
+        x, 0,
+        x, i*cell_height,
+        width, cell_height);
+
+  }
+  
+  
+}
+
+
+
+
+
+
+
+
+
+ProcessList *processlist_construct(void)
+{
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  
+  ProcessList* process_list = g_new(ProcessList,1);
+  
+  process_list->number_of_process = 0;
+
+  process_list->current_hash_data = NULL;
+
+  /* Create the Process list */
+  process_list->list_store = gtk_list_store_new (  N_COLUMNS,
+              G_TYPE_STRING,
+              G_TYPE_UINT,
+              G_TYPE_UINT,
+              G_TYPE_UINT,
+              G_TYPE_ULONG,
+              G_TYPE_ULONG,
+              G_TYPE_ULONG);
+
+
+  process_list->process_list_widget = 
+    gtk_tree_view_new_with_model
+    (GTK_TREE_MODEL (process_list->list_store));
+
+  g_object_unref (G_OBJECT (process_list->list_store));
+
+  gtk_tree_sortable_set_default_sort_func(
+      GTK_TREE_SORTABLE(process_list->list_store),
+      process_sort_func,
+      NULL,
+      NULL);
+
+  gtk_tree_sortable_set_sort_column_id(
+      GTK_TREE_SORTABLE(process_list->list_store),
+      GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+      GTK_SORT_ASCENDING);
+
+
+  process_list->process_hash = g_hash_table_new_full(
+      process_list_hash_fct, process_list_equ_fct,
+      destroy_hash_key, destroy_hash_data
+      );
+  
+  
+  gtk_tree_view_set_headers_visible(
+    GTK_TREE_VIEW(process_list->process_list_widget), TRUE);
+
+  /* Create a column, associating the "text" attribute of the
+   * cell_renderer to the first column of the model */
+  /* Columns alignment : 0.0 : Left    0.5 : Center   1.0 : Right */
+  renderer = gtk_cell_renderer_text_new ();
+  process_list->renderer = renderer;
+
+  gtk_cell_renderer_get_size(renderer,
+      GTK_WIDGET(process_list->process_list_widget),
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      &process_list->cell_height);
+  
+  guint ypad;
+  g_object_get(G_OBJECT(renderer), "ypad", &ypad, NULL);
+
+  process_list->cell_height += ypad;
+  
+  column = gtk_tree_view_column_new_with_attributes ( "Process",
+                renderer,
+                "text",
+                PROCESS_COLUMN,
+                NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+  
+  process_list->button = column->button;
+  
+  column = gtk_tree_view_column_new_with_attributes ( "PID",
+                renderer,
+                "text",
+                PID_COLUMN,
+                NULL);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+
+  column = gtk_tree_view_column_new_with_attributes ( "PPID",
+                renderer,
+                "text",
+                PPID_COLUMN,
+                NULL);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+  
+  column = gtk_tree_view_column_new_with_attributes ( "CPU",
+                renderer,
+                "text",
+                CPU_COLUMN,
+                NULL);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+
+  column = gtk_tree_view_column_new_with_attributes ( "Birth sec",
+                renderer,
+                "text",
+                BIRTH_S_COLUMN,
+                NULL);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+
+  //gtk_tree_view_column_set_visible(column, 0);
+  //
+  column = gtk_tree_view_column_new_with_attributes ( "Birth nsec",
+                renderer,
+                "text",
+                BIRTH_NS_COLUMN,
+                NULL);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+
+  column = gtk_tree_view_column_new_with_attributes ( "TRACE",
+                renderer,
+                "text",
+                TRACE_COLUMN,
+                NULL);
+  gtk_tree_view_append_column (
+    GTK_TREE_VIEW (process_list->process_list_widget), column);
+
+
+  //gtk_tree_view_column_set_visible(column, 0);
+  
+  g_object_set_data_full(
+      G_OBJECT(process_list->process_list_widget),
+      "process_list_Data",
+      process_list,
+      (GDestroyNotify)processlist_destroy);
+
+  process_list->index_to_pixmap = g_ptr_array_sized_new(ALLOCATE_PROCESSES);
+  
+  return process_list;
+}
+
+void processlist_destroy(ProcessList *process_list)
+{
+  g_debug("processlist_destroy %p", process_list);
+  g_hash_table_destroy(process_list->process_hash);
+  process_list->process_hash = NULL;
+  g_ptr_array_free(process_list->index_to_pixmap, TRUE);
+
+  g_free(process_list);
+  g_debug("processlist_destroy end");
+}
+
+static gboolean remove_hash_item(ProcessInfo *process_info,
+                                 HashedProcessData *hashed_process_data,
+                                 ProcessList *process_list)
+{
+  GtkTreeIter iter;
+
+  iter = hashed_process_data->y_iter;
+
+  gtk_list_store_remove (process_list->list_store, &iter);
+  gdk_pixmap_unref(hashed_process_data->pixmap);
+
+  if(likely(process_list->current_hash_data != NULL)) {
+    if(likely(hashed_process_data ==
+                process_list->current_hash_data[process_info->cpu]))
+      process_list->current_hash_data[process_info->cpu] = NULL;
+  }
+  return TRUE; /* remove the element from the hash table */
+}
+
+void processlist_clear(ProcessList *process_list)
+{
+  g_info("processlist_clear %p", process_list);
+
+  g_hash_table_foreach_remove(process_list->process_hash,
+                              (GHRFunc)remove_hash_item,
+                              (gpointer)process_list);
+  process_list->number_of_process = 0;
+  update_index_to_pixmap(process_list);
+}
+
+
+GtkWidget *processlist_get_widget(ProcessList *process_list)
+{
+  return process_list->process_list_widget;
+}
+
+
+void destroy_hash_key(gpointer key)
+{
+  g_free(key);
+}
+
+void destroy_hash_data(gpointer data)
+{
+  g_free(data);
+}
+
+
+void processlist_set_name(ProcessList *process_list,
+    GQuark name,
+    HashedProcessData *hashed_process_data)
+{
+  gtk_list_store_set (  process_list->list_store, &hashed_process_data->y_iter,
+        PROCESS_COLUMN, g_quark_to_string(name),
+        -1);
+}
+
+int processlist_add(  ProcessList *process_list,
+      Drawing_t *drawing,
+      guint pid,
+      guint cpu,
+      guint ppid,
+      LttTime *birth,
+      guint trace_num,
+      GQuark name,
+      guint *height,
+      ProcessInfo **pm_process_info,
+      HashedProcessData **pm_hashed_process_data)
+{
+  ProcessInfo *Process_Info = g_new(ProcessInfo, 1);
+  HashedProcessData *hashed_process_data = g_new(HashedProcessData, 1);
+  *pm_hashed_process_data = hashed_process_data;
+  *pm_process_info = Process_Info;
+  
+  Process_Info->pid = pid;
+  if(pid == 0)
+    Process_Info->cpu = cpu;
+  else
+    Process_Info->cpu = 0;
+  Process_Info->ppid = ppid;
+  Process_Info->birth = *birth;
+  Process_Info->trace_num = trace_num;
+
+  /* When we create it from before state update, we are sure that the
+   * last event occured before the beginning of the global area.
+   *
+   * If it is created after state update, this value (0) will be
+   * overriden by the new state before anything is drawn.
+   */
+  hashed_process_data->x.over = 0;
+  hashed_process_data->x.over_used = FALSE;
+  hashed_process_data->x.over_marked = FALSE;
+  hashed_process_data->x.middle = 0;
+  hashed_process_data->x.middle_used = FALSE;
+  hashed_process_data->x.middle_marked = FALSE;
+  hashed_process_data->x.under = 0;
+  hashed_process_data->x.under_used = FALSE;
+  hashed_process_data->x.under_marked = FALSE;
+  hashed_process_data->next_good_time = ltt_time_zero;
+  /* Add a new row to the model */
+  gtk_list_store_append ( process_list->list_store,
+                          &hashed_process_data->y_iter);
+
+  gtk_list_store_set (  process_list->list_store, &hashed_process_data->y_iter,
+        PROCESS_COLUMN, g_quark_to_string(name),
+        PID_COLUMN, pid,
+        PPID_COLUMN, ppid,
+        CPU_COLUMN, cpu,
+        BIRTH_S_COLUMN, birth->tv_sec,
+        BIRTH_NS_COLUMN, birth->tv_nsec,
+        TRACE_COLUMN, trace_num,
+        -1);
+  //gtk_tree_view_set_model(GTK_TREE_VIEW(process_list->process_list_widget),
+  //                        GTK_TREE_MODEL(process_list->list_store));
+  //gtk_container_resize_children(GTK_CONTAINER(process_list->process_list_widget));
+  
+  g_hash_table_insert(process_list->process_hash,
+        (gpointer)Process_Info,
+        (gpointer)hashed_process_data);
+  
+  process_list->number_of_process++;
+
+  hashed_process_data->height = process_list->cell_height;
+
+  g_assert(hashed_process_data->height != 0);
+
+  *height = hashed_process_data->height * process_list->number_of_process;
+
+  hashed_process_data->pixmap = 
+        gdk_pixmap_new(drawing->drawing_area->window,
+                       drawing->alloc_width,
+                       hashed_process_data->height,
+                       -1);
+  
+  // Clear the image
+  gdk_draw_rectangle (hashed_process_data->pixmap,
+        drawing->drawing_area->style->black_gc,
+        TRUE,
+        0, 0,
+        drawing->alloc_width,
+        hashed_process_data->height);
+
+  update_index_to_pixmap(process_list);
+
+
+  return 0;
+}
+
+int processlist_remove( ProcessList *process_list,
+      guint pid,
+      guint cpu,
+      LttTime *birth,
+      guint trace_num)
+{
+  ProcessInfo process_info;
+  HashedProcessData *hashed_process_data;
+  GtkTreeIter iter;
+  
+  process_info.pid = pid;
+  if(pid == 0)
+    process_info.cpu = cpu;
+  else
+    process_info.cpu = 0;
+  process_info.birth = *birth;
+  process_info.trace_num = trace_num;
+
+
+  hashed_process_data = 
+    (HashedProcessData*)g_hash_table_lookup(
+          process_list->process_hash,
+          &process_info);
+  if(likely(hashed_process_data != NULL))
+  {
+    iter = hashed_process_data->y_iter;
+
+    gtk_list_store_remove (process_list->list_store, &iter);
+    
+    g_hash_table_remove(process_list->process_hash,
+        &process_info);
+
+    if(likely(process_list->current_hash_data != NULL)) {
+      if(likely(hashed_process_data == process_list->current_hash_data[cpu])) {
+        process_list->current_hash_data[cpu] = NULL;
+      }
+    }
+    
+    gdk_pixmap_unref(hashed_process_data->pixmap);
+    
+    update_index_to_pixmap(process_list);
+
+    process_list->number_of_process--;
+
+    return 0; 
+  } else {
+    return 1;
+  }
+}
+
+
+#if 0
+static inline guint get_cpu_number_from_name(GQuark name)
+{
+  const gchar *string;
+  char *begin;
+  guint cpu;
+
+  string = g_quark_to_string(name);
+
+  begin = strrchr(string, '/');
+  begin++;
+
+  g_assert(begin != '\0');
+
+  cpu = strtoul(begin, NULL, 10);
+
+  return cpu;
+}
+#endif //0
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/processlist.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/processlist.h
new file mode 100644 (file)
index 0000000..c832246
--- /dev/null
@@ -0,0 +1,242 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+
+#ifndef _PROCESS_LIST_H
+#define _PROCESS_LIST_H
+
+#include <gtk/gtk.h>
+#include <lttv/state.h>
+#include <ltt/ltt.h>
+
+#include "drawitem.h"
+
+/* The process list
+ *
+ * Tasks :
+ * Create a process list
+ * contains the data for the process list
+ * tells the height of the process list widget
+ * provides methods to add/remove process from the list
+ *  note : the sync with drawing is left to the caller.
+ * provides helper function to convert a process unique identifier to
+ *  pixels (in height).
+ *
+ */
+
+
+/* Enumeration of the columns */
+enum
+{
+  PROCESS_COLUMN,
+  PID_COLUMN,
+  PPID_COLUMN,
+  CPU_COLUMN,
+  BIRTH_S_COLUMN,
+  BIRTH_NS_COLUMN,
+  TRACE_COLUMN,
+  N_COLUMNS
+};
+
+
+typedef struct _ProcessInfo {
+  
+  guint pid;
+  guint cpu;
+  guint ppid;
+  LttTime birth;
+  guint trace_num;
+
+ // gint height_cache;
+
+} ProcessInfo;
+
+typedef struct _HashedProcessData {
+  GdkPixmap *pixmap;  // Pixmap slice containing drawing buffer for the PID
+  gint height; // height of the pixmap
+  GtkTreeIter y_iter; // Access quickly to y pos.
+ // DrawContext *draw_context;
+  /* Information on current drawing */
+  struct {
+    guint over;
+    gboolean over_used;    /* inform the user that information is incomplete */
+    gboolean over_marked;  /* inform the user that information is incomplete */
+    guint middle;
+    gboolean middle_used;  /* inform the user that information is incomplete */
+    gboolean middle_marked;/* inform the user that information is incomplete */
+    guint under;
+    gboolean under_used;   /* inform the user that information is incomplete */
+    gboolean under_marked; /* inform the user that information is incomplete */
+  } x; /* last x position saved by after state update */
+
+  LttTime next_good_time; /* precalculate the next time where the next
+                             pixel is.*/
+
+} HashedProcessData;
+  
+struct _ProcessList {
+  
+  GtkWidget *process_list_widget;
+  GtkListStore *list_store;
+  GtkWidget *button; /* one button of the tree view */
+  GtkCellRenderer *renderer;
+
+  /* A hash table by PID to speed up process position find in the list */
+  GHashTable *process_hash;
+  
+  guint number_of_process;
+  gint cell_height;
+
+  /* Current process, one per cpu */
+  HashedProcessData **current_hash_data;
+
+  /* Array containing index -> pixmap correspondance. Must be updated
+   * every time the process list is reordered, process added or removed */
+  GPtrArray * index_to_pixmap;
+
+};
+
+
+typedef struct _ProcessList ProcessList;
+
+
+#ifndef TYPE_DRAWING_T_DEFINED
+#define TYPE_DRAWING_T_DEFINED
+typedef struct _Drawing_t Drawing_t;
+#endif //TYPE_DRAWING_T_DEFINED
+
+ProcessList *processlist_construct(void);
+void processlist_destroy(ProcessList *process_list);
+GtkWidget *processlist_get_widget(ProcessList *process_list);
+
+void processlist_clear(ProcessList *process_list);
+
+// out : success (0) and height
+/* CPU num is only used for PID 0 */
+int processlist_add(ProcessList *process_list, Drawing_t * drawing, 
+    guint pid, guint cpu, guint ppid,
+    LttTime *birth, guint trace_num, GQuark name, guint *height,
+    ProcessInfo **process_info,
+    HashedProcessData **hashed_process_data);
+// out : success (0) and height
+int processlist_remove(ProcessList *process_list, guint pid, guint cpu, 
+    LttTime *birth, guint trace_num);
+
+/* Set the name of a process */
+void processlist_set_name(ProcessList *process_list,
+    GQuark name,
+    HashedProcessData *hashed_process_data);
+
+
+/* Synchronize the list at the left and the drawing */
+void update_index_to_pixmap(ProcessList *process_list);
+
+/* Update the width of each pixmap buffer for each process */
+void update_pixmap_size(ProcessList *process_list, guint width);
+
+
+/* Put src and/or dest to NULL to copy from/to the each PID specific pixmap */
+void copy_pixmap_region(ProcessList *process_list, GdkDrawable *dest,
+    GdkGC *gc, GdkDrawable *src,
+    gint xsrc, gint ysrc,
+    gint xdest, gint ydest, gint width, gint height);
+
+/* If height is -1, the height of each pixmap is used */
+void rectangle_pixmap(ProcessList *process_list, GdkGC *gc,
+    gboolean filled, gint x, gint y, gint width, gint height);
+
+/* Renders each pixmaps into on big drawable */
+void copy_pixmap_to_screen(ProcessList *process_list,
+    GdkDrawable *dest,
+    GdkGC *gc,
+    gint x, gint y,
+    gint width, gint height);
+
+
+
+
+static inline guint processlist_get_height(ProcessList *process_list)
+{
+  return process_list->cell_height * process_list->number_of_process ;
+}
+
+
+static inline HashedProcessData *processlist_get_process_data( 
+          ProcessList *process_list,
+          guint pid, guint cpu, LttTime *birth, guint trace_num)
+{
+  ProcessInfo process_info;
+
+  process_info.pid = pid;
+  if(pid == 0)
+    process_info.cpu = cpu;
+  else
+    process_info.cpu = ANY_CPU;
+  process_info.birth = *birth;
+  process_info.trace_num = trace_num;
+
+  return  (HashedProcessData*)g_hash_table_lookup(
+                process_list->process_hash,
+                &process_info);
+}
+
+
+static inline gint processlist_get_pixels_from_data(  ProcessList *process_list,
+          HashedProcessData *hashed_process_data,
+          guint *y,
+          guint *height)
+{
+  gint *path_indices;
+  GtkTreePath *tree_path;
+
+  tree_path = gtk_tree_model_get_path((GtkTreeModel*)process_list->list_store,
+                    &hashed_process_data->y_iter);
+  path_indices =  gtk_tree_path_get_indices (tree_path);
+
+  *height = get_cell_height(process_list,
+      (GtkTreeView*)process_list->process_list_widget);
+  *y = *height * path_indices[0];
+  gtk_tree_path_free(tree_path);
+
+  return 0; 
+
+}
+
+static inline guint processlist_get_index_from_data(ProcessList *process_list,
+          HashedProcessData *hashed_process_data)
+{
+  gint *path_indices;
+  GtkTreePath *tree_path;
+  guint ret;
+
+  tree_path = gtk_tree_model_get_path((GtkTreeModel*)process_list->list_store,
+                    &hashed_process_data->y_iter);
+  path_indices =  gtk_tree_path_get_indices (tree_path);
+
+  ret = path_indices[0];
+
+  gtk_tree_path_free(tree_path);
+
+  return ret;
+}
+
+
+
+#endif // _PROCESS_LIST_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/test.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/controlflow/test.c
new file mode 100644 (file)
index 0000000..8a71a52
--- /dev/null
@@ -0,0 +1,578 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+static void destroy_cb( GtkWidget *widget,
+                                       gpointer   data )
+{ 
+           gtk_main_quit ();
+}
+
+
+
+int main(int argc, char **argv)
+{
+       GtkWidget *Window;
+       GtkWidget *CF_Viewer;
+       GtkWidget *VBox_V;
+       GtkWidget *HScroll_VC;
+       ControlFlowData *control_flow_data;
+       guint ev_sel = 444 ;
+       /* Horizontal scrollbar and it's adjustment */
+       GtkWidget *VScroll_VC;
+  GtkAdjustment *v_adjust ;
+       
+       /* Initialize i18n support */
+  gtk_set_locale ();
+
+  /* Initialize the widget set */
+  gtk_init (&argc, &argv);
+
+       init();
+
+  Window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+       gtk_window_set_title (GTK_WINDOW (Window), ("Test Window"));
+       
+       g_signal_connect (G_OBJECT (Window), "destroy",
+                       G_CALLBACK (destroy_cb), NULL);
+
+
+  VBox_V = gtk_vbox_new(0, 0);
+       gtk_container_add (GTK_CONTAINER (Window), VBox_V);
+
+  //ListViewer = hGuiEvents(Window);
+  //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, TRUE, TRUE, 0);
+
+  //ListViewer = hGuiEvents(Window);
+  //gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, FALSE, TRUE, 0);
+       
+       control_flow_data = guicontrolflow();
+       CF_Viewer = control_flow_data->scrolled_window;
+  gtk_box_pack_start(GTK_BOX(VBox_V), CF_Viewer, TRUE, TRUE, 0);
+
+  /* Create horizontal scrollbar and pack it */
+  HScroll_VC = gtk_hscrollbar_new(NULL);
+  gtk_box_pack_start(GTK_BOX(VBox_V), HScroll_VC, FALSE, TRUE, 0);
+       
+       
+  gtk_widget_show (HScroll_VC);
+  gtk_widget_show (VBox_V);
+       gtk_widget_show (Window);
+
+       //Event_Selected_Hook(control_flow_data, &ev_sel);
+       
+       gtk_main ();
+
+       g_critical("main loop finished");
+  
+       //h_guievents_destructor(ListViewer);
+
+       //g_critical("GuiEvents Destructor finished");
+       destroy();
+       
+       return 0;
+}
+
+
+
+void add_test_process(ControlFlowData *control_flow_data)
+{
+       GtkTreeIter iter;
+       int i;
+       gchar *process[] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
+
+       for(i=0; i<control_flow_data->number_of_process; i++)
+       {
+         /* Add a new row to the model */
+               gtk_list_store_append (control_flow_data->list_store, &iter);
+               gtk_list_store_set (    control_flow_data->list_store, &iter,
+                                       PROCESS_COLUMN, process[i],
+                                       -1);
+       }
+                                                       
+}
+       
+
+
+
+
+
+void test_draw(ControlFlowData *control_flow_data)
+{
+       /* Draw event states using available height, Number of process, cell height
+        * (don't forget to remove two pixels at beginning and end).
+        * For horizontal : use width, Time_Begin, Time_End.
+        * This function calls the reading library to get the draw_hook called 
+        * for the desired period of time. */
+       
+       drawingAreaInfo *drawing_Area_Info = &control_flow_data->drawing_Area_Info;
+
+       
+}
+
+#ifdef DEBUG
+void test_draw() {
+       gint cell_height = get_cell_height(GTK_TREE_VIEW(control_flow_data->process_list_widget));
+       GdkGC *GC = gdk_gc_new(widget->window);
+       GdkColor color = CF_Colors[GREEN];
+       
+       gdk_color_alloc (gdk_colormap_get_system () , &color);
+       
+       g_critical("expose");
+
+       /* When redrawing, use widget->allocation.width to get the width of
+        * drawable area. */
+       control_flow_data->drawing_Area_Info.width = widget->allocation.width;
+       
+       test_draw(control_flow_data);
+       
+       gdk_gc_copy(GC,widget->style->black_gc);
+       gdk_gc_set_foreground(GC,&color);
+       
+       //gdk_draw_arc (widget->window,
+  //              widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+  //              TRUE,
+  //              //0, 0, widget->allocation.width, widget->allocation.height,
+  //              0, 0, widget->allocation.width,
+       //                                                      control_flow_data->drawing_Area_Info.height,
+  //              0, 64 * 360);
+
+       
+       //drawing_Area_Init(control_flow_data);
+       
+       // 2 pixels for the box around the drawing area, 1 pixel for off-by-one
+       // (starting from 0)
+       //gdk_gc_copy (&GC, widget->style->fg_gc[GTK_WIDGET_STATE (widget)]);
+
+       gdk_gc_set_line_attributes(GC,12, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
+       
+       gdk_draw_line (widget->window,
+                 GC,
+                                                                0, (cell_height-1)/2,
+                                                                widget->allocation.width, (cell_height-1)/2);
+
+       color = CF_Colors[BLUE];
+       
+       gdk_color_alloc (gdk_colormap_get_system () , &color);
+       
+       gdk_gc_set_foreground(GC,&color);
+
+
+               gdk_gc_set_line_attributes(GC,3, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
+       
+       gdk_draw_line (widget->window,
+                 GC,
+                                                                0, (cell_height-1)/2,
+                                                                widget->allocation.width,(cell_height-1)/2);
+       
+
+
+
+
+
+       g_object_unref(GC);
+       
+       //gdk_colormap_alloc_colors(gdk_colormap_get_system(), TRUE, 
+               
+       //gdk_gc_set_line_attributes(GC,5, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
+       //gdk_gc_set_foreground(GC, 
+
+       //gdk_draw_line (widget->window,
+  //               GC,
+       //                                                       0, (2*cell_height)-2-1,
+       //                                                       50, (2*cell_height)-2-1);
+
+}
+#endif //DEBUG
+
+
+/* Event_Hook.c tests */
+
+void test_draw_item(Drawing_t *drawing,
+                       GdkPixmap *pixmap) 
+{
+       PropertiesIcon properties_icon;
+       DrawContext draw_context;
+       
+       DrawInfo current, previous;
+       ItemInfo over, middle, under, modify_over, modify_middle, modify_under;
+
+       int i=0,j=0;
+       
+       //for(i=0; i<1024;i=i+15)
+       {
+       //      for(j=0;j<768;j=j+15)
+               {
+                       over.x = i;
+                       over.y = j;
+
+                       current.modify_over = &over;
+       
+                       draw_context.drawable = pixmap;
+                       draw_context.gc = drawing->drawing_area->style->black_gc;
+
+                       draw_context.current = &current;
+                       draw_context.previous = NULL;
+       
+                       properties_icon.icon_name = g_new(char, MAX_PATH_LEN);
+                       strncpy(properties_icon.icon_name, 
+                               "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/mini-display.xpm",
+                               MAX_PATH_LEN);
+                       properties_icon.width = -1;
+                       properties_icon.height = -1;
+                       properties_icon.position = OVER;
+                       draw_icon(&properties_icon, &draw_context);
+                       g_free(properties_icon.icon_name);
+               }
+       }
+
+}
+
+#ifdef NOTUSE
+/* NOTE : no drawing data should be sent there, since the drawing widget
+ * has not been initialized */
+void send_test_drawing(ProcessList *process_list,
+                       Drawing_t *drawing,
+                       GdkPixmap *pixmap,
+                       gint x, gint y, // y not used here?
+                 gint width,
+                       gint height) // height won't be used here ?
+{
+       int i,j;
+       ProcessInfo Process_Info = {10000, 12000, 55600};
+       //ProcessInfo Process_Info = {156, 14000, 55500};
+       GtkTreeRowReference *row_ref;
+       PangoContext *context;
+       PangoLayout *layout;
+       PangoFontDescription *FontDesc;// = pango_font_description_new();
+       gint Font_Size;
+
+       //icon
+       //GdkBitmap *mask = g_new(GdkBitmap, 1);
+       //GdkPixmap *icon_pixmap = g_new(GdkPixmap, 1);
+       GdkGC * gc;
+       // rectangle
+       GdkColor color = { 0, 0xffff, 0x0000, 0x0000 };
+       
+       gc = gdk_gc_new(pixmap);
+       /* Sent text data */
+       layout = gtk_widget_create_pango_layout(drawing->drawing_area,
+                       NULL);
+       context = pango_layout_get_context(layout);
+       FontDesc = pango_context_get_font_description(context);
+       Font_Size = pango_font_description_get_size(FontDesc);
+       pango_font_description_set_size(FontDesc, Font_Size-3*PANGO_SCALE);
+       
+       
+
+
+       LttTime birth;
+       birth.tv_sec = 12000;
+       birth.tv_nsec = 55500;
+       g_info("we have : x : %u, y : %u, width : %u, height : %u", x, y, width, height);
+       processlist_get_process_pixels(process_list,
+                                       1,
+                                       &birth,
+                                       &y,
+                                       &height);
+       
+       g_info("we draw : x : %u, y : %u, width : %u, height : %u", x, y, width, height);
+       drawing_draw_line(
+               drawing, pixmap, x,
+               y+(height/2), x + width, y+(height/2),
+               drawing->drawing_area->style->black_gc);
+
+       pango_layout_set_text(layout, "Test", -1);
+       gdk_draw_layout(pixmap, drawing->drawing_area->style->black_gc,
+                       0, y+height, layout);
+
+       birth.tv_sec = 14000;
+       birth.tv_nsec = 55500;
+
+       processlist_get_process_pixels(process_list,
+                                       156,
+                                       &birth,
+                                       &y,
+                                       &height);
+       
+
+       drawing_draw_line(
+               drawing, pixmap, x,
+               y+(height/2), x + width, y+(height/2),
+               drawing->drawing_area->style->black_gc);
+
+       g_info("y : %u, height : %u", y, height);
+
+       
+
+       birth.tv_sec = 12000;
+       birth.tv_nsec = 55700;
+
+       processlist_get_process_pixels(process_list,
+                                       10,
+                                       &birth,
+                                       &y,
+                                       &height);
+
+       /* Draw rectangle (background color) */
+       gdk_gc_copy(gc, drawing->drawing_area->style->black_gc);
+       gdk_gc_set_rgb_fg_color(gc, &color);
+       gdk_draw_rectangle(pixmap, gc,
+                                       TRUE,
+                                       x, y, width, height);
+
+       drawing_draw_line(
+               drawing, pixmap, x,
+               y+(height/2), x + width, y+(height/2),
+               drawing->drawing_area->style->black_gc);
+
+       
+       /* Draw arc */
+       gdk_draw_arc(pixmap, drawing->drawing_area->style->black_gc,
+                                                       TRUE, 100, y, height/2, height/2, 0, 360*64);
+
+       g_info("y : %u, height : %u", y, height);
+
+       for(i=0; i<10; i++)
+       {
+               birth.tv_sec = i*12000;
+               birth.tv_nsec = i*55700;
+
+               processlist_get_process_pixels(process_list,
+                                               i,
+                                               &birth,
+                                               &y,
+                                               &height);
+               
+
+               drawing_draw_line(
+                       drawing, pixmap, x,
+                       y+(height/2), x + width, y+(height/2),
+                       drawing->drawing_area->style->black_gc);
+
+               g_critical("y : %u, height : %u", y, height);
+
+       }
+
+       birth.tv_sec = 12000;
+       birth.tv_nsec = 55600;
+
+       processlist_get_process_pixels(process_list,
+                                       10,
+                                       &birth,
+                                       &y,
+                                       &height);
+       
+
+       drawing_draw_line(
+               drawing, pixmap, x,
+               y+(height/2), x + width, y+(height/2),
+               drawing->drawing_area->style->black_gc);
+
+       g_info("y : %u, height : %u", y, height);
+       
+
+       /* IMPORTANT : This action uses the cpu heavily! */
+       //icon_pixmap = gdk_pixmap_create_from_xpm(pixmap, &mask, NULL,
+//                             "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/move_message.xpm");
+       //                              "/home/compudj/local/share/LinuxTraceToolkit/pixmaps/mini-display.xpm");
+
+       //              gdk_gc_set_clip_mask(drawing->drawing_area->style->black_gc, mask);
+
+//     for(i=x;i<x+width;i=i+15)
+//     {
+//             for(j=0;j<height*20;j=j+15)
+//             {
+                       
+                       /* Draw icon */
+                       //gdk_gc_copy(gc, drawing->drawing_area->style->black_gc);
+//                     gdk_gc_set_clip_origin(drawing->drawing_area->style->black_gc, i, j);
+//                     gdk_draw_drawable(pixmap, 
+//                                     drawing->drawing_area->style->black_gc,
+//                                     icon_pixmap,
+//                                     0, 0, i, j, -1, -1);
+
+//             }
+//     }
+
+       test_draw_item(drawing,pixmap);
+       
+       //gdk_gc_set_clip_origin(drawing->drawing_area->style->black_gc, 0, 0);
+       //gdk_gc_set_clip_mask(drawing->drawing_area->style->black_gc, NULL);
+
+       //g_free(icon_pixmap);
+       //g_free(mask);
+
+
+
+
+
+
+       pango_font_description_set_size(FontDesc, Font_Size);
+       g_object_unref(layout);
+       g_free(gc);
+}
+
+void send_test_process(ProcessList *process_list, Drawing_t *drawing)
+{
+       guint height, y;
+       int i;
+       ProcessInfo Process_Info = {10000, 12000, 55600};
+       //ProcessInfo Process_Info = {156, 14000, 55500};
+       GtkTreeRowReference *row_ref;
+
+       LttTime birth;
+
+       if(process_list->Test_Process_Sent) return;
+
+       birth.tv_sec = 12000;
+       birth.tv_nsec = 55500;
+
+       processlist_add(process_list,
+                       1,
+                       &birth,
+                       &y);
+       processlist_get_process_pixels(process_list,
+                                       1,
+                                       &birth,
+                                       &y,
+                                       &height);
+       drawing_insert_square( drawing, y, height);
+       
+       //g_critical("y : %u, height : %u", y, height);
+       
+       birth.tv_sec = 14000;
+       birth.tv_nsec = 55500;
+
+       processlist_add(process_list,
+                       156,
+                       &birth,
+                       &y);
+       processlist_get_process_pixels(process_list,
+                                       156,
+                                       &birth,
+                                       &y,
+                                       &height);
+       drawing_insert_square( drawing, y, height);
+       
+       //g_critical("y : %u, height : %u", y, height);
+       
+       birth.tv_sec = 12000;
+       birth.tv_nsec = 55700;
+
+       processlist_add(process_list,
+                       10,
+                       &birth,
+                       &height);
+       processlist_get_process_pixels(process_list,
+                                       10,
+                                       &birth,
+                                       &y,
+                                       &height);
+       drawing_insert_square( drawing, y, height);
+       
+       //g_critical("y : %u, height : %u", y, height);
+       
+       //drawing_insert_square( drawing, height, 5);
+
+       for(i=0; i<10; i++)
+       {
+               birth.tv_sec = i*12000;
+               birth.tv_nsec = i*55700;
+
+               processlist_add(process_list,
+                               i,
+                               &birth,
+                               &height);
+               processlist_get_process_pixels(process_list,
+                                               i,
+                                               &birth,
+                                               &y,
+                                               &height);
+               drawing_insert_square( drawing, y, height);
+       
+       //      g_critical("y : %u, height : %u", y, height);
+       
+       }
+       //g_critical("height : %u", height);
+
+       birth.tv_sec = 12000;
+       birth.tv_nsec = 55600;
+
+       processlist_add(process_list,
+                       10,
+                       &birth,
+                       &y);
+       processlist_get_process_pixels(process_list,
+                                       10,
+                                       &birth,
+                                       &y,
+                                       &height);
+       drawing_insert_square( drawing, y, height);
+       
+       //g_critical("y : %u, height : %u", y, height);
+       
+       processlist_add(process_list,
+                       10000,
+                       &birth,
+                       &height);
+       processlist_get_process_pixels(process_list,
+                                       10000,
+                                       &birth,
+                                       &y,
+                                       &height);
+       drawing_insert_square( drawing, y, height);
+       
+       //g_critical("y : %u, height : %u", y, height);
+       
+       //drawing_insert_square( drawing, height, 5);
+       //g_critical("height : %u", height);
+
+
+       processlist_get_process_pixels(process_list,
+                               10000,
+                               &birth,
+                               &y, &height);
+       processlist_remove(     process_list,
+                               10000,
+                               &birth);
+
+       drawing_remove_square( drawing, y, height);
+       
+       if(row_ref = 
+               (GtkTreeRowReference*)g_hash_table_lookup(
+                                       process_list->process_hash,
+                                       &Process_Info))
+       {
+               g_critical("key found");
+               g_critical("position in the list : %s",
+                       gtk_tree_path_to_string (
+                       gtk_tree_row_reference_get_path(
+                               (GtkTreeRowReference*)row_ref)
+                       ));
+               
+       }
+
+       process_list->Test_Process_Sent = TRUE;
+
+}
+#endif//NOTUSE
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/Makefile.am
new file mode 100644 (file)
index 0000000..9c08198
--- /dev/null
@@ -0,0 +1,38 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 Mathieu Desnoyers
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+# MA 02111-1307, USA.
+
+
+
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libguievents.la
+libguievents_la_LDFLAGS = -module
+libguievents_la_SOURCES = events.c
+
+EXTRA_DIST = \
+               hGuiEventsInsert.xpm
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/events.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/events.c
new file mode 100644 (file)
index 0000000..53684d2
--- /dev/null
@@ -0,0 +1,1739 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers and XangXiu Yang
+ *               2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+//*! \defgroup GuiEvents libGuiEvents: The GUI Events display plugin */
+/*\@{*/
+
+/*! \file GuiEvents.c
+ * \brief Graphical plugin for showing events.
+ *
+ * This plugin lists all the events contained in the current time interval
+ * in a list.
+ * 
+ * This plugin adds a Events Viewer functionnality to Linux TraceToolkit
+ * GUI when this plugin is loaded. The init and destroy functions add the
+ * viewer's insertion menu item and toolbar icon by calling viewer.h's
+ * API functions. Then, when a viewer's object is created, the constructor
+ * creates ans register through API functions what is needed to interact
+ * with the lttvwindow.
+ *
+ * Authors : Mathieu Desnoyers and XangXiu Yang, June to December 2003
+ *           Inspired from original LTT, made by Karim Yaghmour
+ *
+ *           Mostly rewritten by Mathieu Desnoyers, August 2005.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <string.h>
+
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/filter.h>
+#include <lttv/print.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+
+#include "hGuiEventsInsert.xpm"
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+
+#ifndef g_debug
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+#endif
+
+#define abs(a) (((a)<0)?(-a):(a))
+
+
+/** Array containing instanced objects. Used when module is unloaded */
+static GSList *g_event_viewer_data_list = NULL ;
+
+typedef enum _ScrollDirection{
+  SCROLL_STEP_UP,
+  SCROLL_STEP_DOWN,
+  SCROLL_PAGE_UP,
+  SCROLL_PAGE_DOWN,
+  SCROLL_JUMP,
+  SCROLL_NONE
+} ScrollDirection;
+
+typedef struct _EventViewerData {
+
+  Tab * tab;
+  LttvHooks  * event_hooks;
+
+  /* previous value is used to determine if it is a page up/down or
+   * step up/down, in which case we move of a certain amount of events (one or
+   * the number of events shown on the screen) instead of changing begin time.
+   */
+  double       previous_value;
+
+  //scroll window containing Tree View
+  GtkWidget * scroll_win;
+
+  /* Model containing list data */
+  GtkListStore *store_m;
+
+  GPtrArray *pos; /* Array of LttvTracesetContextPosition * */
+  GtkWidget *top_widget;
+  GtkWidget *hbox_v;
+  /* Widget to display the data in a columned list */
+  GtkWidget *tree_v;
+  GtkAdjustment *vtree_adjust_c ;
+  GtkWidget *button; /* a button of the header, used to get the header_height */
+  gint header_height;
+  
+  /* Vertical scrollbar and its adjustment */
+  GtkWidget *vscroll_vc;
+  GtkAdjustment *vadjust_c;
+  
+  /* Selection handler */
+  GtkTreeSelection *select_c;
+  
+  gint num_visible_events;
+  
+  LttvTracesetContextPosition *currently_selected_position;
+  gboolean update_cursor; /* Speed optimisation : do not update cursor when 
+                             unnecessary */
+  gboolean report_position; /* do not report position when in current_time
+                               update */
+
+  LttvTracesetContextPosition *first_event;  /* Time of the first event shown */
+  LttvTracesetContextPosition *last_event;  /* Time of the first event shown */
+
+  LttvTracesetContextPosition *current_time_get_first; 
+
+  LttvFilter *main_win_filter;
+
+  gint background_info_waiting;
+
+  guint32 last_tree_update_time; /* To filter out repeat keys */
+
+} EventViewerData ;
+
+/** hook functions for update time interval, current time ... */
+gboolean update_current_time(void * hook_data, void * call_data);
+gboolean update_current_position(void * hook_data, void * call_data);
+//gboolean show_event_detail(void * hook_data, void * call_data);
+gboolean traceset_changed(void * hook_data, void * call_data);
+gboolean filter_changed(void * hook_data, void * call_data);
+
+static void request_background_data(EventViewerData *event_viewer_data);
+
+//! Event Viewer's constructor hook
+GtkWidget *h_gui_events(Tab *tab);
+//! Event Viewer's constructor
+EventViewerData *gui_events(Tab *tab);
+//! Event Viewer's destructor
+void gui_events_destructor(EventViewerData *event_viewer_data);
+void gui_events_free(EventViewerData *event_viewer_data);
+
+static gboolean
+header_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data);
+
+void tree_v_set_cursor(EventViewerData *event_viewer_data);
+void tree_v_get_cursor(EventViewerData *event_viewer_data);
+
+/* Prototype for selection handler callback */
+static void tree_selection_changed_cb (GtkTreeSelection *selection,
+    gpointer data);
+static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data);
+static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc,
+    gpointer data);
+static void tree_v_size_request_cb (GtkWidget *widget,
+    GtkRequisition *requisition, gpointer data);
+static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data);
+static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1,
+    gint arg2, gpointer data);
+static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
+    gpointer user_data);
+
+static gint redraw_notify(void *hook_data, void *call_data);
+
+static void get_events(double time, EventViewerData *event_viewer_data);
+
+int event_hook(void *hook_data, void *call_data);
+
+/* Enumeration of the columns */
+enum
+{
+  TRACE_NAME_COLUMN,
+  TRACEFILE_NAME_COLUMN,
+  CPUID_COLUMN,
+  EVENT_COLUMN,
+  FACILITY_COLUMN,
+  TIME_S_COLUMN,
+  TIME_NS_COLUMN,
+  PID_COLUMN,
+  EVENT_DESCR_COLUMN,
+  POSITION_COLUMN,
+  N_COLUMNS
+};
+
+/**
+ * Event Viewer's constructor hook
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the list.
+ * @param parent_window A pointer to the parent window.
+ * @return The widget created.
+ */
+GtkWidget *
+h_gui_events(Tab * tab)
+{
+  EventViewerData* event_viewer_data = gui_events(tab) ;
+  if(event_viewer_data)
+    return event_viewer_data->top_widget;
+  else return NULL;
+  
+}
+
+/**
+ * Event Viewer's constructor
+ *
+ * This constructor is used to create EventViewerData data structure.
+ * @return The Event viewer data created.
+ */
+EventViewerData *
+gui_events(Tab *tab)
+{
+  LttTime end;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  EventViewerData* event_viewer_data = g_new(EventViewerData,1) ;
+
+  event_viewer_data->tab = tab;
+
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+
+  
+  event_viewer_data->event_hooks = lttv_hooks_new();
+  lttv_hooks_add(event_viewer_data->event_hooks,
+                 event_hook,
+                 event_viewer_data,
+                 LTTV_PRIO_DEFAULT);
+
+  lttvwindow_register_current_time_notify(tab, 
+                update_current_time,event_viewer_data);
+  lttvwindow_register_current_position_notify(tab, 
+                update_current_position,event_viewer_data);
+  lttvwindow_register_traceset_notify(tab, 
+                traceset_changed,event_viewer_data);
+  lttvwindow_register_filter_notify(tab,
+                filter_changed, event_viewer_data);
+  lttvwindow_register_redraw_notify(tab,
+                redraw_notify, event_viewer_data);
+  
+
+  event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (event_viewer_data->scroll_win);
+  gtk_scrolled_window_set_policy(
+      GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win), 
+      GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
+
+  event_viewer_data->currently_selected_position =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->first_event =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->last_event =
+    lttv_traceset_context_position_new(tsc);
+
+  event_viewer_data->main_win_filter = lttvwindow_get_filter(tab);
+
+  event_viewer_data->update_cursor = TRUE;
+  event_viewer_data->report_position = TRUE;
+
+  event_viewer_data->last_tree_update_time = 0;
+
+  /* Create a model for storing the data list */
+  event_viewer_data->store_m = gtk_list_store_new (
+    N_COLUMNS,      /* Total number of columns     */
+    G_TYPE_STRING,  /* Trace name                  */
+    G_TYPE_STRING,  /* Tracefile name              */
+    G_TYPE_UINT,    /* CPUID                       */
+    G_TYPE_STRING,  /* Event                       */
+    G_TYPE_STRING,  /* Facility                    */
+    G_TYPE_UINT,    /* Time s                      */
+    G_TYPE_UINT,    /* Time ns                     */
+    G_TYPE_INT,     /* PID                         */
+    G_TYPE_STRING,  /* Event's description         */
+    G_TYPE_POINTER);/* Position (not shown)        */
+  
+  event_viewer_data->pos = g_ptr_array_sized_new(10);
+  
+  /* Create the viewer widget for the columned list */
+  event_viewer_data->tree_v =
+    gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m));
+    
+  g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-allocate",
+        G_CALLBACK (tree_v_size_allocate_cb),
+        event_viewer_data);
+  g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-request",
+        G_CALLBACK (tree_v_size_request_cb),
+        event_viewer_data);
+  
+  g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "cursor-changed",
+        G_CALLBACK (tree_v_cursor_changed_cb),
+        event_viewer_data);
+  
+  g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "move-cursor",
+        G_CALLBACK (tree_v_move_cursor_cb),
+        event_viewer_data);
+
+  g_signal_connect (G_OBJECT(event_viewer_data->tree_v), "key-press-event",
+      G_CALLBACK(key_handler),
+      event_viewer_data);
+
+  // Use on each column!
+  //gtk_tree_view_column_set_sizing(event_viewer_data->tree_v,
+  //GTK_TREE_VIEW_COLUMN_FIXED);
+  
+  /* The view now holds a reference.  We can get rid of our own
+   * reference */
+  g_object_unref (G_OBJECT (event_viewer_data->store_m));
+  
+
+  /* Create a column, associating the "text" attribute of the
+   * cell_renderer to the first column of the model */
+  /* Columns alignment : 0.0 : Left    0.5 : Center   1.0 : Right */
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Trace",
+                 renderer,
+                 "text", TRACE_NAME_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+  event_viewer_data->button = column->button;
+
+  g_signal_connect (G_OBJECT(event_viewer_data->button),
+        "size-allocate",
+        G_CALLBACK(header_size_allocate),
+        (gpointer)event_viewer_data);
+
+
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Tracefile",
+                 renderer,
+                 "text", TRACEFILE_NAME_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("CPUID",
+                 renderer,
+                 "text", CPUID_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Event",
+                 renderer,
+                 "text", EVENT_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Facility",
+                 renderer,
+                 "text", FACILITY_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Time (s)",
+                 renderer,
+                 "text", TIME_S_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Time (ns)",
+                 renderer,
+                 "text", TIME_NS_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 120);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("PID",
+                 renderer,
+                 "text", PID_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Event Description",
+                 renderer,
+                 "text", EVENT_DESCR_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
+      column);
+
+
+  /* Setup the selection handler */
+  event_viewer_data->select_c =
+    gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v));
+  gtk_tree_selection_set_mode (event_viewer_data->select_c,
+      GTK_SELECTION_SINGLE);
+  g_signal_connect (G_OBJECT (event_viewer_data->select_c), "changed",
+        G_CALLBACK (tree_selection_changed_cb),
+        event_viewer_data);
+  
+  gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win),
+      event_viewer_data->tree_v);
+
+  event_viewer_data->hbox_v = gtk_hbox_new(0, 0);
+  event_viewer_data->top_widget = event_viewer_data->hbox_v;
+  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
+      event_viewer_data->scroll_win, TRUE, TRUE, 0);
+
+  gtk_container_set_border_width(GTK_CONTAINER(event_viewer_data->hbox_v), 1);
+
+  /* Create vertical scrollbar and pack it */
+  event_viewer_data->vscroll_vc = gtk_vscrollbar_new(NULL);
+  gtk_range_set_update_policy (GTK_RANGE(event_viewer_data->vscroll_vc),
+             GTK_UPDATE_CONTINUOUS);
+             // Changed by MD : more user friendly :)
+             //GTK_UPDATE_DISCONTINUOUS);
+  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
+      event_viewer_data->vscroll_vc, FALSE, TRUE, 0);
+  
+  /* Get the vertical scrollbar's adjustment */
+  event_viewer_data->vadjust_c =
+    gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc));
+  event_viewer_data->vtree_adjust_c = gtk_tree_view_get_vadjustment(
+                    GTK_TREE_VIEW (event_viewer_data->tree_v));
+  
+  g_signal_connect (G_OBJECT (event_viewer_data->vadjust_c), "value-changed",
+        G_CALLBACK (v_scroll_cb),
+        event_viewer_data);
+  /* Set the upper bound to the last event number */
+  event_viewer_data->previous_value = 0;
+  event_viewer_data->vadjust_c->lower = 0.0;
+    //event_viewer_data->vadjust_c->upper = event_viewer_data->number_of_events;
+  event_viewer_data->vadjust_c->value = 0.0;
+  event_viewer_data->vadjust_c->step_increment = 1.0;
+  event_viewer_data->vadjust_c->page_increment = 2.0;
+    //  event_viewer_data->vtree_adjust_c->upper;
+  event_viewer_data->vadjust_c->page_size = 2.0;
+  //    event_viewer_data->vtree_adjust_c->upper;
+  /*  Raw event trace */
+  gtk_widget_show(event_viewer_data->hbox_v);
+  gtk_widget_show(event_viewer_data->tree_v);
+  gtk_widget_show(event_viewer_data->vscroll_vc);
+
+  /* Add the object's information to the module's array */
+  g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list,
+      event_viewer_data);
+
+  event_viewer_data->num_visible_events = 1;
+
+  //get the life span of the traceset and set the upper of the scroll bar
+  
+  TimeInterval time_span = tsc->time_span;
+  end = ltt_time_sub(time_span.end_time, time_span.start_time);
+
+  event_viewer_data->vadjust_c->upper =
+              ltt_time_to_double(end);
+
+  /* Set the Selected Event */
+  //  tree_v_set_cursor(event_viewer_data);
+
+ // event_viewer_data->current_time_updated = FALSE;
+ //
+  g_object_set_data_full(
+      G_OBJECT(event_viewer_data->hbox_v),
+      "event_viewer_data",
+      event_viewer_data,
+      (GDestroyNotify)gui_events_free);
+  
+  event_viewer_data->background_info_waiting = 0;
+
+  request_background_data(event_viewer_data);
+  
+
+  return event_viewer_data;
+}
+
+
+
+static gint background_ready(void *hook_data, void *call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData *)hook_data;
+  LttvTrace *trace = (LttvTrace*)call_data;
+
+  event_viewer_data->background_info_waiting--;
+
+  if(event_viewer_data->background_info_waiting == 0) {
+    g_message("event viewer : background computation data ready.");
+
+    redraw_notify(event_viewer_data, NULL);
+  }
+
+  return 0;
+}
+
+
+static void request_background_data(EventViewerData *event_viewer_data)
+{
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  gint num_traces = lttv_traceset_number(tsc->ts);
+  gint i;
+  LttvTrace *trace;
+
+  LttvHooks *background_ready_hook = 
+    lttv_hooks_new();
+  lttv_hooks_add(background_ready_hook, background_ready, event_viewer_data,
+      LTTV_PRIO_DEFAULT);
+  event_viewer_data->background_info_waiting = 0;
+  
+  for(i=0;i<num_traces;i++) {
+    trace = lttv_traceset_get(tsc->ts, i);
+
+    if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
+
+      if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
+                                          trace) == FALSE) {
+        /* We first remove requests that could have been done for the same
+         * information. Happens when two viewers ask for it before servicing
+         * starts.
+         */
+        if(!lttvwindowtraces_background_request_find(trace, "state"))
+          lttvwindowtraces_background_request_queue(
+              main_window_get_widget(event_viewer_data->tab), trace, "state");
+        lttvwindowtraces_background_notify_queue(event_viewer_data,
+                                                 trace,
+                                                 ltt_time_infinite,
+                                                 NULL,
+                                                 background_ready_hook);
+        event_viewer_data->background_info_waiting++;
+      } else { /* in progress */
+      
+        lttvwindowtraces_background_notify_current(event_viewer_data,
+                                                   trace,
+                                                   ltt_time_infinite,
+                                                   NULL,
+                                                   background_ready_hook);
+        event_viewer_data->background_info_waiting++;
+      }
+    } else {
+      /* Data ready. Be its nature, this viewer doesn't need to have
+       * its data ready hook called htere, because a background
+       * request is always linked with a redraw.
+       */
+    }
+    
+  }
+
+  lttv_hooks_destroy(background_ready_hook);
+
+}
+
+static gboolean
+header_size_allocate(GtkWidget *widget,
+                        GtkAllocation *allocation,
+                        gpointer user_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)user_data;
+
+  event_viewer_data->header_height = allocation->height;
+
+  return 0;
+}
+
+
+void tree_v_set_cursor(EventViewerData *event_viewer_data)
+{
+  GtkTreePath *path;
+  
+  g_debug("set cursor cb");
+
+#if 0
+  if(event_viewer_data->currently_selected_event != -1)
+    {
+      path = gtk_tree_path_new_from_indices(
+              event_viewer_data->currently_selected_event,
+              -1);
+      
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+          path, NULL, FALSE);
+      gtk_tree_path_free(path);
+    }
+#endif //0
+}
+
+void tree_v_get_cursor(EventViewerData *event_viewer_data)
+{
+  GtkTreePath *path;
+  gint *indices;
+  
+  g_debug("get cursor cb");
+  
+
+#if 0
+  gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+      &path, NULL);
+  indices = gtk_tree_path_get_indices(path);
+  
+  if(indices != NULL)
+      event_viewer_data->currently_selected_event = indices[0];
+    else
+      event_viewer_data->currently_selected_event = -1;
+  
+  gtk_tree_path_free(path);
+#endif //0
+}
+
+/* Filter out the key repeats that come too fast */
+static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
+    gpointer user_data)
+{
+  EventViewerData *evd = (EventViewerData *)user_data;
+  g_debug("event time : %u , last time : %u", event->time,
+      evd->last_tree_update_time);
+  
+  if(guint32_before(event->time, evd->last_tree_update_time))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+void tree_v_move_cursor_cb (GtkWidget *widget,
+                            GtkMovementStep arg1,
+                            gint arg2,
+                            gpointer data)
+{
+  GtkTreePath *path; // = gtk_tree_path_new();
+  gint *indices;
+  gdouble value;
+  EventViewerData *event_viewer_data = (EventViewerData*)data;
+  
+  g_debug("move cursor cb");
+  //gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+  //                          &path, NULL);
+  //if(path == NULL)
+  //{
+    /* No prior cursor, put it at beginning of page
+     * and let the execution do */
+  //  path = gtk_tree_path_new_from_indices(0, -1);
+  //  gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+  //                              path, NULL, FALSE);
+  //}
+
+  //indices = gtk_tree_path_get_indices(path);
+  
+  //value = gtk_adjustment_get_value(event_viewer_data->vadjust_c);
+  /* If events request pending, do nothing*/
+  if(lttvwindow_events_request_pending(event_viewer_data->tab)) return;
+  
+  /* If no prior position... */
+  if(ltt_time_compare(
+        lttv_traceset_context_position_get_time(
+          event_viewer_data->currently_selected_position),
+        ltt_time_infinite) == 0) {
+    
+    path = gtk_tree_path_new_from_indices(0, -1);
+    gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                                path, NULL, FALSE);
+
+    gtk_tree_path_free(path);
+    return;
+
+  }
+
+  
+  g_debug("tree view move cursor : arg1 is %u and arg2 is %d",
+      (guint)arg1, arg2);
+
+  switch(arg1) {
+  case GTK_MOVEMENT_DISPLAY_LINES:
+    if(arg2 == 1) {
+      /* Move one line down */
+      if(event_viewer_data->pos->len > 0) {
+        LttvTracesetContextPosition *end_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             event_viewer_data->pos->len-1);
+        if(lttv_traceset_context_pos_pos_compare(end_pos, 
+              event_viewer_data->currently_selected_position) == 0) {
+          /* Must get down one event and select the last one */
+          gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+                GTK_TREE_VIEW(event_viewer_data->tree_v)));
+          event_viewer_data->update_cursor = FALSE;
+          gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+              gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
+          event_viewer_data->update_cursor = TRUE;
+          path = gtk_tree_path_new_from_indices(
+              event_viewer_data->pos->len - 1, -1);
+          gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                                   path, NULL, FALSE);
+          gtk_tree_path_free(path);
+        }
+      }
+
+    } else {
+      if(event_viewer_data->pos->len > 0) {
+        /* Move one line up */
+        LttvTracesetContextPosition *begin_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             0);
+        if(lttv_traceset_context_pos_pos_compare(begin_pos, 
+              event_viewer_data->currently_selected_position) == 0) {
+          /* Must get up one event and select the first one */
+          gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+                GTK_TREE_VIEW(event_viewer_data->tree_v)));
+          event_viewer_data->update_cursor = FALSE;
+          gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+              gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
+          event_viewer_data->update_cursor = TRUE;
+          path = gtk_tree_path_new_from_indices(
+              0, -1);
+          gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                                   path, NULL, FALSE);
+          gtk_tree_path_free(path);
+        }
+      }
+    }
+    break;
+  case GTK_MOVEMENT_PAGES:
+    if(arg2 == 1) {
+      /* Move one page down */
+      if(event_viewer_data->pos->len > 0) {
+        LttvTracesetContextPosition *end_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             event_viewer_data->pos->len-1);
+        if(lttv_traceset_context_pos_pos_compare(end_pos, 
+              event_viewer_data->currently_selected_position) == 0) {
+          /* Must get down one page and select the last one */
+          gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+                GTK_TREE_VIEW(event_viewer_data->tree_v)));
+          
+          event_viewer_data->update_cursor = FALSE;
+          gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+              gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 2);
+          event_viewer_data->update_cursor = TRUE;
+
+          path = gtk_tree_path_new_from_indices(
+              event_viewer_data->pos->len - 1, -1);
+          gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                                   path, NULL, FALSE);
+          gtk_tree_path_free(path);
+
+        }
+      }
+
+    } else {
+      /* Move one page up */
+      if(event_viewer_data->pos->len > 0) {
+        LttvTracesetContextPosition *begin_pos = 
+          (LttvTracesetContextPosition*)g_ptr_array_index(
+                                             event_viewer_data->pos,
+                                             0);
+        if(lttv_traceset_context_pos_pos_compare(begin_pos, 
+              event_viewer_data->currently_selected_position) == 0) {
+          /* Must get up one page and select the first one */
+          gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
+                GTK_TREE_VIEW(event_viewer_data->tree_v)));
+          
+          event_viewer_data->update_cursor = FALSE;
+          gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+              gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 2);
+          event_viewer_data->update_cursor = TRUE;
+
+          path = gtk_tree_path_new_from_indices(
+              0, -1);
+          gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                                   path, NULL, FALSE);
+          gtk_tree_path_free(path);
+        }
+      }
+
+    }
+    break;
+  default:
+    break;
+  }
+
+  //gtk_tree_path_free(path);
+  
+#if 0
+  if(arg1 == GTK_MOVEMENT_DISPLAY_LINES)
+  {
+    /* Move one line */
+    if(arg2 == 1)
+    {
+      /* move one line down */
+      if(indices[0]) // Do we need an empty field here (before first)?
+      {
+        if(value + event_viewer_data->num_visible_events <= 
+            event_viewer_data->number_of_events -1)
+        {
+          event_viewer_data->currently_selected_event += 1;
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1);
+          //gtk_tree_path_free(path);
+          //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
+          //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+        }
+      }
+    } else {
+      /* Move one line up */
+      if(indices[0] == 0)
+      {
+        if(value - 1 >= 0 )
+        {
+          event_viewer_data->currently_selected_event -= 1;
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1);
+          //gtk_tree_path_free(path);
+          //path = gtk_tree_path_new_from_indices(0, -1);
+          //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+        }
+      }
+    }
+  }
+  
+  if(arg1 == GTK_MOVEMENT_PAGES)
+  {
+    /* Move one page */
+    if(arg2 == 1)
+    {
+      if(event_viewer_data->num_visible_events == 1)
+        value += 1 ;
+      /* move one page down */
+      if(value + event_viewer_data->num_visible_events-1 <= 
+                      event_viewer_data->number_of_events )
+      {
+        event_viewer_data->currently_selected_event += 
+                                  event_viewer_data->num_visible_events-1;
+        //        gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+        //               value+(event_viewer_data->num_visible_events-1));
+        //gtk_tree_path_free(path);
+        //path = gtk_tree_path_new_from_indices(0, -1);
+        //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+        g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+      }
+    } else {
+      /* Move one page up */
+      if(event_viewer_data->num_visible_events == 1)
+        value -= 1 ;
+
+      if(indices[0] < event_viewer_data->num_visible_events - 2 )
+      {
+        if(value - (event_viewer_data->num_visible_events-1) >= 0)
+        {
+          event_viewer_data->currently_selected_event -=
+                          event_viewer_data->num_visible_events-1;
+      
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+          //             value-(event_viewer_data->num_visible_events-1));
+          //gtk_tree_path_free(path);
+          //path = gtk_tree_path_new_from_indices(0, -1);
+          //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+      
+        } else {
+          /* Go to first Event */
+          event_viewer_data->currently_selected_event == 0 ;
+          //      gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+          //             0);
+          //gtk_tree_path_free(path);
+          //path = gtk_tree_path_new_from_indices(0, -1);
+          //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+          g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+      
+        }
+      }
+    }
+  }
+  
+  if(arg1 == GTK_MOVEMENT_BUFFER_ENDS)
+  {
+    /* Move to the ends of the buffer */
+    if(arg2 == 1)
+    {
+      /* move end of buffer */
+      event_viewer_data->currently_selected_event =
+                            event_viewer_data->number_of_events-1 ;
+      //    gtk_adjustment_set_value(event_viewer_data->vadjust_c, 
+      //           event_viewer_data->number_of_events -
+      //           event_viewer_data->num_visible_events);
+      //gtk_tree_path_free(path);
+      //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
+      //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+    } else {
+      /* Move beginning of buffer */
+      event_viewer_data->currently_selected_event = 0 ;
+      //    gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0);
+        //gtk_tree_path_free(path);
+        //path = gtk_tree_path_new_from_indices(0, -1);
+        //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
+      g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
+    }
+  }
+#endif //0
+}
+
+void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*) data;
+  Tab *tab = event_viewer_data->tab;
+  GtkTreeIter iter;
+  GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
+  GtkTreePath *path;
+  LttvTracesetContextPosition *pos;
+
+  g_debug("cursor changed cb");
+
+  /* On cursor change, modify the currently selected event by calling
+   * the right API function */
+  
+  
+  if(event_viewer_data->report_position) {
+    gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+        &path, NULL);
+    if(gtk_tree_model_get_iter(model,&iter,path)){
+      gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
+      
+      if(lttv_traceset_context_pos_pos_compare(pos, 
+            event_viewer_data->currently_selected_position) != 0)
+        lttvwindow_report_current_position(tab, pos);
+    }else{
+      g_warning("Can not get iter\n");
+    }
+    gtk_tree_path_free(path);
+  }
+}
+
+
+static void tree_selection_changed_cb (GtkTreeSelection *selection,
+    gpointer data)
+{
+  g_debug("tree sel changed cb");
+  EventViewerData *event_viewer_data = (EventViewerData*) data;
+#if 0
+    /* Set the cursor to currently selected event */
+  GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
+  GtkTreeIter iter;
+  LttvTracesetContextPosition *pos;
+  guint i;
+  GtkTreePath *tree_path;
+
+  for(i=0;i<event_viewer_data->num_visible_events;i++) {
+    tree_path = gtk_tree_path_new_from_indices(
+                i,
+               -1);
+    if(gtk_tree_model_get_iter(model,&iter,tree_path)){
+      gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
+      
+      if(lttv_traceset_context_pos_pos_compare(pos, 
+            event_viewer_data->currently_selected_position) == 0) {
+        /* Match! */
+            gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                tree_path, NULL, FALSE);
+        break;
+      }
+      
+    }else{
+      g_warning("Can not get iter\n");
+    }
+   gtk_tree_path_free(tree_path);
+  }
+#endif //0
+}
+
+#if 0
+static gint key_snooper(GtkWidget *grab_widget, GdkEventKey *event,
+    gpointer func_data)
+{
+  return TRUE;
+}
+#endif //0
+
+/* This callback may be recalled after a step up/down, but we don't want to lose
+ * the exact position : what we do is that we only set the value if it has
+ * changed : a step up/down that doesn't change the time value of the first
+ * event won't trigger a scrollbar change. */
+
+void v_scroll_cb (GtkAdjustment *adjustment, gpointer data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)data;
+  LttvTracesetStats *tss =
+    lttvwindow_get_traceset_stats(event_viewer_data->tab);
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+  g_debug("SCROLL begin");
+  g_debug("SCROLL values : %g , %g, %g",
+      adjustment->value, event_viewer_data->previous_value,
+      (adjustment->value - event_viewer_data->previous_value));
+
+  LttTime new_time_off = ltt_time_from_double(adjustment->value);
+  LttTime old_time_off = ltt_time_from_double(event_viewer_data->previous_value);
+  g_debug("SCROLL time values %lu.%lu, %lu.%lu", new_time_off.tv_sec,
+      new_time_off.tv_nsec, old_time_off.tv_sec, old_time_off.tv_nsec);
+  /* If same value : nothing to update */
+  if(ltt_time_compare(new_time_off, old_time_off) == 0)
+    return;
+  
+  //LttTime old_time = event_viewer_data->first_event;
+  
+
+  //gint snoop = gtk_key_snooper_install(key_snooper, NULL);
+  
+  get_events(adjustment->value, event_viewer_data);
+
+  //gtk_key_snooper_remove(snoop);
+#if 0 
+  LttTime time = ltt_time_sub(event_viewer_data->first_event,
+                              tsc->time_span.start_time);
+  double value = ltt_time_to_double(time);
+  gtk_adjustment_set_value(event_viewer_data->vadjust_c, value);
+  
+  if(event_viewer_data->currently_selected_event != -1) {
+      
+      tree_path = gtk_tree_path_new_from_indices(
+             event_viewer_data->currently_selected_event,
+             -1);
+      
+      //      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), tree_path,
+      //             NULL, FALSE);
+      gtk_tree_path_free(tree_path);
+  }
+#endif //0
+  g_debug("SCROLL end");
+}
+
+static __inline gint get_cell_height(GtkTreeView *TreeView)
+{
+  gint height;
+  GtkTreeViewColumn *column = gtk_tree_view_get_column(TreeView, 0);
+  
+  gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height);
+  
+  return height;
+}
+
+void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)data;
+  gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
+  gint last_num_visible_events = event_viewer_data->num_visible_events;
+  gdouble exact_num_visible;
+  
+  exact_num_visible = ( alloc->height -
+          event_viewer_data->header_height )
+            / (double)cell_height ;
+  
+  event_viewer_data->num_visible_events = ceil(exact_num_visible) ;
+  
+/*
+  event_viewer_data->vadjust_c->page_increment = 
+    floor(exact_num_visible);
+  event_viewer_data->vadjust_c->page_size =
+    floor(exact_num_visible);
+*/
+  g_debug("size allocate : last_num_visible_events : %d,\
+           num_visible_events : %d",
+           last_num_visible_events,
+           event_viewer_data->num_visible_events);
+  if(event_viewer_data->num_visible_events != last_num_visible_events)
+    {
+      get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+    }
+  
+
+}
+
+void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data)
+{
+  gint h;
+  EventViewerData *event_viewer_data = (EventViewerData*)data;
+  gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
+  
+  h = cell_height + event_viewer_data->header_height;
+  requisition->height = h;
+  
+}
+
+#if 0
+gboolean show_event_detail(void * hook_data, void * call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+  LttvTracesetContext * tsc = lttvwindow_get_traceset_context(event_viewer_data->tab);
+
+  if(event_viewer_data->event_fields_queue_tmp->length == 0 &&
+     event_viewer_data->event_fields_queue->length == 0){
+    event_viewer_data->shown = FALSE;
+    return FALSE;
+  }
+
+  if(event_viewer_data->shown == FALSE){
+    event_viewer_data->shown = TRUE;
+    update_raw_data_array(event_viewer_data, 
+        event_viewer_data->event_fields_queue_tmp->length);
+
+    get_data(event_viewer_data->vadjust_c->value,
+      event_viewer_data->num_visible_events, 
+      event_viewer_data);
+
+    remove_context_hooks(event_viewer_data,tsc);
+  }
+
+  return FALSE;
+}
+#endif //0
+
+
+
+
+
+
+
+static void get_events(double new_value, EventViewerData *event_viewer_data)
+{
+  GtkTreePath *tree_path;
+  LttvTracesetStats *tss =
+    lttvwindow_get_traceset_stats(event_viewer_data->tab);
+  LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
+  guint i;
+  gboolean seek_by_time;
+  
+  double value = new_value - event_viewer_data->previous_value;
+
+  /* See where we have to scroll... */
+  ScrollDirection direction;
+  gint relative_position;
+  
+  if(value < -0.8) {
+    if(value >= -1.0) direction = SCROLL_STEP_UP;
+    else {
+      if(value >= -2.0) direction = SCROLL_PAGE_UP;
+      else direction = SCROLL_JUMP;
+    }
+  } else if(value > 0.8) {
+    if(value <= 1.0) direction = SCROLL_STEP_DOWN;
+    else {
+      if(value <= 2.0) direction = SCROLL_PAGE_DOWN;
+      else direction = SCROLL_JUMP;
+    }
+  } else direction = SCROLL_NONE; /* 0.0 */
+
+
+  switch(direction) {
+  case SCROLL_STEP_UP:
+    g_debug("get_events : SCROLL_STEP_UP");
+    relative_position = -1;
+    seek_by_time = 0;
+    break;
+  case SCROLL_STEP_DOWN:
+    g_debug("get_events : SCROLL_STEP_DOWN");
+    relative_position = 1;
+    seek_by_time = 0;
+    break;
+  case SCROLL_PAGE_UP:
+    g_debug("get_events : SCROLL_PAGE_UP");
+    relative_position = -(event_viewer_data->num_visible_events);
+    seek_by_time = 0;
+    break;
+  case SCROLL_PAGE_DOWN:
+    g_debug("get_events : SCROLL_PAGE_DOWN");
+    relative_position = event_viewer_data->num_visible_events;
+    seek_by_time = 0;
+    break;
+  case SCROLL_JUMP:
+    g_debug("get_events : SCROLL_JUMP");
+    seek_by_time = 1;
+    break;
+  case SCROLL_NONE:
+    g_debug("get_events : SCROLL_NONE");
+    relative_position = 0;
+    seek_by_time = 0;
+    break;
+  }
+
+  LttTime time = ltt_time_from_double(new_value);
+  time = ltt_time_add(tsc->time_span.start_time, time);
+
+  if(!seek_by_time) {
+  
+    LttvTracesetContextPosition *pos =
+        lttv_traceset_context_position_new(tsc);
+    
+    /* Remember the beginning position */
+    if(event_viewer_data->pos->len > 0) {
+      LttvTracesetContextPosition *first_pos = 
+        (LttvTracesetContextPosition*)g_ptr_array_index(
+                                                    event_viewer_data->pos,
+                                                    0);
+      lttv_traceset_context_position_copy(pos, first_pos);
+
+      if(relative_position >= 0) {
+        LttTime first_event_time = 
+            lttv_traceset_context_position_get_time(
+                              pos);
+        lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+          first_event_time);
+        lttv_process_traceset_middle(tsc, ltt_time_infinite,
+                                   G_MAXUINT,
+                                   pos);
+       
+      } else if(relative_position < 0) {
+        g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0); 
+      }
+    } else {
+      /* There is nothing in the list : simply seek to the time value. */
+      lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+          time);
+      lttv_process_traceset_middle(tsc, time, G_MAXUINT,
+                                   NULL);
+    }
+    
+  /* Note that, as we mess with the tsc position, this function CANNOT be called
+   * from a hook inside the lttv_process_traceset_middle. */
+  /* As the lttvwindow API keeps a sync_position inside the tsc to go back at
+   * the right spot after being interrupted, it's ok to change the tsc position,
+   * as long as we do not touch the sync_position. */
+
+  /* Get the beginning position of the read (with seek backward or seek forward)
+   */
+    if(relative_position > 0) {
+      guint count;
+      count = lttv_process_traceset_seek_n_forward(tsc, relative_position,
+          event_viewer_data->main_win_filter);
+    } else if(relative_position < 0) {
+      guint count;
+      
+      /* Get an idea of currently shown event dispersion */
+      LttTime first_event_time =
+        lttv_traceset_context_position_get_time(event_viewer_data->first_event);
+      LttTime last_event_time =
+        lttv_traceset_context_position_get_time(event_viewer_data->last_event);
+      LttTime time_diff = ltt_time_sub(last_event_time, first_event_time);
+      if(ltt_time_compare(time_diff, ltt_time_zero) == 0)
+        time_diff = seek_back_default_offset;
+      count = lttv_process_traceset_seek_n_backward(tsc, abs(relative_position),
+          time_diff,
+          (seek_time_fct)lttv_state_traceset_seek_time_closest,
+          event_viewer_data->main_win_filter);
+    } /* else 0 : do nothing : we are already at the beginning position */
+
+    lttv_traceset_context_position_destroy(pos);
+
+    /* Save the first event position */
+    lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
+    
+    time = lttv_traceset_context_position_get_time(
+                                            event_viewer_data->first_event);
+    //if(ltt_time_compare(time, tsc->time_span.end_time) > 0)
+    //  time = tsc->time_span.end_time;
+
+    LttTime time_val = ltt_time_sub(time,
+                        tsc->time_span.start_time);
+    event_viewer_data->previous_value = ltt_time_to_double(time_val);
+    
+    lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, time);
+    lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT,
+                                 event_viewer_data->first_event);
+
+  } else {
+    /* Seek by time */
+    lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+          time);
+    lttv_process_traceset_middle(tsc, time, G_MAXUINT,
+                                 NULL);
+    LttTime time_val = ltt_time_sub(time,
+                        tsc->time_span.start_time);
+    event_viewer_data->previous_value = ltt_time_to_double(time_val);
+    lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
+  }
+  /* Clear the model (don't forget to free the TCS positions!) */
+  gtk_list_store_clear(event_viewer_data->store_m);
+  for(i=0;i<event_viewer_data->pos->len;i++) {
+    LttvTracesetContextPosition *cur_pos = 
+      (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
+                                                      i);
+    lttv_traceset_context_position_destroy(cur_pos);
+  }
+  g_ptr_array_set_size(event_viewer_data->pos, 0);
+  
+
+  /* Mathieu :
+   * I make the choice not to use the mainwindow lttvwindow API here : the idle
+   * loop might have a too low priority, and we want good update while
+   * scrolling.
+   */
+  
+  lttv_process_traceset_begin(tsc,
+      NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
+  
+  lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
+  
+  lttv_process_traceset_end(tsc,
+      NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
+  
+  /* Get the end position */
+  if(event_viewer_data->pos->len > 0) {
+    LttvTracesetContextPosition *cur_pos = 
+      (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
+                                               event_viewer_data->pos->len - 1);
+    lttv_traceset_context_position_copy(event_viewer_data->last_event,
+        cur_pos);
+  } else
+    lttv_traceset_context_position_save(tsc, event_viewer_data->last_event);
+
+  gtk_adjustment_set_value(event_viewer_data->vadjust_c,
+      event_viewer_data->previous_value);
+  
+  //g_signal_emit_by_name(G_OBJECT (event_viewer_data->select_c),
+  //    "changed");
+  
+  event_viewer_data->last_tree_update_time = 
+    gdk_x11_get_server_time(
+        gtk_widget_get_parent_window(event_viewer_data->tree_v));
+
+  return;
+}
+
+
+
+int event_hook(void *hook_data, void *call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
+  LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
+  LttEvent *e = ltt_tracefile_get_event(tfc->tf);
+
+  LttvFilter *filter = event_viewer_data->main_win_filter;
+  if(filter != NULL && filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
+
+  LttFacility *facility = ltt_event_facility(e);
+  LttEventType *event_type = ltt_event_eventtype(e);
+  LttField *field = ltt_event_field(e);
+  LttTime time = ltt_event_time(e);
+
+  guint cpu = ltt_tracefile_num(tfc->tf);
+  LttvTraceState *ts = (LttvTraceState*)tfc->t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+  
+  GtkTreeIter iter;
+
+  GString *desc = g_string_new("");
+  
+  LttvTracesetContextPosition *pos =
+    lttv_traceset_context_position_new(tfc->t_context->ts_context);
+
+  lttv_traceset_context_position_save(tfc->t_context->ts_context, pos);
+
+  if(field)
+    lttv_print_field(e, field, desc, TRUE);
+
+  g_info("field : %s", desc->str);
+  
+  gtk_list_store_append (event_viewer_data->store_m, &iter);
+  gtk_list_store_set (event_viewer_data->store_m, &iter,
+      TRACE_NAME_COLUMN, g_quark_to_string(ltt_trace_name(tfc->t_context->t)),
+      TRACEFILE_NAME_COLUMN, g_quark_to_string(ltt_tracefile_name(tfc->tf)),
+      CPUID_COLUMN, cpu,
+      FACILITY_COLUMN, g_quark_to_string(ltt_facility_name(facility)),
+      EVENT_COLUMN, g_quark_to_string(ltt_eventtype_name(event_type)),
+      TIME_S_COLUMN, time.tv_sec,
+      TIME_NS_COLUMN, time.tv_nsec,
+      PID_COLUMN, process->pid,
+      EVENT_DESCR_COLUMN, desc->str,
+      POSITION_COLUMN, pos,
+      -1);
+
+  g_ptr_array_add(event_viewer_data->pos, pos);
+  
+  g_string_free(desc, TRUE);
+
+  if(event_viewer_data->update_cursor) {
+    if(lttv_traceset_context_pos_pos_compare(pos, 
+          event_viewer_data->currently_selected_position) == 0) {
+      GtkTreePath *path = gtk_tree_path_new_from_indices(
+                          event_viewer_data->pos->len - 1, -1);
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                             path, NULL, FALSE);
+      gtk_tree_path_free(path);
+    }
+  }
+  
+  if(event_viewer_data->pos->len >= event_viewer_data->num_visible_events )
+    return TRUE;
+  else
+    return FALSE;
+}
+
+
+
+static void event_update_selection(EventViewerData *event_viewer_data)
+{
+  guint i;
+  GPtrArray *positions = event_viewer_data->pos;
+  g_info("event_update_selection");
+
+  for(i=0;i<positions->len;i++) {
+    LttvTracesetContextPosition *cur_pos = 
+      (LttvTracesetContextPosition*)g_ptr_array_index(positions, i);
+    if(lttv_traceset_context_pos_pos_compare(cur_pos, 
+          event_viewer_data->currently_selected_position) == 0) {
+      GtkTreePath *path = gtk_tree_path_new_from_indices(i, -1);
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
+                             path, NULL, FALSE);
+      gtk_tree_path_free(path);
+    }
+  }
+}
+
+static int current_time_get_first_event_hook(void *hook_data, void *call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
+  LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
+  LttEvent *e = ltt_tracefile_get_event(tfc->tf);
+
+  LttvFilter *filter = event_viewer_data->main_win_filter;
+  if(filter != NULL && filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+          tfc->t_context->t,tfc))
+      return FALSE;
+
+  lttv_traceset_context_position_save(tfc->t_context->ts_context, 
+      event_viewer_data->current_time_get_first);
+  return TRUE;
+}
+
+
+gboolean update_current_time(void * hook_data, void * call_data)
+{
+  g_info("update_current_time");
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+  const LttTime * current_time = (LttTime*)call_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  GtkTreePath *path;
+  
+  /* If the currently selected event time != current time, set the first event
+   * with this time as currently selected. */
+  LttTime pos_time = lttv_traceset_context_position_get_time(
+      event_viewer_data->currently_selected_position);
+  if(ltt_time_compare(pos_time, *current_time) != 0) {
+    
+    lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
+        *current_time);
+    lttv_process_traceset_middle(tsc, *current_time, G_MAXUINT,
+                                   NULL);
+
+    /* Get the first event that passes in the filter */
+    event_viewer_data->current_time_get_first =
+                lttv_traceset_context_position_new(tsc);
+    LttvHooks *hooks = lttv_hooks_new();
+    lttv_hooks_add(hooks,
+                   current_time_get_first_event_hook,
+                   event_viewer_data,
+                   LTTV_PRIO_DEFAULT);
+
+    lttv_process_traceset_begin(tsc,
+        NULL, NULL, NULL, hooks, NULL);
+    
+    lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
+    
+    lttv_process_traceset_end(tsc,
+        NULL, NULL, NULL, hooks, NULL);
+   
+    lttv_hooks_destroy(hooks);
+
+    lttv_traceset_context_position_copy(
+        event_viewer_data->currently_selected_position,
+        event_viewer_data->current_time_get_first);
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->current_time_get_first);
+    pos_time = lttv_traceset_context_position_get_time(
+        event_viewer_data->currently_selected_position);
+  }
+
+  LttTime time = ltt_time_sub(pos_time, tsc->time_span.start_time);
+  double new_value = ltt_time_to_double(time);
+  event_viewer_data->report_position = FALSE;
+  /* Change the viewed area if does not match */
+  if(lttv_traceset_context_pos_pos_compare(
+        event_viewer_data->currently_selected_position,
+        event_viewer_data->first_event) < 0
+    ||
+     lttv_traceset_context_pos_pos_compare(
+        event_viewer_data->currently_selected_position,
+        event_viewer_data->last_event) > 0) {
+    gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
+  } else {
+    /* Simply update the current time : it is in the list */
+    event_update_selection(event_viewer_data);
+  }
+  event_viewer_data->report_position = TRUE;
+  
+  return FALSE;
+}
+
+gboolean update_current_position(void * hook_data, void * call_data)
+{
+  g_info("update_current_position");
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+  const LttvTracesetContextPosition *current_pos =
+    (LttvTracesetContextPosition*)call_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  
+  if(lttv_traceset_context_pos_pos_compare(
+        event_viewer_data->currently_selected_position, current_pos) != 0) {
+    lttv_traceset_context_position_copy(
+        event_viewer_data->currently_selected_position, current_pos);
+
+    /* Change the viewed area if does not match */
+    if(lttv_traceset_context_pos_pos_compare(
+          event_viewer_data->currently_selected_position,
+          event_viewer_data->first_event) < 0
+      ||
+       lttv_traceset_context_pos_pos_compare(
+          event_viewer_data->currently_selected_position,
+          event_viewer_data->last_event) > 0) {
+      LttTime time = lttv_traceset_context_position_get_time(current_pos);
+      time = ltt_time_sub(time, tsc->time_span.start_time);
+      double new_value = ltt_time_to_double(time);
+      gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
+    } else {
+      /* Simply update the current time : it is in the list */
+      event_update_selection(event_viewer_data);
+    }
+
+  }
+
+
+  return FALSE;
+}
+
+
+
+gboolean traceset_changed(void * hook_data, void * call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+  TimeInterval time_span = tsc->time_span;
+  LttTime end;
+  gtk_list_store_clear(event_viewer_data->store_m);
+  g_ptr_array_set_size(event_viewer_data->pos, 0);
+
+  end = ltt_time_sub(time_span.end_time, time_span.start_time);
+  event_viewer_data->vadjust_c->upper = ltt_time_to_double(end);
+
+  /* Reset the positions */
+  lttv_traceset_context_position_destroy(
+      event_viewer_data->currently_selected_position);
+  lttv_traceset_context_position_destroy(
+      event_viewer_data->first_event);
+  lttv_traceset_context_position_destroy(
+      event_viewer_data->last_event);
+  event_viewer_data->currently_selected_position =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->first_event =
+    lttv_traceset_context_position_new(tsc);
+  event_viewer_data->last_event =
+    lttv_traceset_context_position_new(tsc);
+
+  get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+  //  event_viewer_data->vadjust_c->value = 0;
+
+  return FALSE;
+}
+
+gboolean filter_changed(void * hook_data, void * call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+  LttvTracesetContext * tsc =
+        lttvwindow_get_traceset_context(event_viewer_data->tab);
+
+  event_viewer_data->main_win_filter = 
+    (LttvFilter*)call_data;
+  get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+
+  return FALSE;
+}
+
+
+gint redraw_notify(void *hook_data, void *call_data)
+{
+  EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+
+  get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+}
+
+void gui_events_free(EventViewerData *event_viewer_data)
+{
+  Tab *tab = event_viewer_data->tab;
+  guint i;
+  if(event_viewer_data){
+    lttv_hooks_remove(event_viewer_data->event_hooks,event_hook);
+    lttv_hooks_destroy(event_viewer_data->event_hooks);
+    
+    for(i=0;i<event_viewer_data->pos->len;i++) {
+      LttvTracesetContextPosition *cur_pos = 
+        (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
+                                                        i);
+      lttv_traceset_context_position_destroy(cur_pos);
+    }
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->currently_selected_position);
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->first_event);
+    lttv_traceset_context_position_destroy(
+        event_viewer_data->last_event);
+    g_ptr_array_free(event_viewer_data->pos, TRUE);
+    
+    lttvwindow_unregister_current_time_notify(tab,
+                        update_current_time, event_viewer_data);
+    lttvwindow_unregister_current_position_notify(tab,
+                        update_current_position, event_viewer_data);
+    //lttvwindow_unregister_show_notify(tab,
+    //                    show_event_detail, event_viewer_data);
+    lttvwindow_unregister_traceset_notify(tab,
+                        traceset_changed, event_viewer_data);
+    lttvwindow_unregister_filter_notify(tab,
+                        filter_changed, event_viewer_data);
+    lttvwindow_unregister_redraw_notify(tab,
+                redraw_notify, event_viewer_data);
+
+    lttvwindowtraces_background_notify_remove(event_viewer_data);
+
+    g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list,
+        event_viewer_data);
+    g_free(event_viewer_data);
+  }
+}
+
+
+
+void gui_events_destructor(EventViewerData *event_viewer_data)
+{
+  /* May already been done by GTK window closing */
+  if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){
+    gtk_widget_destroy(event_viewer_data->hbox_v);
+  }
+}
+
+
+
+/**
+ * plugin's init function
+ *
+ * This function initializes the Event Viewer functionnality through the
+ * gtkTraceSet API.
+ */
+static void init() {
+
+  lttvwindow_register_constructor("guievents",
+                                  "/",
+                                  "Insert Event Viewer",
+                                  hGuiEventsInsert_xpm,
+                                  "Insert Event Viewer",
+                                  h_gui_events);
+}
+
+void event_destroy_walk(gpointer data, gpointer user_data)
+{
+  gui_events_destructor((EventViewerData*)data);
+}
+
+/**
+ * plugin's destroy function
+ *
+ * This function releases the memory reserved by the module and unregisters
+ * everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+  
+  g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL );
+  g_slist_free(g_event_viewer_data_list);
+
+  lttvwindow_unregister_constructor(h_gui_events);
+  
+}
+
+
+
+
+LTTV_MODULE("guievents", "Detailed events view", \
+    "Graphical module to display a detailed event list", \
+           init, destroy, "lttvwindow", "print")
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/hGuiEventsInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/detailedevents/hGuiEventsInsert.xpm
new file mode 100644 (file)
index 0000000..159209b
--- /dev/null
@@ -0,0 +1,230 @@
+/* XPM */
+static char * hGuiEventsInsert_xpm[] = {
+"22 22 205 2",
+"      c None",
+".     c #3995E5",
+"+     c #449DE8",
+"@     c #4BA0EA",
+"#     c #479BE7",
+"$     c #4395E5",
+"%     c #3F8FE2",
+"&     c #3A89E0",
+"*     c #3683DD",
+"=     c #327DDB",
+"-     c #2D77D8",
+";     c #2971D6",
+">     c #246BD3",
+",     c #2065D1",
+"'     c #1B5FCE",
+")     c #1759CC",
+"!     c #1253C9",
+"~     c #0E4DC7",
+"{     c #0A47C4",
+"]     c #0742C2",
+"^     c #053FBF",
+"/     c #0238B2",
+"(     c #0032A4",
+"_     c #8BCFFF",
+":     c #84C9FF",
+"<     c #7DC1FF",
+"[     c #75BAFF",
+"}     c #6DB2FF",
+"|     c #65AAFF",
+"1     c #5DA1FF",
+"2     c #5499FF",
+"3     c #4B90FF",
+"4     c #4287FF",
+"5     c #397FFF",
+"6     c #3076FF",
+"7     c #276DFF",
+"8     c #1E64FF",
+"9     c #155BFF",
+"0     c #0C52FF",
+"a     c #044AFF",
+"b     c #0349FF",
+"c     c #0340F1",
+"d     c #0032AB",
+"e     c #4DA3EC",
+"f     c #84C8FF",
+"g     c #7EC2FF",
+"h     c #77BBFF",
+"i     c #70B4FF",
+"j     c #68ADFF",
+"k     c #60A5FF",
+"l     c #589DFF",
+"m     c #5095FF",
+"n     c #488DFF",
+"o     c #3F84FF",
+"p     c #367BFF",
+"q     c #2D73FF",
+"r     c #246AFF",
+"s     c #1C61FF",
+"t     c #1358FF",
+"u     c #0A4FFF",
+"v     c #0343F6",
+"w     c #0132B1",
+"x     c #5BA8EB",
+"y     c #BFE1FF",
+"z     c #BCDEFF",
+"A     c #B9DBFF",
+"B     c #B5D7FF",
+"C     c #B1D4FF",
+"D     c #AED0FF",
+"E     c #AACCFF",
+"F     c #A6C8FF",
+"G     c #A2C4FF",
+"H     c #9DC0FF",
+"I     c #99BCFF",
+"J     c #95B8FF",
+"K     c #90B3FF",
+"L     c #8CAFFF",
+"M     c #87AAFF",
+"N     c #82A5FE",
+"O     c #7FA2FE",
+"P     c #7EA1FD",
+"Q     c #7DA0FD",
+"R     c #7A9AF5",
+"S     c #1D48B3",
+"T     c #6AAFEB",
+"U     c #FFFFFF",
+"V     c #FEFEFF",
+"W     c #FDFDFE",
+"X     c #FBFBFC",
+"Y     c #F9F9FB",
+"Z     c #F7F7FA",
+"`     c #F6F6F9",
+" .    c #F0EFF4",
+"..    c #385EB5",
+"+.    c #69AEEA",
+"@.    c #F4F4F8",
+"#.    c #EEEDF3",
+"$.    c #385DB4",
+"%.    c #69ACE9",
+"&.    c #848484",
+"*.    c #7F7F7F",
+"=.    c #808080",
+"-.    c #7E7E7F",
+";.    c #7D7D7E",
+">.    c #7C7C7D",
+",.    c #7B7B7D",
+"'.    c #7B7B7C",
+").    c #7A7A7C",
+"!.    c #F2F2F7",
+"~.    c #ECEBF2",
+"{.    c #375CB4",
+"].    c #68AAE8",
+"^.    c #FBFBFD",
+"/.    c #F1F1F6",
+"(.    c #E9E9F0",
+"_.    c #365BB3",
+":.    c #67A9E7",
+"<.    c #F8F8FB",
+"[.    c #F3F3F7",
+"}.    c #EFEFF5",
+"|.    c #E7E7EE",
+"1.    c #355AB2",
+"2.    c #66A7E6",
+"3.    c #858585",
+"4.    c #7C7C7E",
+"5.    c #79797B",
+"6.    c #78787B",
+"7.    c #7B7B7E",
+"8.    c #EDEDF4",
+"9.    c #E5E5ED",
+"0.    c #3459B2",
+"a.    c #65A6E5",
+"b.    c #F9F9FC",
+"c.    c #ECECF3",
+"d.    c #E3E3EC",
+"e.    c #3358B1",
+"f.    c #64A5E4",
+"g.    c #F6F6FA",
+"h.    c #EAEAF2",
+"i.    c #E1E1EA",
+"j.    c #3358B0",
+"k.    c #63A3E3",
+"l.    c #8D8D8D",
+"m.    c #8A8A8C",
+"n.    c #77777A",
+"o.    c #76767A",
+"p.    c #767679",
+"q.    c #808085",
+"r.    c #E8E8F1",
+"s.    c #DFDFE9",
+"t.    c #3257B0",
+"u.    c #62A2E2",
+"v.    c #FAFAFC",
+"w.    c #F4F4F9",
+"x.    c #EEEEF4",
+"y.    c #E7E7F0",
+"z.    c #DEDDE8",
+"A.    c #62A0E1",
+"B.    c #E5E5EF",
+"C.    c #DCDCE7",
+"D.    c #619FE1",
+"E.    c #8A8A8B",
+"F.    c #87878A",
+"G.    c #757579",
+"H.    c #747478",
+"I.    c #737378",
+"J.    c #7E7E83",
+"K.    c #E3E3EE",
+"L.    c #DBDBE6",
+"M.    c #609DDF",
+"N.    c #F3F3F8",
+"O.    c #F1F1F7",
+"P.    c #E2E2ED",
+"Q.    c #DAD9E6",
+"R.    c #5E9ADE",
+"S.    c #FAFAFB",
+"T.    c #F9F9FA",
+"U.    c #F7F6F9",
+"V.    c #F5F4F7",
+"W.    c #F2F2F6",
+"X.    c #F1F0F5",
+"Y.    c #EFEEF3",
+"Z.    c #EDECF2",
+"`.    c #EBEAF1",
+" +    c #E9E8EF",
+".+    c #E7E6EE",
+"++    c #E4E4ED",
+"@+    c #E3E2EB",
+"#+    c #E1E0EA",
+"$+    c #D4D3E0",
+"%+    c #357FD4",
+"&+    c #5791D7",
+"*+    c #548CD4",
+"=+    c #5188D1",
+"-+    c #4E83CE",
+";+    c #4B7ECA",
+">+    c #487AC7",
+",+    c #4575C4",
+"'+    c #4271C1",
+")+    c #406CBE",
+"!+    c #3D68BB",
+"~+    c #3A63B8",
+"{+    c #375FB5",
+"]+    c #345AB2",
+"^+    c #0C3BA7",
+"                                            ",
+". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( ",
+"+ _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b b c d ",
+"e f g h i j k l m n o p q r s t u b b b v w ",
+"x y z A B C D E F G H I J K L M N O P Q R S ",
+"T U U U U U U U U U U U U U V W X Y Z `  ...",
+"+.U U U U U U U U U U U U V W X Y Z ` @.#.$.",
+"%.U U &.*.*.*.U U =.=.*.*.-.;.>.,.'.).!.~.{.",
+"].U U U U U U U U U U V W ^.Y Z ` @.!./.(._.",
+":.U U U U U U U U U V W ^.Y <.` @.[./.}.|.1.",
+"2.U U 3.*.*.*.U U *.=.;.4.>.'.).5.6.7.8.9.0.",
+"a.U U U U U U U U W ^.b.<.` @.[./.}.8.c.d.e.",
+"f.U U U U U U U W ^.b.<.g.@.[./.}.8.c.h.i.j.",
+"k.U U *.*.*.l.W ^.4.m.,.).5.6.n.o.p.q.r.s.t.",
+"u.U U U U U W ^.v.<.g.w.[./.}.x.c.h.r.y.z.t.",
+"A.U U U U W ^.v.<.g.w.[./.}.x.c.h.r.y.B.C.t.",
+"D.U U *.-.;.E.<.g.).F.6.n.n.p.G.H.I.J.K.L.t.",
+"M.U U W ^.v.<.g.w.N.O.}.x.c.h.r.y.B.K.P.Q.t.",
+"R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+s.z.C.L.Q.$+t.",
+"%+&+*+=+-+;+>+,+'+)+!+~+{+]+t.t.t.t.t.t.t.^+",
+"                                            ",
+"                                            "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/.deps/diskperformance.Plo b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/.deps/diskperformance.Plo
new file mode 100644 (file)
index 0000000..6f889e1
--- /dev/null
@@ -0,0 +1,1044 @@
+diskperformance.lo diskperformance.o: diskperformance.c \
+  /usr/include/math.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/gnu/stubs.h /usr/include/bits/huge_val.h \
+  /usr/include/bits/mathdef.h /usr/include/bits/mathcalls.h \
+  /usr/include/bits/mathinline.h /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/syslimits.h \
+  /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+  /usr/include/bits/posix2_lim.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/gtk-2.0/gtk/gtk.h /usr/include/gtk-2.0/gdk/gdk.h \
+  /usr/include/gtk-2.0/gdk/gdkcolor.h /usr/include/gtk-2.0/gdk/gdktypes.h \
+  /usr/include/pango-1.0/pango/pango.h \
+  /usr/include/pango-1.0/pango/pango-attributes.h \
+  /usr/include/pango-1.0/pango/pango-font.h \
+  /usr/include/pango-1.0/pango/pango-coverage.h \
+  /usr/include/pango-1.0/pango/pango-types.h \
+  /usr/include/glib-2.0/glib-object.h \
+  /usr/include/glib-2.0/gobject/gboxed.h \
+  /usr/include/glib-2.0/gobject/gtype.h \
+  /usr/include/glib-2.0/gobject/genums.h \
+  /usr/include/glib-2.0/gobject/gobject.h \
+  /usr/include/glib-2.0/gobject/gvalue.h \
+  /usr/include/glib-2.0/gobject/gparam.h \
+  /usr/include/glib-2.0/gobject/gclosure.h \
+  /usr/include/glib-2.0/gobject/gsignal.h \
+  /usr/include/glib-2.0/gobject/gmarshal.h \
+  /usr/include/glib-2.0/gobject/gparamspecs.h \
+  /usr/include/glib-2.0/gobject/gsourceclosure.h \
+  /usr/include/glib-2.0/gobject/gtypemodule.h \
+  /usr/include/glib-2.0/gobject/gtypeplugin.h \
+  /usr/include/glib-2.0/gobject/gvaluearray.h \
+  /usr/include/glib-2.0/gobject/gvaluetypes.h \
+  /usr/include/pango-1.0/pango/pango-break.h \
+  /usr/include/pango-1.0/pango/pango-item.h \
+  /usr/include/pango-1.0/pango/pango-context.h \
+  /usr/include/pango-1.0/pango/pango-fontmap.h \
+  /usr/include/pango-1.0/pango/pango-fontset.h \
+  /usr/include/pango-1.0/pango/pango-engine.h \
+  /usr/include/pango-1.0/pango/pango-glyph.h \
+  /usr/include/pango-1.0/pango/pango-script.h \
+  /usr/include/pango-1.0/pango/pango-enum-types.h \
+  /usr/include/pango-1.0/pango/pango-layout.h \
+  /usr/include/pango-1.0/pango/pango-glyph-item.h \
+  /usr/include/pango-1.0/pango/pango-tabs.h \
+  /usr/lib/gtk-2.0/include/gdkconfig.h \
+  /usr/include/gtk-2.0/gdk/gdkcursor.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-features.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-loader.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-enum-types.h \
+  /usr/include/gtk-2.0/gdk/gdkdisplay.h \
+  /usr/include/gtk-2.0/gdk/gdkevents.h /usr/include/gtk-2.0/gdk/gdkdnd.h \
+  /usr/include/gtk-2.0/gdk/gdkinput.h \
+  /usr/include/gtk-2.0/gdk/gdkdrawable.h /usr/include/gtk-2.0/gdk/gdkgc.h \
+  /usr/include/gtk-2.0/gdk/gdkrgb.h \
+  /usr/include/gtk-2.0/gdk/gdkenumtypes.h \
+  /usr/include/gtk-2.0/gdk/gdkfont.h /usr/include/gtk-2.0/gdk/gdkimage.h \
+  /usr/include/gtk-2.0/gdk/gdkkeys.h \
+  /usr/include/gtk-2.0/gdk/gdkdisplaymanager.h \
+  /usr/include/gtk-2.0/gdk/gdkpango.h \
+  /usr/include/gtk-2.0/gdk/gdkpixbuf.h \
+  /usr/include/gtk-2.0/gdk/gdkpixmap.h \
+  /usr/include/gtk-2.0/gdk/gdkproperty.h \
+  /usr/include/gtk-2.0/gdk/gdkregion.h \
+  /usr/include/gtk-2.0/gdk/gdkscreen.h \
+  /usr/include/gtk-2.0/gdk/gdkselection.h \
+  /usr/include/gtk-2.0/gdk/gdkspawn.h \
+  /usr/include/gtk-2.0/gdk/gdkvisual.h \
+  /usr/include/gtk-2.0/gdk/gdkwindow.h \
+  /usr/include/gtk-2.0/gtk/gtkaccelgroup.h \
+  /usr/include/gtk-2.0/gtk/gtkenums.h \
+  /usr/include/gtk-2.0/gtk/gtkaccellabel.h \
+  /usr/include/gtk-2.0/gtk/gtklabel.h /usr/include/gtk-2.0/gtk/gtkmisc.h \
+  /usr/include/gtk-2.0/gtk/gtkwidget.h \
+  /usr/include/gtk-2.0/gtk/gtkobject.h \
+  /usr/include/gtk-2.0/gtk/gtktypeutils.h \
+  /usr/include/gtk-2.0/gtk/gtktypebuiltins.h \
+  /usr/include/gtk-2.0/gtk/gtkdebug.h \
+  /usr/include/gtk-2.0/gtk/gtkadjustment.h \
+  /usr/include/gtk-2.0/gtk/gtkstyle.h \
+  /usr/include/gtk-2.0/gtk/gtksettings.h /usr/include/gtk-2.0/gtk/gtkrc.h \
+  /usr/include/atk-1.0/atk/atkobject.h \
+  /usr/include/atk-1.0/atk/atkstate.h \
+  /usr/include/atk-1.0/atk/atkrelationtype.h \
+  /usr/include/gtk-2.0/gtk/gtkwindow.h /usr/include/gtk-2.0/gtk/gtkbin.h \
+  /usr/include/gtk-2.0/gtk/gtkcontainer.h \
+  /usr/include/gtk-2.0/gtk/gtkmenu.h \
+  /usr/include/gtk-2.0/gtk/gtkmenushell.h \
+  /usr/include/gtk-2.0/gtk/gtkaccelmap.h \
+  /usr/include/gtk-2.0/gtk/gtkaccessible.h /usr/include/atk-1.0/atk/atk.h \
+  /usr/include/atk-1.0/atk/atkaction.h \
+  /usr/include/atk-1.0/atk/atkcomponent.h \
+  /usr/include/atk-1.0/atk/atkutil.h \
+  /usr/include/atk-1.0/atk/atkdocument.h \
+  /usr/include/atk-1.0/atk/atkeditabletext.h \
+  /usr/include/atk-1.0/atk/atktext.h \
+  /usr/include/atk-1.0/atk/atkgobjectaccessible.h \
+  /usr/include/atk-1.0/atk/atkhyperlink.h \
+  /usr/include/atk-1.0/atk/atkhypertext.h \
+  /usr/include/atk-1.0/atk/atkimage.h \
+  /usr/include/atk-1.0/atk/atknoopobject.h \
+  /usr/include/atk-1.0/atk/atknoopobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkregistry.h \
+  /usr/include/atk-1.0/atk/atkobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkrelation.h \
+  /usr/include/atk-1.0/atk/atkrelationset.h \
+  /usr/include/atk-1.0/atk/atkselection.h \
+  /usr/include/atk-1.0/atk/atkstateset.h \
+  /usr/include/atk-1.0/atk/atkstreamablecontent.h \
+  /usr/include/atk-1.0/atk/atktable.h /usr/include/atk-1.0/atk/atkvalue.h \
+  /usr/include/gtk-2.0/gtk/gtkaction.h \
+  /usr/include/gtk-2.0/gtk/gtkactiongroup.h \
+  /usr/include/gtk-2.0/gtk/gtkitemfactory.h \
+  /usr/include/gtk-2.0/gtk/gtkalignment.h \
+  /usr/include/gtk-2.0/gtk/gtkarrow.h \
+  /usr/include/gtk-2.0/gtk/gtkaspectframe.h \
+  /usr/include/gtk-2.0/gtk/gtkframe.h /usr/include/gtk-2.0/gtk/gtkbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkbox.h \
+  /usr/include/gtk-2.0/gtk/gtkbindings.h \
+  /usr/include/gtk-2.0/gtk/gtkbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcalendar.h \
+  /usr/include/gtk-2.0/gtk/gtksignal.h \
+  /usr/include/gtk-2.0/gtk/gtkmarshal.h \
+  /usr/include/gtk-2.0/gtk/gtkcelllayout.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderer.h \
+  /usr/include/gtk-2.0/gtk/gtkcelleditable.h \
+  /usr/include/gtk-2.0/gtk/gtktreeviewcolumn.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodel.h \
+  /usr/include/gtk-2.0/gtk/gtktreesortable.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrendererpixbuf.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderertext.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderertoggle.h \
+  /usr/include/gtk-2.0/gtk/gtkcheckbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktogglebutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcheckmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkitem.h \
+  /usr/include/gtk-2.0/gtk/gtkclipboard.h \
+  /usr/include/gtk-2.0/gtk/gtkselection.h \
+  /usr/include/gtk-2.0/gtk/gtkclist.h \
+  /usr/include/gtk-2.0/gtk/gtkhscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkrange.h \
+  /usr/include/gtk-2.0/gtk/gtkvscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorsel.h \
+  /usr/include/gtk-2.0/gtk/gtkdialog.h /usr/include/gtk-2.0/gtk/gtkvbox.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorseldialog.h \
+  /usr/include/gtk-2.0/gtk/gtkcombo.h /usr/include/gtk-2.0/gtk/gtkhbox.h \
+  /usr/include/gtk-2.0/gtk/gtkcombobox.h \
+  /usr/include/gtk-2.0/gtk/gtktreeview.h \
+  /usr/include/gtk-2.0/gtk/gtkdnd.h \
+  /usr/include/gtk-2.0/gtk/gtkcomboboxentry.h \
+  /usr/include/gtk-2.0/gtk/gtkctree.h /usr/include/gtk-2.0/gtk/gtkcurve.h \
+  /usr/include/gtk-2.0/gtk/gtkdrawingarea.h \
+  /usr/include/gtk-2.0/gtk/gtkeditable.h \
+  /usr/include/gtk-2.0/gtk/gtkentry.h \
+  /usr/include/gtk-2.0/gtk/gtkimcontext.h \
+  /usr/include/gtk-2.0/gtk/gtkentrycompletion.h \
+  /usr/include/gtk-2.0/gtk/gtkliststore.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodelfilter.h \
+  /usr/include/gtk-2.0/gtk/gtkeventbox.h \
+  /usr/include/gtk-2.0/gtk/gtkexpander.h \
+  /usr/include/gtk-2.0/gtk/gtkfilesel.h \
+  /usr/include/gtk-2.0/gtk/gtkfixed.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooserdialog.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooser.h \
+  /usr/include/gtk-2.0/gtk/gtkfilefilter.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooserwidget.h \
+  /usr/include/gtk-2.0/gtk/gtkfontbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkfontsel.h \
+  /usr/include/gtk-2.0/gtk/gtkgamma.h /usr/include/gtk-2.0/gtk/gtkgc.h \
+  /usr/include/gtk-2.0/gtk/gtkhandlebox.h \
+  /usr/include/gtk-2.0/gtk/gtkhbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkhpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkhruler.h \
+  /usr/include/gtk-2.0/gtk/gtkruler.h \
+  /usr/include/gtk-2.0/gtk/gtkhscale.h \
+  /usr/include/gtk-2.0/gtk/gtkscale.h \
+  /usr/include/gtk-2.0/gtk/gtkhseparator.h \
+  /usr/include/gtk-2.0/gtk/gtkseparator.h \
+  /usr/include/gtk-2.0/gtk/gtkiconfactory.h \
+  /usr/include/gtk-2.0/gtk/gtkicontheme.h \
+  /usr/include/gtk-2.0/gtk/gtkimage.h \
+  /usr/include/gtk-2.0/gtk/gtkimagemenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkimcontextsimple.h \
+  /usr/include/gtk-2.0/gtk/gtkimmulticontext.h \
+  /usr/include/gtk-2.0/gtk/gtkinputdialog.h \
+  /usr/include/gtk-2.0/gtk/gtkinvisible.h \
+  /usr/include/gtk-2.0/gtk/gtklayout.h /usr/include/gtk-2.0/gtk/gtklist.h \
+  /usr/include/gtk-2.0/gtk/gtklistitem.h \
+  /usr/include/gtk-2.0/gtk/gtkmain.h \
+  /usr/include/gtk-2.0/gtk/gtkmenubar.h \
+  /usr/include/gtk-2.0/gtk/gtkmessagedialog.h \
+  /usr/include/gtk-2.0/gtk/gtknotebook.h \
+  /usr/include/gtk-2.0/gtk/gtkoldeditable.h \
+  /usr/include/gtk-2.0/gtk/gtkoptionmenu.h \
+  /usr/include/gtk-2.0/gtk/gtkpixmap.h /usr/include/gtk-2.0/gtk/gtkplug.h \
+  /usr/include/gtk-2.0/gtk/gtksocket.h \
+  /usr/include/gtk-2.0/gtk/gtkpreview.h \
+  /usr/include/gtk-2.0/gtk/gtkprogress.h \
+  /usr/include/gtk-2.0/gtk/gtkprogressbar.h \
+  /usr/include/gtk-2.0/gtk/gtkradioaction.h \
+  /usr/include/gtk-2.0/gtk/gtktoggleaction.h \
+  /usr/include/gtk-2.0/gtk/gtkradiobutton.h \
+  /usr/include/gtk-2.0/gtk/gtkradiomenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkradiotoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtktooltips.h \
+  /usr/include/gtk-2.0/gtk/gtkscrolledwindow.h \
+  /usr/include/gtk-2.0/gtk/gtkviewport.h \
+  /usr/include/gtk-2.0/gtk/gtkseparatormenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkseparatortoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtksizegroup.h \
+  /usr/include/gtk-2.0/gtk/gtkspinbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkstatusbar.h \
+  /usr/include/gtk-2.0/gtk/gtkstock.h /usr/include/gtk-2.0/gtk/gtktable.h \
+  /usr/include/gtk-2.0/gtk/gtktearoffmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtktext.h \
+  /usr/include/gtk-2.0/gtk/gtktextbuffer.h \
+  /usr/include/gtk-2.0/gtk/gtktexttagtable.h \
+  /usr/include/gtk-2.0/gtk/gtktexttag.h \
+  /usr/include/gtk-2.0/gtk/gtktextiter.h \
+  /usr/include/gtk-2.0/gtk/gtktextchild.h \
+  /usr/include/gtk-2.0/gtk/gtktextmark.h \
+  /usr/include/gtk-2.0/gtk/gtktextview.h \
+  /usr/include/gtk-2.0/gtk/gtktipsquery.h \
+  /usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbar.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtktree.h \
+  /usr/include/gtk-2.0/gtk/gtktreednd.h \
+  /usr/include/gtk-2.0/gtk/gtktreeitem.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodelsort.h \
+  /usr/include/gtk-2.0/gtk/gtktreeselection.h \
+  /usr/include/gtk-2.0/gtk/gtktreestore.h \
+  /usr/include/gtk-2.0/gtk/gtkuimanager.h \
+  /usr/include/gtk-2.0/gtk/gtkvbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkversion.h \
+  /usr/include/gtk-2.0/gtk/gtkvpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkvruler.h \
+  /usr/include/gtk-2.0/gtk/gtkvscale.h \
+  /usr/include/gtk-2.0/gtk/gtkvseparator.h /usr/include/stdio.h \
+  /usr/include/bits/types.h /usr/include/bits/wordsize.h \
+  /usr/include/bits/typesizes.h /usr/include/libio.h \
+  /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
+  /usr/include/gconv.h /usr/include/bits/stdio_lim.h \
+  /usr/include/bits/sys_errlist.h /usr/include/bits/stdio.h \
+  /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
+  /usr/include/endian.h /usr/include/bits/endian.h \
+  /usr/include/sys/select.h /usr/include/bits/select.h \
+  /usr/include/bits/sigset.h /usr/include/bits/time.h \
+  /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+  /usr/include/bits/sched.h /usr/include/alloca.h /usr/include/string.h \
+  /usr/include/bits/string.h /usr/include/bits/string2.h \
+  ../../../../ltt/ltt.h ../../../../ltt/time.h ../../../../ltt/compiler.h \
+  ../../../../ltt/event.h ../../../../ltt/type.h ../../../../ltt/trace.h \
+  ../../../../ltt/facility.h ../../../../lttv/lttv/module.h \
+  ../../../../lttv/lttv/hook.h ../../../../lttv/lttv/tracecontext.h \
+  ../../../../lttv/lttv/traceset.h ../../../../lttv/lttv/attribute.h \
+  ../../../../lttv/lttv/iattribute.h ../../../../lttv/lttv/state.h \
+  ../../../../lttv/lttv/filter.h \
+  ../../../../lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h \
+  ../../../../lttv/lttv/stats.h \
+  ../../../../lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h \
+  hDiskPerformanceInsert.xpm
+
+/usr/include/math.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/bits/huge_val.h:
+
+/usr/include/bits/mathdef.h:
+
+/usr/include/bits/mathcalls.h:
+
+/usr/include/bits/mathinline.h:
+
+/usr/include/glib-2.0/glib.h:
+
+/usr/include/glib-2.0/glib/galloca.h:
+
+/usr/include/glib-2.0/glib/gtypes.h:
+
+/usr/lib/glib-2.0/include/glibconfig.h:
+
+/usr/include/glib-2.0/glib/gmacros.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/syslimits.h:
+
+/usr/include/limits.h:
+
+/usr/include/bits/posix1_lim.h:
+
+/usr/include/bits/local_lim.h:
+
+/usr/include/linux/limits.h:
+
+/usr/include/bits/posix2_lim.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/float.h:
+
+/usr/include/glib-2.0/glib/garray.h:
+
+/usr/include/glib-2.0/glib/gasyncqueue.h:
+
+/usr/include/glib-2.0/glib/gthread.h:
+
+/usr/include/glib-2.0/glib/gerror.h:
+
+/usr/include/glib-2.0/glib/gquark.h:
+
+/usr/include/glib-2.0/glib/gatomic.h:
+
+/usr/include/glib-2.0/glib/gbacktrace.h:
+
+/usr/include/glib-2.0/glib/gcache.h:
+
+/usr/include/glib-2.0/glib/glist.h:
+
+/usr/include/glib-2.0/glib/gmem.h:
+
+/usr/include/glib-2.0/glib/gcompletion.h:
+
+/usr/include/glib-2.0/glib/gconvert.h:
+
+/usr/include/glib-2.0/glib/gdataset.h:
+
+/usr/include/glib-2.0/glib/gdate.h:
+
+/usr/include/glib-2.0/glib/gdir.h:
+
+/usr/include/glib-2.0/glib/gfileutils.h:
+
+/usr/include/glib-2.0/glib/ghash.h:
+
+/usr/include/glib-2.0/glib/ghook.h:
+
+/usr/include/glib-2.0/glib/giochannel.h:
+
+/usr/include/glib-2.0/glib/gmain.h:
+
+/usr/include/glib-2.0/glib/gslist.h:
+
+/usr/include/glib-2.0/glib/gstring.h:
+
+/usr/include/glib-2.0/glib/gunicode.h:
+
+/usr/include/glib-2.0/glib/gutils.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h:
+
+/usr/include/glib-2.0/glib/gmarkup.h:
+
+/usr/include/glib-2.0/glib/gmessages.h:
+
+/usr/include/glib-2.0/glib/gnode.h:
+
+/usr/include/glib-2.0/glib/gpattern.h:
+
+/usr/include/glib-2.0/glib/gprimes.h:
+
+/usr/include/glib-2.0/glib/gqsort.h:
+
+/usr/include/glib-2.0/glib/gqueue.h:
+
+/usr/include/glib-2.0/glib/grand.h:
+
+/usr/include/glib-2.0/glib/grel.h:
+
+/usr/include/glib-2.0/glib/gscanner.h:
+
+/usr/include/glib-2.0/glib/gshell.h:
+
+/usr/include/glib-2.0/glib/gspawn.h:
+
+/usr/include/glib-2.0/glib/gstrfuncs.h:
+
+/usr/include/glib-2.0/glib/gthreadpool.h:
+
+/usr/include/glib-2.0/glib/gtimer.h:
+
+/usr/include/glib-2.0/glib/gtree.h:
+
+/usr/include/gtk-2.0/gtk/gtk.h:
+
+/usr/include/gtk-2.0/gdk/gdk.h:
+
+/usr/include/gtk-2.0/gdk/gdkcolor.h:
+
+/usr/include/gtk-2.0/gdk/gdktypes.h:
+
+/usr/include/pango-1.0/pango/pango.h:
+
+/usr/include/pango-1.0/pango/pango-attributes.h:
+
+/usr/include/pango-1.0/pango/pango-font.h:
+
+/usr/include/pango-1.0/pango/pango-coverage.h:
+
+/usr/include/pango-1.0/pango/pango-types.h:
+
+/usr/include/glib-2.0/glib-object.h:
+
+/usr/include/glib-2.0/gobject/gboxed.h:
+
+/usr/include/glib-2.0/gobject/gtype.h:
+
+/usr/include/glib-2.0/gobject/genums.h:
+
+/usr/include/glib-2.0/gobject/gobject.h:
+
+/usr/include/glib-2.0/gobject/gvalue.h:
+
+/usr/include/glib-2.0/gobject/gparam.h:
+
+/usr/include/glib-2.0/gobject/gclosure.h:
+
+/usr/include/glib-2.0/gobject/gsignal.h:
+
+/usr/include/glib-2.0/gobject/gmarshal.h:
+
+/usr/include/glib-2.0/gobject/gparamspecs.h:
+
+/usr/include/glib-2.0/gobject/gsourceclosure.h:
+
+/usr/include/glib-2.0/gobject/gtypemodule.h:
+
+/usr/include/glib-2.0/gobject/gtypeplugin.h:
+
+/usr/include/glib-2.0/gobject/gvaluearray.h:
+
+/usr/include/glib-2.0/gobject/gvaluetypes.h:
+
+/usr/include/pango-1.0/pango/pango-break.h:
+
+/usr/include/pango-1.0/pango/pango-item.h:
+
+/usr/include/pango-1.0/pango/pango-context.h:
+
+/usr/include/pango-1.0/pango/pango-fontmap.h:
+
+/usr/include/pango-1.0/pango/pango-fontset.h:
+
+/usr/include/pango-1.0/pango/pango-engine.h:
+
+/usr/include/pango-1.0/pango/pango-glyph.h:
+
+/usr/include/pango-1.0/pango/pango-script.h:
+
+/usr/include/pango-1.0/pango/pango-enum-types.h:
+
+/usr/include/pango-1.0/pango/pango-layout.h:
+
+/usr/include/pango-1.0/pango/pango-glyph-item.h:
+
+/usr/include/pango-1.0/pango/pango-tabs.h:
+
+/usr/lib/gtk-2.0/include/gdkconfig.h:
+
+/usr/include/gtk-2.0/gdk/gdkcursor.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-features.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-loader.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-enum-types.h:
+
+/usr/include/gtk-2.0/gdk/gdkdisplay.h:
+
+/usr/include/gtk-2.0/gdk/gdkevents.h:
+
+/usr/include/gtk-2.0/gdk/gdkdnd.h:
+
+/usr/include/gtk-2.0/gdk/gdkinput.h:
+
+/usr/include/gtk-2.0/gdk/gdkdrawable.h:
+
+/usr/include/gtk-2.0/gdk/gdkgc.h:
+
+/usr/include/gtk-2.0/gdk/gdkrgb.h:
+
+/usr/include/gtk-2.0/gdk/gdkenumtypes.h:
+
+/usr/include/gtk-2.0/gdk/gdkfont.h:
+
+/usr/include/gtk-2.0/gdk/gdkimage.h:
+
+/usr/include/gtk-2.0/gdk/gdkkeys.h:
+
+/usr/include/gtk-2.0/gdk/gdkdisplaymanager.h:
+
+/usr/include/gtk-2.0/gdk/gdkpango.h:
+
+/usr/include/gtk-2.0/gdk/gdkpixbuf.h:
+
+/usr/include/gtk-2.0/gdk/gdkpixmap.h:
+
+/usr/include/gtk-2.0/gdk/gdkproperty.h:
+
+/usr/include/gtk-2.0/gdk/gdkregion.h:
+
+/usr/include/gtk-2.0/gdk/gdkscreen.h:
+
+/usr/include/gtk-2.0/gdk/gdkselection.h:
+
+/usr/include/gtk-2.0/gdk/gdkspawn.h:
+
+/usr/include/gtk-2.0/gdk/gdkvisual.h:
+
+/usr/include/gtk-2.0/gdk/gdkwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccelgroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkenums.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccellabel.h:
+
+/usr/include/gtk-2.0/gtk/gtklabel.h:
+
+/usr/include/gtk-2.0/gtk/gtkmisc.h:
+
+/usr/include/gtk-2.0/gtk/gtkwidget.h:
+
+/usr/include/gtk-2.0/gtk/gtkobject.h:
+
+/usr/include/gtk-2.0/gtk/gtktypeutils.h:
+
+/usr/include/gtk-2.0/gtk/gtktypebuiltins.h:
+
+/usr/include/gtk-2.0/gtk/gtkdebug.h:
+
+/usr/include/gtk-2.0/gtk/gtkadjustment.h:
+
+/usr/include/gtk-2.0/gtk/gtkstyle.h:
+
+/usr/include/gtk-2.0/gtk/gtksettings.h:
+
+/usr/include/gtk-2.0/gtk/gtkrc.h:
+
+/usr/include/atk-1.0/atk/atkobject.h:
+
+/usr/include/atk-1.0/atk/atkstate.h:
+
+/usr/include/atk-1.0/atk/atkrelationtype.h:
+
+/usr/include/gtk-2.0/gtk/gtkwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkbin.h:
+
+/usr/include/gtk-2.0/gtk/gtkcontainer.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenu.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenushell.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccelmap.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccessible.h:
+
+/usr/include/atk-1.0/atk/atk.h:
+
+/usr/include/atk-1.0/atk/atkaction.h:
+
+/usr/include/atk-1.0/atk/atkcomponent.h:
+
+/usr/include/atk-1.0/atk/atkutil.h:
+
+/usr/include/atk-1.0/atk/atkdocument.h:
+
+/usr/include/atk-1.0/atk/atkeditabletext.h:
+
+/usr/include/atk-1.0/atk/atktext.h:
+
+/usr/include/atk-1.0/atk/atkgobjectaccessible.h:
+
+/usr/include/atk-1.0/atk/atkhyperlink.h:
+
+/usr/include/atk-1.0/atk/atkhypertext.h:
+
+/usr/include/atk-1.0/atk/atkimage.h:
+
+/usr/include/atk-1.0/atk/atknoopobject.h:
+
+/usr/include/atk-1.0/atk/atknoopobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkregistry.h:
+
+/usr/include/atk-1.0/atk/atkobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkrelation.h:
+
+/usr/include/atk-1.0/atk/atkrelationset.h:
+
+/usr/include/atk-1.0/atk/atkselection.h:
+
+/usr/include/atk-1.0/atk/atkstateset.h:
+
+/usr/include/atk-1.0/atk/atkstreamablecontent.h:
+
+/usr/include/atk-1.0/atk/atktable.h:
+
+/usr/include/atk-1.0/atk/atkvalue.h:
+
+/usr/include/gtk-2.0/gtk/gtkaction.h:
+
+/usr/include/gtk-2.0/gtk/gtkactiongroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkitemfactory.h:
+
+/usr/include/gtk-2.0/gtk/gtkalignment.h:
+
+/usr/include/gtk-2.0/gtk/gtkarrow.h:
+
+/usr/include/gtk-2.0/gtk/gtkaspectframe.h:
+
+/usr/include/gtk-2.0/gtk/gtkframe.h:
+
+/usr/include/gtk-2.0/gtk/gtkbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkbindings.h:
+
+/usr/include/gtk-2.0/gtk/gtkbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcalendar.h:
+
+/usr/include/gtk-2.0/gtk/gtksignal.h:
+
+/usr/include/gtk-2.0/gtk/gtkmarshal.h:
+
+/usr/include/gtk-2.0/gtk/gtkcelllayout.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderer.h:
+
+/usr/include/gtk-2.0/gtk/gtkcelleditable.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeviewcolumn.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodel.h:
+
+/usr/include/gtk-2.0/gtk/gtktreesortable.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrendererpixbuf.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderertext.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderertoggle.h:
+
+/usr/include/gtk-2.0/gtk/gtkcheckbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktogglebutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcheckmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkclipboard.h:
+
+/usr/include/gtk-2.0/gtk/gtkselection.h:
+
+/usr/include/gtk-2.0/gtk/gtkclist.h:
+
+/usr/include/gtk-2.0/gtk/gtkhscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkrange.h:
+
+/usr/include/gtk-2.0/gtk/gtkvscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorsel.h:
+
+/usr/include/gtk-2.0/gtk/gtkdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkvbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorseldialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkcombo.h:
+
+/usr/include/gtk-2.0/gtk/gtkhbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkcombobox.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeview.h:
+
+/usr/include/gtk-2.0/gtk/gtkdnd.h:
+
+/usr/include/gtk-2.0/gtk/gtkcomboboxentry.h:
+
+/usr/include/gtk-2.0/gtk/gtkctree.h:
+
+/usr/include/gtk-2.0/gtk/gtkcurve.h:
+
+/usr/include/gtk-2.0/gtk/gtkdrawingarea.h:
+
+/usr/include/gtk-2.0/gtk/gtkeditable.h:
+
+/usr/include/gtk-2.0/gtk/gtkentry.h:
+
+/usr/include/gtk-2.0/gtk/gtkimcontext.h:
+
+/usr/include/gtk-2.0/gtk/gtkentrycompletion.h:
+
+/usr/include/gtk-2.0/gtk/gtkliststore.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodelfilter.h:
+
+/usr/include/gtk-2.0/gtk/gtkeventbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkexpander.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilesel.h:
+
+/usr/include/gtk-2.0/gtk/gtkfixed.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooserdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooser.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilefilter.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooserwidget.h:
+
+/usr/include/gtk-2.0/gtk/gtkfontbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkfontsel.h:
+
+/usr/include/gtk-2.0/gtk/gtkgamma.h:
+
+/usr/include/gtk-2.0/gtk/gtkgc.h:
+
+/usr/include/gtk-2.0/gtk/gtkhandlebox.h:
+
+/usr/include/gtk-2.0/gtk/gtkhbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkhpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkhruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkhscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkhseparator.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparator.h:
+
+/usr/include/gtk-2.0/gtk/gtkiconfactory.h:
+
+/usr/include/gtk-2.0/gtk/gtkicontheme.h:
+
+/usr/include/gtk-2.0/gtk/gtkimage.h:
+
+/usr/include/gtk-2.0/gtk/gtkimagemenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkimcontextsimple.h:
+
+/usr/include/gtk-2.0/gtk/gtkimmulticontext.h:
+
+/usr/include/gtk-2.0/gtk/gtkinputdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkinvisible.h:
+
+/usr/include/gtk-2.0/gtk/gtklayout.h:
+
+/usr/include/gtk-2.0/gtk/gtklist.h:
+
+/usr/include/gtk-2.0/gtk/gtklistitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkmain.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenubar.h:
+
+/usr/include/gtk-2.0/gtk/gtkmessagedialog.h:
+
+/usr/include/gtk-2.0/gtk/gtknotebook.h:
+
+/usr/include/gtk-2.0/gtk/gtkoldeditable.h:
+
+/usr/include/gtk-2.0/gtk/gtkoptionmenu.h:
+
+/usr/include/gtk-2.0/gtk/gtkpixmap.h:
+
+/usr/include/gtk-2.0/gtk/gtkplug.h:
+
+/usr/include/gtk-2.0/gtk/gtksocket.h:
+
+/usr/include/gtk-2.0/gtk/gtkpreview.h:
+
+/usr/include/gtk-2.0/gtk/gtkprogress.h:
+
+/usr/include/gtk-2.0/gtk/gtkprogressbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkradioaction.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggleaction.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiobutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiomenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiotoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktooltips.h:
+
+/usr/include/gtk-2.0/gtk/gtkscrolledwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkviewport.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparatormenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparatortoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtksizegroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkspinbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkstatusbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkstock.h:
+
+/usr/include/gtk-2.0/gtk/gtktable.h:
+
+/usr/include/gtk-2.0/gtk/gtktearoffmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktext.h:
+
+/usr/include/gtk-2.0/gtk/gtktextbuffer.h:
+
+/usr/include/gtk-2.0/gtk/gtktexttagtable.h:
+
+/usr/include/gtk-2.0/gtk/gtktexttag.h:
+
+/usr/include/gtk-2.0/gtk/gtktextiter.h:
+
+/usr/include/gtk-2.0/gtk/gtktextchild.h:
+
+/usr/include/gtk-2.0/gtk/gtktextmark.h:
+
+/usr/include/gtk-2.0/gtk/gtktextview.h:
+
+/usr/include/gtk-2.0/gtk/gtktipsquery.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbar.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktree.h:
+
+/usr/include/gtk-2.0/gtk/gtktreednd.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodelsort.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeselection.h:
+
+/usr/include/gtk-2.0/gtk/gtktreestore.h:
+
+/usr/include/gtk-2.0/gtk/gtkuimanager.h:
+
+/usr/include/gtk-2.0/gtk/gtkvbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkversion.h:
+
+/usr/include/gtk-2.0/gtk/gtkvpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkvruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkvscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkvseparator.h:
+
+/usr/include/stdio.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/include/bits/wchar.h:
+
+/usr/include/gconv.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/bits/sched.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+../../../../ltt/ltt.h:
+
+../../../../ltt/time.h:
+
+../../../../ltt/compiler.h:
+
+../../../../ltt/event.h:
+
+../../../../ltt/type.h:
+
+../../../../ltt/trace.h:
+
+../../../../ltt/facility.h:
+
+../../../../lttv/lttv/module.h:
+
+../../../../lttv/lttv/hook.h:
+
+../../../../lttv/lttv/tracecontext.h:
+
+../../../../lttv/lttv/traceset.h:
+
+../../../../lttv/lttv/attribute.h:
+
+../../../../lttv/lttv/iattribute.h:
+
+../../../../lttv/lttv/state.h:
+
+../../../../lttv/lttv/filter.h:
+
+../../../../lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h:
+
+../../../../lttv/lttv/stats.h:
+
+../../../../lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h:
+
+hDiskPerformanceInsert.xpm:
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/.deps/libsysteminfo.la.Plo b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/.deps/libsysteminfo.la.Plo
new file mode 100644 (file)
index 0000000..9ce06a8
--- /dev/null
@@ -0,0 +1 @@
+# dummy
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/Makefile.am
new file mode 100644 (file)
index 0000000..3396bc6
--- /dev/null
@@ -0,0 +1,38 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 Mathieu Desnoyers
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+# MA 02111-1307, USA.
+
+
+
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libdiskperformance.la
+libdiskperformance_la_LDFLAGS = -module
+libdiskperformance_la_SOURCES = diskperformance.c
+
+EXTRA_DIST = \
+               hDiskPerformanceInsert.xpm
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/diskperformance.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/diskperformance.c
new file mode 100644 (file)
index 0000000..cee71c6
--- /dev/null
@@ -0,0 +1,638 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2005 Peter Ho
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+#include <math.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/filter.h>
+#include <lttvwindow/lttvwindow.h>
+#include <ltt/time.h>
+
+#include "hDiskPerformanceInsert.xpm" 
+
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+#define NO_ITEMS 0
+
+enum{
+  DISKNAME_COLUMN,
+  BYTES_RD_COLUMN,
+  BYTES_RD_SEC_COLUMN,
+  NUM_RD_COLUMN,
+  BYTES_WR_COLUMN,
+  BYTES_WR_SEC_COLUMN,
+  NUM_WR_COLUMN,
+  N_COLUMNS
+};
+enum operation_t {
+     LTTV_READ_OPERATION = 1,  
+     LTTV_WRITE_OPERATION
+};
+
+typedef struct _DiskPerformanceData {
+
+  Tab       * tab;
+  LttvHooks  * event_hooks;
+  LttvHooks  * hooks_trace_after;
+  LttvHooks  * hooks_trace_before;
+  TimeWindow   time_window;            // time window
+      
+  GtkWidget * scroll_win;
+  /* Model containing list data */
+  GtkListStore *store_m;
+  GtkWidget *hbox_v;
+  /* Widget to display the data in a columned list */
+  GtkWidget *tree_v;
+  /* Selection handler */
+  GtkTreeSelection *select_c;
+  
+  GArray *disk_array; 
+  
+} DiskPerformanceData;
+
+
+typedef struct _lttv_block { 
+       guint major_number;
+       guint minor_number;
+       guint size;
+} lttv_block;
+
+typedef struct _lttv_total_block {
+       char diskname[10];
+       guint64 total_bytes_read;
+       guint num_read_operations;
+       guint64 total_bytes_written;
+       guint num_write_operations;
+        
+} lttv_total_block;
+
+GSList *g_disk_data_list = NULL ;
+
+DiskPerformanceData *disk_performance_data(Tab *tab);
+static void disk_destroy_walk(gpointer data, gpointer user_data);
+static gboolean parse_event(void *hook_data, void *call_data);
+static gboolean disk_show(void *hook_data, void *call_data);
+static gboolean trace_header(void *hook_data, void *call_data);
+static gboolean disk_update_time_window(void * hook_data, void * call_data);
+static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data);
+static void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data);
+static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data);
+static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data);
+static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
+static void request_event(  DiskPerformanceData *disk_performance);
+void gui_disperformance_free(DiskPerformanceData *event_viewer_data);
+static void get_event_detail(LttEvent *e, LttField *f, GString * s, lttv_block* disk_data);
+static char * major_minor_to_diskname( lttv_block* disk_data); 
+static void sum_data(char* diskname, guint size, enum operation_t opt, GArray *disk_array);
+
+GtkWidget *disk_performance(Tab * tab){
+ DiskPerformanceData* disk_data = disk_performance_data(tab);
+ if(disk_data)
+    return disk_data->hbox_v;
+ else 
+    return NULL; 
+
+}
+
+DiskPerformanceData *disk_performance_data(Tab *tab){
+  
+  LttTime end;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  DiskPerformanceData* disk_data = g_new(DiskPerformanceData,1) ;
+  
+  g_info("enter disk_performance_data \n");
+  
+  disk_data->tab = tab;
+  disk_data->time_window  =  lttvwindow_get_time_window(tab);
+  
+  disk_data->disk_array = g_array_new(FALSE, FALSE, sizeof(lttv_total_block ));
+  
+  lttvwindow_register_time_window_notify(tab,
+                                         disk_update_time_window,
+                                         disk_data);   
+                                               
+  disk_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (disk_data->scroll_win);
+  gtk_scrolled_window_set_policy(
+      GTK_SCROLLED_WINDOW(disk_data->scroll_win), 
+      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC/*GTK_POLICY_NEVER*/);
+
+  /* Create a model for storing the data list */
+  disk_data->store_m = gtk_list_store_new (
+    N_COLUMNS,      /* Total number of columns     */
+    G_TYPE_STRING,     /* Diskname                 */ // to change from INT to string later 
+    G_TYPE_INT64,     /* Bytes read                */
+    G_TYPE_INT64,     /* Bytes read/sec                   */
+    G_TYPE_INT,
+    G_TYPE_INT64,    /*  bytes written               */
+    G_TYPE_INT64,    /*  bytes written/sec            */
+    G_TYPE_INT
+    );  
+  disk_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (disk_data->store_m));
+  g_signal_connect (G_OBJECT (disk_data->tree_v), "size-allocate",
+        G_CALLBACK (tree_v_size_allocate_cb),
+        disk_data);
+  g_signal_connect (G_OBJECT (disk_data->tree_v), "size-request",
+        G_CALLBACK (tree_v_size_request_cb),
+        disk_data);  
+  g_signal_connect (G_OBJECT (disk_data->tree_v), "cursor-changed",
+        G_CALLBACK (tree_v_cursor_changed_cb),
+        disk_data);
+  g_signal_connect (G_OBJECT (disk_data->tree_v), "move-cursor",
+        G_CALLBACK (tree_v_move_cursor_cb),
+        disk_data);
+  
+  g_object_unref (G_OBJECT (disk_data->store_m));
+    
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("DiskName",
+                 renderer,
+                 "text", DISKNAME_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("BytesRead",
+                 renderer,
+                 "text", BYTES_RD_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column,  220);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("BytesRead/sec",
+                 renderer,
+                 "text", BYTES_RD_SEC_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 220);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("NumReadOperations",
+                 renderer,
+                 "text",NUM_RD_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 220);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("BytesWritten",
+                 renderer,
+                 "text", BYTES_WR_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 145);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("BytesWritten/sec",
+                 renderer,
+                 "text", BYTES_WR_SEC_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 220);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+  
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("NumWriteOperations",
+                 renderer,
+                 "text",NUM_WR_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 145);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
+  
+  disk_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (disk_data->tree_v));
+  gtk_tree_selection_set_mode (disk_data->select_c, GTK_SELECTION_SINGLE);
+  g_signal_connect (G_OBJECT (disk_data->select_c), "changed",
+                   G_CALLBACK (tree_selection_changed_cb),
+                    disk_data);
+  
+  gtk_container_add (GTK_CONTAINER (disk_data->scroll_win), disk_data->tree_v);
+
+  disk_data->hbox_v = gtk_hbox_new(0, 0);
+  gtk_box_pack_start(GTK_BOX(disk_data->hbox_v), disk_data->scroll_win, TRUE, TRUE, 0);
+  
+  gtk_widget_show(disk_data->hbox_v);
+  gtk_widget_show(disk_data->tree_v);
+   
+  g_disk_data_list = g_slist_append(g_disk_data_list, disk_data);
+  g_object_set_data_full(G_OBJECT(disk_data->hbox_v),
+      "disk_data",
+       disk_data,
+      (GDestroyNotify)gui_disperformance_free);
+  
+  request_event(disk_data);
+  return disk_data;
+}
+  
+
+static gboolean disk_show(void *hook_data, void *call_data){
+  
+  guint i;
+  lttv_total_block element; 
+  GtkTreeIter    iter;
+  LttTime time_interval;
+  guint64 time_interval_64;
+  guint64 temp_variable; 
+  guint64 bytes_read_per_sec, bytes_written_per_sec;
+  g_info(" diskperformance: disk_show() \n");
+  DiskPerformanceData *disk_performance = (DiskPerformanceData *)hook_data;
+  GArray *disk_array = disk_performance->disk_array;
+  time_interval =  ltt_time_sub(disk_performance->time_window.end_time, disk_performance->time_window.start_time); 
+  
+  time_interval_64  = time_interval.tv_sec;
+  time_interval_64 *= NANOSECONDS_PER_SECOND;
+  time_interval_64 += time_interval.tv_nsec;
+  gtk_list_store_clear(disk_performance->store_m);
+  for(i = 0; i < disk_array->len; i++){  
+    
+    element = g_array_index(disk_array,lttv_total_block,i);  
+    temp_variable =  element.total_bytes_read * NANOSECONDS_PER_SECOND;
+    bytes_read_per_sec = (guint64) temp_variable / time_interval_64;
+    
+    temp_variable =  element.total_bytes_written * NANOSECONDS_PER_SECOND;
+    bytes_written_per_sec  = (guint64) temp_variable / time_interval_64;
+    
+    gtk_list_store_append (disk_performance->store_m, &iter);
+    gtk_list_store_set (disk_performance->store_m, &iter,
+      DISKNAME_COLUMN, element.diskname,
+      BYTES_RD_COLUMN, element.total_bytes_read,
+      BYTES_RD_SEC_COLUMN,bytes_read_per_sec,
+      NUM_RD_COLUMN, element.num_read_operations,
+      BYTES_WR_COLUMN, element.total_bytes_written,
+      BYTES_WR_SEC_COLUMN, bytes_written_per_sec,
+      NUM_WR_COLUMN, element.num_write_operations,
+      -1); 
+       
+  }
+  if(disk_performance->disk_array->len) 
+    g_array_remove_range (disk_performance->disk_array,0,disk_performance->disk_array->len);
+  return FALSE;
+}
+
+static gboolean trace_header(void *hook_data, void *call_data){
+  return FALSE;
+}
+
+void request_event(DiskPerformanceData *disk_performance){
+
+  disk_performance->event_hooks = lttv_hooks_new();
+  lttv_hooks_add(disk_performance->event_hooks, parse_event, disk_performance, LTTV_PRIO_DEFAULT);
+
+  disk_performance->hooks_trace_after = lttv_hooks_new();
+  lttv_hooks_add(disk_performance->hooks_trace_after, disk_show, disk_performance, LTTV_PRIO_DEFAULT);
+
+  disk_performance->hooks_trace_before = lttv_hooks_new();
+  lttv_hooks_add(disk_performance->hooks_trace_before, trace_header, disk_performance, LTTV_PRIO_DEFAULT);
+
+  EventsRequest *events_request = g_new(EventsRequest, 1);
+  events_request->owner       = disk_performance;
+  events_request->viewer_data = disk_performance;
+  events_request->servicing   = FALSE;
+  events_request->start_time  = disk_performance->time_window.start_time;
+  events_request->start_position  = NULL;
+  events_request->stop_flag       = FALSE;
+  events_request->end_time        = disk_performance->time_window.end_time;
+  events_request->num_events      = G_MAXUINT;
+  events_request->end_position     = NULL;
+  events_request->trace           = 0;
+  events_request->hooks           = NULL;
+  events_request->before_chunk_traceset = NULL;
+  events_request->before_chunk_trace    = disk_performance->hooks_trace_before;
+  events_request->before_chunk_tracefile= NULL;
+  events_request->event                        = disk_performance->event_hooks;
+  events_request->event_by_id          = NULL;
+  events_request->after_chunk_tracefile = NULL;
+  events_request->after_chunk_trace     = NULL;
+  events_request->after_chunk_traceset = NULL;
+  events_request->before_request       = NULL;
+  events_request->after_request                = disk_performance->hooks_trace_after;
+
+  lttvwindow_events_request(disk_performance->tab, events_request);
+
+}
+
+static gboolean disk_update_time_window(void * hook_data, void * call_data){
+     
+  DiskPerformanceData *disk_performance = (DiskPerformanceData *) hook_data;
+  const TimeWindowNotifyData *time_window_nofify_data =  ((const TimeWindowNotifyData *)call_data);
+  disk_performance->time_window = *time_window_nofify_data->new_time_window;
+  /*
+  printf("end_time: %ld.%ld\n",    disk_performance->time_window.end_time.tv_sec,disk_performance->time_window.end_time.tv_nsec);
+  */
+  Tab *tab = disk_performance->tab;
+  lttvwindow_events_request_remove_all(tab, disk_performance);
+  request_event( disk_performance);  
+   
+  
+    return FALSE;
+}
+
+void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data){
+  g_info("enter tree_v_size_allocate_cb\n");
+}
+
+void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data){
+
+}
+
+static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data){
+
+}
+
+static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data){
+}
+static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data){
+
+}
+void gui_disperformance_free(DiskPerformanceData  *eventdata){ 
+  Tab *tab = eventdata->tab;
+  g_info("disperformance.c : gui_disperformance_free, %p", eventdata);
+  g_info("%p, %p", eventdata, tab);
+  if(tab != NULL)
+  {
+     g_array_free (eventdata->disk_array, TRUE);
+     
+     lttvwindow_unregister_time_window_notify(tab,
+        disk_update_time_window,
+        eventdata);
+       
+     lttvwindow_events_request_remove_all(eventdata->tab,
+                                          eventdata);  
+     g_disk_data_list = g_slist_remove(g_disk_data_list, eventdata);                                     
+  }
+  g_free(eventdata);                                     
+  g_info("disperformance.c : gui_disperformance_free end, %p", eventdata);
+}
+  
+
+static char * major_minor_to_diskname( lttv_block* disk_data){
+  if (disk_data->major_number == 3 && disk_data->minor_number == 0)
+       return "hda";
+  if (disk_data->major_number == 4 && disk_data->minor_number == 0)    
+       return "hdb";
+}
+
+static void sum_data(char* diskname, guint size, enum operation_t operation, GArray *disk_array){
+  
+  lttv_total_block data;
+  lttv_total_block *element; 
+  guint i;
+  gboolean  notFound = FALSE;
+  
+  memset ((void*)&data, 0,sizeof(lttv_total_block));
+   
+  if(disk_array->len == NO_ITEMS){
+       strcpy(data.diskname, diskname);
+       if(operation == LTTV_READ_OPERATION){
+          data.total_bytes_read = size;
+          data.num_read_operations++;
+       }
+       else{
+          data.total_bytes_written = size;
+          data.num_write_operations ++;
+       }
+       g_array_append_val (disk_array, data);
+  } 
+  else{
+       for(i = 0; i < disk_array->len; i++){
+           element = &g_array_index(disk_array,lttv_total_block,i);
+           if(strcmp(element->diskname,diskname) == 0){
+               if(operation == LTTV_READ_OPERATION){
+                 element->num_read_operations++;       
+                 element->total_bytes_read += size;
+               }
+               else{
+                 element->num_write_operations ++;
+                 element->total_bytes_written += size;
+               }
+               notFound = TRUE;
+           }
+       }
+       if(!notFound){
+           strcpy(data.diskname, diskname);
+           if(operation == LTTV_READ_OPERATION){
+             data.total_bytes_read = size;
+             data.num_read_operations ++;
+           }
+           else{
+             data.total_bytes_written = size;
+             data.num_write_operations ++;
+           }
+           g_array_append_val (disk_array, data);
+       }       
+  }
+}
+
+static void  get_event_detail(LttEvent *e, LttField *f, GString * s, lttv_block* disk_data){
+  LttType *type;
+  LttField *element;
+  //char *name;
+  GQuark name;
+  int nb, i;
+  static int count;
+  type = ltt_field_type(f);
+  switch(ltt_type_class(type)) {
+    case LTT_INT:
+      g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f));
+      break;
+      
+    case LTT_UINT:
+      g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f));
+      break;
+
+    case LTT_FLOAT:
+      g_string_append_printf(s, " %g", ltt_event_get_double(e,f));
+      break;
+
+    case LTT_STRING:
+      g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f));
+      break;
+
+    case LTT_ENUM:
+      g_string_append_printf(s, " %s", ltt_enum_string_get(type,
+          ltt_event_get_unsigned(e,f)-1));
+      break;
+
+    case LTT_ARRAY:
+    case LTT_SEQUENCE:
+      g_string_append_printf(s, " {");
+      nb = ltt_event_field_element_number(e,f);
+      element = ltt_field_element(f);
+      for(i = 0 ; i < nb ; i++) {
+        ltt_event_field_element_select(e,f,i);
+        get_event_detail(e, element, s, disk_data);
+      }
+      g_string_append_printf(s, " }");
+      break;
+
+    case LTT_STRUCT:
+      g_string_append_printf(s, " {");
+      nb = ltt_type_member_number(type);
+      for(i = 0 ; i < nb ; i++) {
+        element = ltt_field_member(f,i);
+        ltt_type_member_type(type, i, &name);
+        g_string_append_printf(s, " %s = ", name);        
+       if(i== 0)
+         disk_data->major_number = ltt_event_get_long_unsigned(e, element); 
+        if(i== 1)
+         disk_data->minor_number = ltt_event_get_long_unsigned(e, element); 
+       if(i==2)
+         disk_data->size = ltt_event_get_long_unsigned(e, element); 
+      }
+      g_string_append_printf(s, " }");
+      break;
+
+    case LTT_UNION:
+      g_string_append_printf(s, " {");
+      nb = ltt_type_member_number(type);
+      for(i = 0 ; i < nb ; i++) {
+        element = ltt_field_member(f,i);
+        ltt_type_member_type(type, i, &name);
+        g_string_append_printf(s, " %s = ", name);        
+       get_event_detail(e, element, s, disk_data);
+      }
+      g_string_append_printf(s, " }");
+      break;
+
+  }
+  
+}
+
+gboolean parse_event(void *hook_data, void *call_data){
+
+  static LttTime time_entry, previous_time, event_time; 
+  LttEvent *e;
+  LttField *field;
+  LttEventType *event_type;
+  gint i;
+  unsigned cpu_id;
+  lttv_block block_read, block_write;
+  char *diskname;
+  gboolean  notFound = FALSE;
+  DiskPerformanceData * disk_performance  = (DiskPerformanceData *)hook_data;
+  GArray *disk_array = disk_performance->disk_array; // pho
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+  
+  //e = tfc->e;
+  e = ltt_tracefile_get_event(tfc->tf); 
+  previous_time = event_time;
+  field = ltt_event_field(e);
+  event_time = ltt_event_time(e);
+  event_type = ltt_event_eventtype(e);
+  cpu_id = ltt_event_cpu_id(e);
+  GString * detail_event = g_string_new("");
+  
+  if ((ltt_time_compare(event_time,disk_performance->time_window.start_time) == TRUE) &&    
+     (ltt_time_compare(disk_performance->time_window.end_time,event_time) == TRUE)){
+     if (strcmp( g_quark_to_string(ltt_eventtype_name(event_type)),"block_read") == 0) {       
+          get_event_detail(e, field, detail_event, &block_read); 
+          diskname = major_minor_to_diskname(&block_read);
+          sum_data(diskname, block_read.size,LTTV_READ_OPERATION, disk_array);
+           
+     }
+     if (strcmp( g_quark_to_string(ltt_eventtype_name(event_type)),"block_write") == 0) {      
+          get_event_detail(e, field, detail_event, &block_write); 
+         diskname = major_minor_to_diskname(&block_write);
+         sum_data(diskname, block_write.size,LTTV_WRITE_OPERATION, disk_array);
+     }
+          
+  }
+   g_string_free(detail_event, TRUE);
+   return FALSE;
+}
+
+void disk_destructor_full(DiskPerformanceData *disk_data)
+{
+
+  if(GTK_IS_WIDGET(disk_data->hbox_v))
+    gtk_widget_destroy(disk_data->hbox_v);
+
+}
+
+static void disk_destroy_walk(gpointer data, gpointer user_data)
+{
+  g_info("Walk destroy GUI disk performance Viewer");
+  disk_destructor_full((DiskPerformanceData*)data);
+}
+
+static void init()
+{
+  
+  g_info("Init diskPerformance.c");
+ lttvwindow_register_constructor("diskperformance",
+                                  "/",
+                                  "Insert Disk Performance",
+                                  hDiskPerformanceInsert_xpm,
+                                  "Insert Disk Performance",
+                                  disk_performance);
+  
+}
+
+
+static void destroy()
+{
+  g_info("Destroy diskPerformance");
+  g_slist_foreach(g_disk_data_list, disk_destroy_walk, NULL );
+  g_slist_free(g_disk_data_list);
+  
+  lttvwindow_unregister_constructor(disk_performance);
+  
+}
+
+
+LTTV_MODULE("diskperformance", "disk info view", \
+           "Produce disk I/O performance", \
+           init, destroy, "lttvwindow") 
+           
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/hDiskPerformanceInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/hDiskPerformanceInsert.xpm
new file mode 100644 (file)
index 0000000..5eb65b5
--- /dev/null
@@ -0,0 +1,27 @@
+/* XPM */
+static char * hDiskPerformanceInsert_xpm[] = {
+"22 22 2 1",
+"      c None",
+".     c #800080",
+"                      ",
+"                      ",
+"     ..........       ",
+"    .............     ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"   ..           ..    ",
+"    .............     ",
+"     ..........       ",
+"                      ",
+"                      "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/liste.txt b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/diskperformance/liste.txt
new file mode 100644 (file)
index 0000000..20bb40b
--- /dev/null
@@ -0,0 +1,3 @@
+3      0       hda
+4      0       hdb
+6      0       hdc
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/Makefile.am
new file mode 100644 (file)
index 0000000..25fc978
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libguifilter.la
+libguifilter_la_LDFLAGS = -module
+libguifilter_la_SOURCES = filter.c
+
+EXTRA_DIST = \
+    hGuiFilterInsert.xpm
+    
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/filter.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/filter.c
new file mode 100644 (file)
index 0000000..8d1232b
--- /dev/null
@@ -0,0 +1,681 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2005 Simon Bouvier-Zappa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/filter.h>
+
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+
+#include "hGuiFilterInsert.xpm"
+
+
+GSList *g_filter_list = NULL ;
+
+/*! \file lttv/modules/gui/filter/filter.c
+ *  \brief Graphic filter interface.
+ *
+ *  The gui filter facility gives the user an easy to use 
+ *  basic interface to construct and modify at will a filter 
+ *  expression.  User may either decide to write it himself in 
+ *  expression text entry or add simple expressions using the 
+ *  many choices boxes.
+ *  
+ *  \note The version of gtk-2.0 currently installed on 
+ *  my desktop misses some function of the newer 
+ *  gtk+ api.  For the time being, I'll use the older api 
+ *  to keep compatibility with most systems.
+ */
+
+typedef struct _FilterViewerData FilterViewerData;
+typedef struct _FilterViewerDataLine FilterViewerDataLine;
+
+/*
+ * Prototypes
+ */
+GtkWidget *guifilter_get_widget(FilterViewerData *fvd);
+FilterViewerData *gui_filter(Tab *tab);
+void gui_filter_destructor(FilterViewerData *fvd);
+FilterViewerDataLine* gui_filter_add_line(FilterViewerData *fvd);
+void gui_filter_line_set_visible(FilterViewerDataLine *fvdl, gboolean v);
+void gui_filter_line_reset(FilterViewerDataLine *fvdl);
+GtkWidget* h_guifilter(Tab *tab);
+void filter_destroy_walk(gpointer data, gpointer user_data);
+  
+/*
+ * Callback functions
+ */
+void callback_process_button(GtkWidget *widget, gpointer data);
+gboolean callback_enter_check(GtkWidget *widget,
+    GdkEventKey *event,
+    gpointer user_data);
+void callback_add_button(GtkWidget *widget, gpointer data);
+void callback_logical_op_box(GtkWidget *widget, gpointer data);
+void callback_expression_field(GtkWidget *widget, gpointer data);
+
+/**
+ *  @struct _FilterViewerDataLine
+ *
+ *  @brief Defines a simple expression
+ *  This structures defines a simple
+ *  expression whithin the main filter 
+ *  viewer data
+ */
+struct _FilterViewerDataLine {
+  int row;                            /**< row number */
+  gboolean visible;                   /**< visible state */
+  GtkWidget *f_not_op_box;            /**< '!' operator (GtkComboBox) */
+  GtkWidget *f_logical_op_box;        /**< '&,|,^' operators (GtkComboBox) */
+  GtkWidget *f_field_box;             /**< field types (GtkComboBox) */
+  GtkWidget *f_math_op_box;           /**< '>,>=,<,<=,=,!=' operators (GtkComboBox) */
+  GtkWidget *f_value_field;           /**< expression's value (GtkComboBox) */
+};
+
+/**
+ *  @struct _FilterViewerData
+ *  
+ *  @brief Main structure of gui filter
+ *  Main struct for the filter gui module
+ */
+struct _FilterViewerData {
+  Tab *tab;                             /**< current tab of module */
+
+  GtkWidget *f_window;                  /**< filter window */
+  
+  GtkWidget *f_main_box;                /**< main container */
+
+  GtkWidget *f_expression_field;        /**< entire expression (GtkEntry) */
+  GtkWidget *f_process_button;          /**< process expression button (GtkButton) */
+
+  GtkWidget *f_logical_op_junction_box; /**< linking operator box (GtkComboBox) */
+
+  int rows;                             /**< number of rows */
+  GPtrArray *f_lines;                   /**< array of FilterViewerDataLine */
+
+  GPtrArray *f_not_op_options;          /**< array of operators types for not_op box */
+  GPtrArray *f_logical_op_options;      /**< array of operators types for logical_op box */
+  GPtrArray *f_field_options;           /**< array of field types for field box */
+  GPtrArray *f_math_op_options;         /**< array of operators types for math_op box */
+  
+  GtkWidget *f_add_button;              /**< add expression to current expression (GtkButton) */
+};
+
+/**
+ *  @fn GtkWidget* guifilter_get_widget(FilterViewerData*)
+ * 
+ *  This function returns the current main widget 
+ *  used by this module
+ *  @param fvd the module struct
+ *  @return The main widget
+ */
+GtkWidget*
+guifilter_get_widget(FilterViewerData *fvd)
+{
+  return fvd->f_window;
+}
+
+/**
+ *  @fn FilterViewerData* gui_filter(Tab*)
+ * 
+ *  Constructor is used to create FilterViewerData data structure.
+ *  @param tab The tab structure used by the widget
+ *  @return The Filter viewer data created.
+ */
+FilterViewerData*
+gui_filter(Tab *tab)
+{
+  g_debug("filter::gui_filter()");
+
+  unsigned i;
+  GtkCellRenderer *renderer;
+  GtkTreeViewColumn *column;
+
+  FilterViewerData* fvd = g_new(FilterViewerData,1);
+
+  fvd->tab  = tab;
+
+//  lttvwindow_register_traceset_notify(fvd->tab,
+//                                      filter_traceset_changed,
+//                                     filter_viewer_data);
+//  request_background_data(filter_viewer_data);
+  /*
+   * Initiating items for
+   * combo boxes
+   */
+  fvd->f_not_op_options = g_ptr_array_new();
+  g_ptr_array_add(fvd->f_not_op_options,(gpointer) g_string_new(""));
+  g_ptr_array_add(fvd->f_not_op_options,(gpointer) g_string_new("!"));
+  
+  fvd->f_logical_op_options = g_ptr_array_new(); //g_array_new(FALSE,FALSE,sizeof(gchar));
+  g_ptr_array_add(fvd->f_logical_op_options,(gpointer) g_string_new(""));
+  g_ptr_array_add(fvd->f_logical_op_options,(gpointer) g_string_new("&"));
+  g_ptr_array_add(fvd->f_logical_op_options,(gpointer) g_string_new("|"));
+  g_ptr_array_add(fvd->f_logical_op_options,(gpointer) g_string_new("!"));
+  g_ptr_array_add(fvd->f_logical_op_options,(gpointer) g_string_new("^"));
+
+  fvd->f_field_options = g_ptr_array_new(); //g_array_new(FALSE,FALSE,16);
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new(""));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("event.name"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("event.facility"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("event.category"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("event.time"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("event.tsc"));
+  /*
+   * TODO: Add core.xml fields here !
+   */
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("tracefile.name"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("trace.name"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.process_name"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.pid"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.ppid"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.creation_time"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.insertion_time"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.execution_mode"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.execution_submode"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.process_status"));
+  g_ptr_array_add(fvd->f_field_options,(gpointer) g_string_new("state.cpu"));
+  
+  fvd->f_math_op_options = g_ptr_array_new(); //g_array_new(FALSE,FALSE,7);  
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new(""));
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new("="));
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new("!="));
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new("<"));
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new("<="));
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new(">"));
+  g_ptr_array_add(fvd->f_math_op_options,(gpointer) g_string_new(">="));
+  
+
+  fvd->f_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(fvd->f_window), "LTTV Filter");
+  gtk_window_set_transient_for(GTK_WINDOW(fvd->f_window),
+      GTK_WINDOW(main_window_get_widget(tab)));
+  gtk_window_set_destroy_with_parent(GTK_WINDOW(fvd->f_window), TRUE);
+
+  /* 
+   * Initiating GtkTable layout 
+   * starts with 2 rows and 5 columns and 
+   * expands when expressions added
+   */
+  fvd->f_main_box = gtk_table_new(3,7,FALSE);
+  gtk_table_set_row_spacings(GTK_TABLE(fvd->f_main_box),5);
+  gtk_table_set_col_spacings(GTK_TABLE(fvd->f_main_box),5);
+  
+  gtk_container_add(GTK_CONTAINER(fvd->f_window), GTK_WIDGET(fvd->f_main_box));
+  
+  /*
+   *  First half of the filter window
+   *  - textual entry of filter expression
+   *  - processing button
+   */
+  fvd->f_expression_field = gtk_entry_new(); //gtk_scrolled_window_new (NULL, NULL);
+  g_signal_connect (G_OBJECT(fvd->f_expression_field),
+      "key-press-event", G_CALLBACK (callback_enter_check), (gpointer)fvd);
+//  gtk_entry_set_text(GTK_ENTRY(fvd->f_expression_field),"state.cpu>0");
+  gtk_widget_show (fvd->f_expression_field);
+
+  g_signal_connect (G_OBJECT (fvd->f_expression_field), "changed",
+      G_CALLBACK (callback_expression_field), (gpointer) fvd); 
+
+  fvd->f_process_button = gtk_button_new_with_label("Process");
+  gtk_widget_show (fvd->f_process_button);
+  
+  g_signal_connect (G_OBJECT (fvd->f_process_button), "clicked",
+      G_CALLBACK (callback_process_button), (gpointer) fvd); 
+  
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_expression_field,0,6,0,1,GTK_FILL,GTK_FILL,0,0);
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_process_button,6,7,0,1,GTK_FILL,GTK_FILL,0,0);
+
+
+  
+  /*
+   *  Second half of the filter window
+   *  - combo boxes featuring filtering options added to the expression
+   */
+  fvd->f_add_button = gtk_button_new_with_label("Add Expression");
+  gtk_widget_show (fvd->f_add_button);
+
+  g_signal_connect (G_OBJECT (fvd->f_add_button), "clicked",
+      G_CALLBACK (callback_add_button), (gpointer) fvd);
+  
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_add_button,6,7,1,2,GTK_FILL,GTK_FILL,0,0);
+  
+  fvd->f_logical_op_junction_box = gtk_combo_box_new_text();
+  for(i=0;i<fvd->f_logical_op_options->len;i++) {
+    GString* s = g_ptr_array_index(fvd->f_logical_op_options,i);
+    gtk_combo_box_append_text(GTK_COMBO_BOX(fvd->f_logical_op_junction_box), s->str); 
+  }
+  gtk_combo_box_set_active(GTK_COMBO_BOX(fvd->f_logical_op_junction_box),0);
+  
+  //gtk_widget_show(fvd->f_logical_op_box);
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_logical_op_junction_box,0,1,1,2,GTK_SHRINK,GTK_FILL,0,0);
+
+  gtk_container_set_border_width(GTK_CONTAINER(fvd->f_main_box), 1);
+  
+  /* initialize a new line */
+  fvd->f_lines = g_ptr_array_new();
+  fvd->rows = 1;
+  FilterViewerDataLine* fvdl = gui_filter_add_line(fvd);
+  g_ptr_array_add(fvd->f_lines,(gpointer) fvdl);
+  
+  /* 
+   * show main container 
+   */
+  gtk_widget_show(fvd->f_main_box);
+  gtk_widget_show(fvd->f_window);
+  
+  
+  g_object_set_data_full(
+      G_OBJECT(guifilter_get_widget(fvd)),
+      "filter_viewer_data",
+      fvd,
+      (GDestroyNotify)gui_filter_destructor);
+
+  g_filter_list = g_slist_append(
+      g_filter_list,
+      fvd);
+  
+  return fvd;
+}
+
+/**
+ *  @fn FilterViewerDataLine* gui_filter_add_line(FilterViewerData*)
+ * 
+ *  Adds a filter option line on the module tab
+ *  @param fvd The filter module structure 
+ *  @return The line structure
+ */
+FilterViewerDataLine*
+gui_filter_add_line(FilterViewerData* fvd) {
+
+  FilterViewerDataLine* fvdl = g_new(FilterViewerDataLine,1);
+
+  unsigned i;
+  fvdl->row = fvd->rows;
+  fvdl->visible = TRUE;
+
+  fvdl->f_not_op_box = gtk_combo_box_new_text();
+  for(i=0;i<fvd->f_not_op_options->len;i++) {
+    GString* s = g_ptr_array_index(fvd->f_not_op_options,i);
+    gtk_combo_box_append_text(GTK_COMBO_BOX(fvdl->f_not_op_box), s->str);
+  }
+
+  fvdl->f_field_box = gtk_combo_box_new_text();
+  for(i=0;i<fvd->f_field_options->len;i++) {
+    GString* s = g_ptr_array_index(fvd->f_field_options,i);
+//    g_print("String field: %s\n",s->str);
+    gtk_combo_box_append_text(GTK_COMBO_BOX(fvdl->f_field_box), s->str);
+  }
+  
+  fvdl->f_math_op_box = gtk_combo_box_new_text();
+  for(i=0;i<fvd->f_math_op_options->len;i++) {
+    GString* s = g_ptr_array_index(fvd->f_math_op_options,i);
+    gtk_combo_box_append_text(GTK_COMBO_BOX(fvdl->f_math_op_box), s->str); 
+  }
+  
+  fvdl->f_value_field = gtk_entry_new();
+  fvdl->f_logical_op_box = gtk_combo_box_new_text();
+  for(i=0;i<fvd->f_logical_op_options->len;i++) {
+    GString* s = g_ptr_array_index(fvd->f_logical_op_options,i);
+    gtk_combo_box_append_text(GTK_COMBO_BOX(fvdl->f_logical_op_box), s->str); 
+  }
+  gtk_widget_set_events(fvdl->f_logical_op_box,
+      GDK_ENTER_NOTIFY_MASK |
+      GDK_LEAVE_NOTIFY_MASK |
+      GDK_FOCUS_CHANGE_MASK);
+
+  g_signal_connect (G_OBJECT (fvdl->f_logical_op_box), "changed",
+    G_CALLBACK (callback_logical_op_box), (gpointer) fvd); 
+
+  gui_filter_line_reset(fvdl);
+  gui_filter_line_set_visible(fvdl,TRUE);
+  
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_not_op_box,0,1,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_field_box,1,3,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_math_op_box,3,4,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_value_field,4,5,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
+  gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_logical_op_box,5,6,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
+  return fvdl;
+}
+
+/**
+ *  @fn void gui_filter_line_set_visible(FilterViewerDataLine*,gboolean)
+ *
+ *  Change visible state of current FilterViewerDataLine
+ *  @param fvdl pointer to the current FilterViewerDataLine
+ *  @param v TRUE: sets visible, FALSE: sets invisible
+ */
+void 
+gui_filter_line_set_visible(FilterViewerDataLine *fvdl, gboolean v) {
+
+  fvdl->visible = v;
+  if(v) {
+    gtk_widget_show(fvdl->f_not_op_box);
+    gtk_widget_show(fvdl->f_field_box);
+    gtk_widget_show(fvdl->f_math_op_box);
+    gtk_widget_show(fvdl->f_value_field);
+    gtk_widget_show(fvdl->f_logical_op_box);
+  } else {
+    gtk_widget_hide(fvdl->f_not_op_box);
+    gtk_widget_hide(fvdl->f_field_box);
+    gtk_widget_hide(fvdl->f_math_op_box);
+    gtk_widget_hide(fvdl->f_value_field);
+    gtk_widget_hide(fvdl->f_logical_op_box);
+ } 
+  
+}
+
+/**
+ *  @fn void gui_filter_line_reset(FilterViewerDataLine*)
+ *
+ *  Sets selections of all boxes in current FilterViewerDataLine 
+ *  to default value (0)
+ *  @param fvdl pointer to current FilterViewerDataLine
+ */
+void 
+gui_filter_line_reset(FilterViewerDataLine *fvdl) {
+
+  gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_not_op_box),0);
+  gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_field_box),0);
+  gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_math_op_box),0);
+  gtk_entry_set_text(GTK_ENTRY(fvdl->f_value_field),"");
+  gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_logical_op_box),0);
+}
+
+/**
+ *  @fn void gui_filter_destructor(FilterViewerData*)
+ * 
+ *  Destructor for the filter gui module
+ *  @param fvd The module structure
+ */
+void
+gui_filter_destructor(FilterViewerData *fvd)
+{
+  Tab *tab = fvd->tab;
+
+  /* May already been done by GTK window closing */
+  if(GTK_IS_WIDGET(guifilter_get_widget(fvd))){
+    g_info("widget still exists");
+  }
+//  if(tab != NULL) {
+//    lttvwindow_unregister_traceset_notify(fvd->tab,
+//                                          filter_traceset_changed,
+//                                          filter_viewer_data);
+//  }
+  lttvwindowtraces_background_notify_remove(fvd);
+  
+  g_filter_list = g_slist_remove(g_filter_list, fvd);
+  g_free(fvd);
+}
+
+
+/**
+ *  @fn GtkWidget* h_guifilter(Tab*)
+ * 
+ *  Filter Module's constructor hook
+ *
+ *  This constructor is given as a parameter to the menuitem and toolbar button
+ *  registration. It creates the list.
+ *  @param tab A pointer to the parent window.
+ *  @return The widget created.
+ */
+GtkWidget *
+h_guifilter(Tab *tab)
+{
+  FilterViewerData* f = gui_filter(tab) ;
+
+  return NULL;
+}
+
+/**
+ *  @fn static void init()
+ * 
+ *  This function initializes the Filter Viewer functionnality through the
+ *  gtkTraceSet API.
+ */
+static void init() {
+
+  lttvwindow_register_constructor("guifilter",
+                                  "/",
+                                  "Insert Filter Module",
+                                  hGuiFilterInsert_xpm,
+                                  "Insert Filter Module",
+                                  h_guifilter);
+}
+
+/**
+ *  @fn void filter_destroy_walk(gpointer,gpointer)
+ * 
+ *  Initiate the destruction of the current gui module
+ *  on the GTK Interface
+ */
+void 
+filter_destroy_walk(gpointer data, gpointer user_data)
+{
+  FilterViewerData *fvd = (FilterViewerData*)data;
+
+  g_debug("CFV.c : filter_destroy_walk, %p", fvd);
+
+  /* May already have been done by GTK window closing */
+  if(GTK_IS_WIDGET(guifilter_get_widget(fvd)))
+    gtk_widget_destroy(guifilter_get_widget(fvd));
+}
+
+/**
+ *  @fn static void destroy()
+ *  @brief plugin's destroy function
+ *
+ *  This function releases the memory reserved by the module and unregisters
+ *  everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+  g_slist_foreach(g_filter_list, filter_destroy_walk, NULL );
+  
+  lttvwindow_unregister_constructor(h_guifilter);
+  
+}
+
+/**
+ *  @fn void callback_process_button(GtkWidget*,gpointer)
+ * 
+ *  The Process Button callback function
+ *  @param widget The Button widget passed to the callback function
+ *  @param data Data sent along with the callback function
+ */
+void 
+callback_process_button(GtkWidget *widget, gpointer data) {
+
+  g_debug("callback_process_button(): Processing expression");
+  
+  FilterViewerData *fvd = (FilterViewerData*)data;
+  LttvFilter* filter;
+
+  if(strlen(gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field))) !=0) {
+    filter = lttv_filter_new();
+    GString* s = g_string_new(gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field)));
+    lttv_filter_append_expression(filter,s->str);
+    g_string_free(s,TRUE);
+    //SetFilter(fvd->tab,filter);
+  } else {
+    filter = NULL;
+  }
+  lttvwindow_report_filter(fvd->tab, filter);
+}
+
+gboolean callback_enter_check(GtkWidget *widget,
+    GdkEventKey *event,
+    gpointer user_data)
+{
+ g_debug("typed : %x", event->keyval);
+ switch(event->keyval) {
+   case GDK_Return:
+   case GDK_KP_Enter:
+   case GDK_ISO_Enter:
+   case GDK_3270_Enter:
+     callback_process_button(widget, user_data);
+     break;
+   default:
+     break;
+ }
+ return FALSE;
+}
+
+/**
+ *  @fn void callback_expression_field(GtkWidget*,gpointer)
+ * 
+ *  The Add Button callback function
+ *  @param widget The Button widget passed to the callback function
+ *  @param data Data sent along with the callback function
+ */
+void 
+callback_expression_field(GtkWidget *widget, gpointer data) {
+  
+  FilterViewerData *fvd = (FilterViewerData*)data;
+
+  if(strlen(gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field))) !=0) {
+    gtk_widget_show(fvd->f_logical_op_junction_box);
+  } else {
+    gtk_widget_hide(fvd->f_logical_op_junction_box);
+  }
+}
+
+
+/**
+ *  @fn void callback_add_button(GtkWidget*,gpointer)
+ * 
+ *  The Add Button callback function
+ *  @param widget The Button widget passed to the callback function
+ *  @param data Data sent along with the callback function
+ */
+void 
+callback_add_button(GtkWidget *widget, gpointer data) {
+
+  g_debug("callback_add_button(): processing simple expressions");
+
+  unsigned i;
+  
+  FilterViewerData *fvd = (FilterViewerData*)data;
+  FilterViewerDataLine *fvdl = NULL;
+  GString* a_filter_string = g_string_new("");
+
+  /*
+   * adding linking operator to 
+   * string
+   */
+  GString* s;
+  s = g_ptr_array_index(fvd->f_logical_op_options,gtk_combo_box_get_active(GTK_COMBO_BOX(fvd->f_logical_op_junction_box)));
+  g_string_append(a_filter_string,s->str);
+  gtk_combo_box_set_active(GTK_COMBO_BOX(fvd->f_logical_op_junction_box),0);
+
+  /* begin expression */
+  g_string_append_c(a_filter_string,'(');
+
+  /*
+   * For each simple expression, add the resulting string 
+   * to the filter string
+   *
+   * Each simple expression takes the following schema
+   * [not operator '!',' '] [field type] [math operator '<','<=','>','>=','=','!='] [value]
+   */
+  for(i=0;i<fvd->f_lines->len;i++) {
+    fvdl = (FilterViewerDataLine*)g_ptr_array_index(fvd->f_lines,i);
+    s = g_ptr_array_index(fvd->f_not_op_options,gtk_combo_box_get_active(GTK_COMBO_BOX(fvdl->f_not_op_box)));
+    g_string_append(a_filter_string,s->str);
+    
+    s = g_ptr_array_index(fvd->f_field_options,gtk_combo_box_get_active(GTK_COMBO_BOX(fvdl->f_field_box)));
+    g_string_append(a_filter_string,s->str);
+    
+    s = g_ptr_array_index(fvd->f_math_op_options,gtk_combo_box_get_active(GTK_COMBO_BOX(fvdl->f_math_op_box)));
+    g_string_append(a_filter_string,s->str);
+    
+    g_string_append(a_filter_string,gtk_entry_get_text(GTK_ENTRY(fvdl->f_value_field)));
+    
+    s = g_ptr_array_index(fvd->f_logical_op_options,gtk_combo_box_get_active(GTK_COMBO_BOX(fvdl->f_logical_op_box)));
+    g_string_append(a_filter_string,s->str);
+    
+    /*
+     * resetting simple expression lines
+     */
+    gui_filter_line_reset(fvdl);
+    if(i) gui_filter_line_set_visible(fvdl,FALSE); // Only keep the first line
+  }
+
+  /* end expression */
+  g_string_append_c(a_filter_string,')');
+
+  g_string_prepend(a_filter_string,gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field)));
+  gtk_entry_set_text(GTK_ENTRY(fvd->f_expression_field),a_filter_string->str);
+  
+}
+
+/**
+ *  @fn void callback_logical_op_box(GtkWidget*,gpointer)
+ * 
+ *  The logical op box callback function 
+ *  @param widget The Button widget passed to the callback function
+ *  @param data Data sent along with the callback function
+ */
+void 
+callback_logical_op_box(GtkWidget *widget, gpointer data) {
+  g_debug("callback_logical_op_box(): adding new simple expression");
+
+  FilterViewerData *fvd = (FilterViewerData*)data;
+  FilterViewerDataLine *fvdl = NULL;
+  
+  int i;
+  for(i=0;i<fvd->f_lines->len;i++) {
+    fvdl = (FilterViewerDataLine*)g_ptr_array_index(fvd->f_lines,i);
+    if(fvdl->f_logical_op_box == widget) {
+      if(gtk_combo_box_get_active(GTK_COMBO_BOX(fvdl->f_logical_op_box)) == 0) return;
+      if(i==fvd->f_lines->len-1) {  /* create a new line */
+        fvd->rows++;
+        FilterViewerDataLine* fvdl2 = gui_filter_add_line(fvd);
+        g_ptr_array_add(fvd->f_lines,(gpointer) fvdl2);
+      } else {
+        FilterViewerDataLine *fvdl2 = (FilterViewerDataLine*)g_ptr_array_index(fvd->f_lines,i+1);
+        if(!fvdl2->visible) gui_filter_line_set_visible(fvdl2,TRUE); 
+      }
+    }
+  }
+  
+}
+
+LTTV_MODULE("guifilter", "Filter window", \
+    "Graphical module that let user specify their filtering options", \
+    init, destroy, "lttvwindow")
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/hGuiFilterInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/filter/hGuiFilterInsert.xpm
new file mode 100644 (file)
index 0000000..2b3e7f8
--- /dev/null
@@ -0,0 +1,28 @@
+/* XPM */
+static char * hGuiFilterInsert_xpm[] = {
+"22 22 3 1",
+"      c None",
+".     c #000000",
+"r  c #FF0000",
+"                      ",
+"                      ",
+"      .....           ",
+"      ..  ..          ",
+"      ..   ..         ",
+"      ..    ..        ",
+"   rrr..     ..       ",
+"   rrr..      .       ",
+"      ..      ..      ",
+"      ..      ..      ",
+"      ..      ..rrr   ",
+"      ..      ..rrr   ",
+"      ..      ..      ",
+"      ..      ..      ",
+"   rrr..      .       ",
+"   rrr..     ..       ",
+"      ..    ..        ",
+"      ..   ..         ",
+"      ..  ..          ",
+"      .....           ",
+"                      ",
+"                      "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/.deps/interrupts.Plo b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/.deps/interrupts.Plo
new file mode 100644 (file)
index 0000000..7e126d1
--- /dev/null
@@ -0,0 +1,1044 @@
+interrupts.lo interrupts.o: interrupts.c /usr/include/math.h \
+  /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/gnu/stubs.h /usr/include/bits/huge_val.h \
+  /usr/include/bits/mathdef.h /usr/include/bits/mathcalls.h \
+  /usr/include/bits/mathinline.h /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/syslimits.h \
+  /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+  /usr/include/bits/posix2_lim.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/gtk-2.0/gtk/gtk.h /usr/include/gtk-2.0/gdk/gdk.h \
+  /usr/include/gtk-2.0/gdk/gdkcolor.h /usr/include/gtk-2.0/gdk/gdktypes.h \
+  /usr/include/pango-1.0/pango/pango.h \
+  /usr/include/pango-1.0/pango/pango-attributes.h \
+  /usr/include/pango-1.0/pango/pango-font.h \
+  /usr/include/pango-1.0/pango/pango-coverage.h \
+  /usr/include/pango-1.0/pango/pango-types.h \
+  /usr/include/glib-2.0/glib-object.h \
+  /usr/include/glib-2.0/gobject/gboxed.h \
+  /usr/include/glib-2.0/gobject/gtype.h \
+  /usr/include/glib-2.0/gobject/genums.h \
+  /usr/include/glib-2.0/gobject/gobject.h \
+  /usr/include/glib-2.0/gobject/gvalue.h \
+  /usr/include/glib-2.0/gobject/gparam.h \
+  /usr/include/glib-2.0/gobject/gclosure.h \
+  /usr/include/glib-2.0/gobject/gsignal.h \
+  /usr/include/glib-2.0/gobject/gmarshal.h \
+  /usr/include/glib-2.0/gobject/gparamspecs.h \
+  /usr/include/glib-2.0/gobject/gsourceclosure.h \
+  /usr/include/glib-2.0/gobject/gtypemodule.h \
+  /usr/include/glib-2.0/gobject/gtypeplugin.h \
+  /usr/include/glib-2.0/gobject/gvaluearray.h \
+  /usr/include/glib-2.0/gobject/gvaluetypes.h \
+  /usr/include/pango-1.0/pango/pango-break.h \
+  /usr/include/pango-1.0/pango/pango-item.h \
+  /usr/include/pango-1.0/pango/pango-context.h \
+  /usr/include/pango-1.0/pango/pango-fontmap.h \
+  /usr/include/pango-1.0/pango/pango-fontset.h \
+  /usr/include/pango-1.0/pango/pango-engine.h \
+  /usr/include/pango-1.0/pango/pango-glyph.h \
+  /usr/include/pango-1.0/pango/pango-script.h \
+  /usr/include/pango-1.0/pango/pango-enum-types.h \
+  /usr/include/pango-1.0/pango/pango-layout.h \
+  /usr/include/pango-1.0/pango/pango-glyph-item.h \
+  /usr/include/pango-1.0/pango/pango-tabs.h \
+  /usr/lib/gtk-2.0/include/gdkconfig.h \
+  /usr/include/gtk-2.0/gdk/gdkcursor.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-features.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-loader.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-enum-types.h \
+  /usr/include/gtk-2.0/gdk/gdkdisplay.h \
+  /usr/include/gtk-2.0/gdk/gdkevents.h /usr/include/gtk-2.0/gdk/gdkdnd.h \
+  /usr/include/gtk-2.0/gdk/gdkinput.h \
+  /usr/include/gtk-2.0/gdk/gdkdrawable.h /usr/include/gtk-2.0/gdk/gdkgc.h \
+  /usr/include/gtk-2.0/gdk/gdkrgb.h \
+  /usr/include/gtk-2.0/gdk/gdkenumtypes.h \
+  /usr/include/gtk-2.0/gdk/gdkfont.h /usr/include/gtk-2.0/gdk/gdkimage.h \
+  /usr/include/gtk-2.0/gdk/gdkkeys.h \
+  /usr/include/gtk-2.0/gdk/gdkdisplaymanager.h \
+  /usr/include/gtk-2.0/gdk/gdkpango.h \
+  /usr/include/gtk-2.0/gdk/gdkpixbuf.h \
+  /usr/include/gtk-2.0/gdk/gdkpixmap.h \
+  /usr/include/gtk-2.0/gdk/gdkproperty.h \
+  /usr/include/gtk-2.0/gdk/gdkregion.h \
+  /usr/include/gtk-2.0/gdk/gdkscreen.h \
+  /usr/include/gtk-2.0/gdk/gdkselection.h \
+  /usr/include/gtk-2.0/gdk/gdkspawn.h \
+  /usr/include/gtk-2.0/gdk/gdkvisual.h \
+  /usr/include/gtk-2.0/gdk/gdkwindow.h \
+  /usr/include/gtk-2.0/gtk/gtkaccelgroup.h \
+  /usr/include/gtk-2.0/gtk/gtkenums.h \
+  /usr/include/gtk-2.0/gtk/gtkaccellabel.h \
+  /usr/include/gtk-2.0/gtk/gtklabel.h /usr/include/gtk-2.0/gtk/gtkmisc.h \
+  /usr/include/gtk-2.0/gtk/gtkwidget.h \
+  /usr/include/gtk-2.0/gtk/gtkobject.h \
+  /usr/include/gtk-2.0/gtk/gtktypeutils.h \
+  /usr/include/gtk-2.0/gtk/gtktypebuiltins.h \
+  /usr/include/gtk-2.0/gtk/gtkdebug.h \
+  /usr/include/gtk-2.0/gtk/gtkadjustment.h \
+  /usr/include/gtk-2.0/gtk/gtkstyle.h \
+  /usr/include/gtk-2.0/gtk/gtksettings.h /usr/include/gtk-2.0/gtk/gtkrc.h \
+  /usr/include/atk-1.0/atk/atkobject.h \
+  /usr/include/atk-1.0/atk/atkstate.h \
+  /usr/include/atk-1.0/atk/atkrelationtype.h \
+  /usr/include/gtk-2.0/gtk/gtkwindow.h /usr/include/gtk-2.0/gtk/gtkbin.h \
+  /usr/include/gtk-2.0/gtk/gtkcontainer.h \
+  /usr/include/gtk-2.0/gtk/gtkmenu.h \
+  /usr/include/gtk-2.0/gtk/gtkmenushell.h \
+  /usr/include/gtk-2.0/gtk/gtkaccelmap.h \
+  /usr/include/gtk-2.0/gtk/gtkaccessible.h /usr/include/atk-1.0/atk/atk.h \
+  /usr/include/atk-1.0/atk/atkaction.h \
+  /usr/include/atk-1.0/atk/atkcomponent.h \
+  /usr/include/atk-1.0/atk/atkutil.h \
+  /usr/include/atk-1.0/atk/atkdocument.h \
+  /usr/include/atk-1.0/atk/atkeditabletext.h \
+  /usr/include/atk-1.0/atk/atktext.h \
+  /usr/include/atk-1.0/atk/atkgobjectaccessible.h \
+  /usr/include/atk-1.0/atk/atkhyperlink.h \
+  /usr/include/atk-1.0/atk/atkhypertext.h \
+  /usr/include/atk-1.0/atk/atkimage.h \
+  /usr/include/atk-1.0/atk/atknoopobject.h \
+  /usr/include/atk-1.0/atk/atknoopobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkregistry.h \
+  /usr/include/atk-1.0/atk/atkobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkrelation.h \
+  /usr/include/atk-1.0/atk/atkrelationset.h \
+  /usr/include/atk-1.0/atk/atkselection.h \
+  /usr/include/atk-1.0/atk/atkstateset.h \
+  /usr/include/atk-1.0/atk/atkstreamablecontent.h \
+  /usr/include/atk-1.0/atk/atktable.h /usr/include/atk-1.0/atk/atkvalue.h \
+  /usr/include/gtk-2.0/gtk/gtkaction.h \
+  /usr/include/gtk-2.0/gtk/gtkactiongroup.h \
+  /usr/include/gtk-2.0/gtk/gtkitemfactory.h \
+  /usr/include/gtk-2.0/gtk/gtkalignment.h \
+  /usr/include/gtk-2.0/gtk/gtkarrow.h \
+  /usr/include/gtk-2.0/gtk/gtkaspectframe.h \
+  /usr/include/gtk-2.0/gtk/gtkframe.h /usr/include/gtk-2.0/gtk/gtkbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkbox.h \
+  /usr/include/gtk-2.0/gtk/gtkbindings.h \
+  /usr/include/gtk-2.0/gtk/gtkbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcalendar.h \
+  /usr/include/gtk-2.0/gtk/gtksignal.h \
+  /usr/include/gtk-2.0/gtk/gtkmarshal.h \
+  /usr/include/gtk-2.0/gtk/gtkcelllayout.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderer.h \
+  /usr/include/gtk-2.0/gtk/gtkcelleditable.h \
+  /usr/include/gtk-2.0/gtk/gtktreeviewcolumn.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodel.h \
+  /usr/include/gtk-2.0/gtk/gtktreesortable.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrendererpixbuf.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderertext.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderertoggle.h \
+  /usr/include/gtk-2.0/gtk/gtkcheckbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktogglebutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcheckmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkitem.h \
+  /usr/include/gtk-2.0/gtk/gtkclipboard.h \
+  /usr/include/gtk-2.0/gtk/gtkselection.h \
+  /usr/include/gtk-2.0/gtk/gtkclist.h \
+  /usr/include/gtk-2.0/gtk/gtkhscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkrange.h \
+  /usr/include/gtk-2.0/gtk/gtkvscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorsel.h \
+  /usr/include/gtk-2.0/gtk/gtkdialog.h /usr/include/gtk-2.0/gtk/gtkvbox.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorseldialog.h \
+  /usr/include/gtk-2.0/gtk/gtkcombo.h /usr/include/gtk-2.0/gtk/gtkhbox.h \
+  /usr/include/gtk-2.0/gtk/gtkcombobox.h \
+  /usr/include/gtk-2.0/gtk/gtktreeview.h \
+  /usr/include/gtk-2.0/gtk/gtkdnd.h \
+  /usr/include/gtk-2.0/gtk/gtkcomboboxentry.h \
+  /usr/include/gtk-2.0/gtk/gtkctree.h /usr/include/gtk-2.0/gtk/gtkcurve.h \
+  /usr/include/gtk-2.0/gtk/gtkdrawingarea.h \
+  /usr/include/gtk-2.0/gtk/gtkeditable.h \
+  /usr/include/gtk-2.0/gtk/gtkentry.h \
+  /usr/include/gtk-2.0/gtk/gtkimcontext.h \
+  /usr/include/gtk-2.0/gtk/gtkentrycompletion.h \
+  /usr/include/gtk-2.0/gtk/gtkliststore.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodelfilter.h \
+  /usr/include/gtk-2.0/gtk/gtkeventbox.h \
+  /usr/include/gtk-2.0/gtk/gtkexpander.h \
+  /usr/include/gtk-2.0/gtk/gtkfilesel.h \
+  /usr/include/gtk-2.0/gtk/gtkfixed.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooserdialog.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooser.h \
+  /usr/include/gtk-2.0/gtk/gtkfilefilter.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooserwidget.h \
+  /usr/include/gtk-2.0/gtk/gtkfontbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkfontsel.h \
+  /usr/include/gtk-2.0/gtk/gtkgamma.h /usr/include/gtk-2.0/gtk/gtkgc.h \
+  /usr/include/gtk-2.0/gtk/gtkhandlebox.h \
+  /usr/include/gtk-2.0/gtk/gtkhbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkhpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkhruler.h \
+  /usr/include/gtk-2.0/gtk/gtkruler.h \
+  /usr/include/gtk-2.0/gtk/gtkhscale.h \
+  /usr/include/gtk-2.0/gtk/gtkscale.h \
+  /usr/include/gtk-2.0/gtk/gtkhseparator.h \
+  /usr/include/gtk-2.0/gtk/gtkseparator.h \
+  /usr/include/gtk-2.0/gtk/gtkiconfactory.h \
+  /usr/include/gtk-2.0/gtk/gtkicontheme.h \
+  /usr/include/gtk-2.0/gtk/gtkimage.h \
+  /usr/include/gtk-2.0/gtk/gtkimagemenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkimcontextsimple.h \
+  /usr/include/gtk-2.0/gtk/gtkimmulticontext.h \
+  /usr/include/gtk-2.0/gtk/gtkinputdialog.h \
+  /usr/include/gtk-2.0/gtk/gtkinvisible.h \
+  /usr/include/gtk-2.0/gtk/gtklayout.h /usr/include/gtk-2.0/gtk/gtklist.h \
+  /usr/include/gtk-2.0/gtk/gtklistitem.h \
+  /usr/include/gtk-2.0/gtk/gtkmain.h \
+  /usr/include/gtk-2.0/gtk/gtkmenubar.h \
+  /usr/include/gtk-2.0/gtk/gtkmessagedialog.h \
+  /usr/include/gtk-2.0/gtk/gtknotebook.h \
+  /usr/include/gtk-2.0/gtk/gtkoldeditable.h \
+  /usr/include/gtk-2.0/gtk/gtkoptionmenu.h \
+  /usr/include/gtk-2.0/gtk/gtkpixmap.h /usr/include/gtk-2.0/gtk/gtkplug.h \
+  /usr/include/gtk-2.0/gtk/gtksocket.h \
+  /usr/include/gtk-2.0/gtk/gtkpreview.h \
+  /usr/include/gtk-2.0/gtk/gtkprogress.h \
+  /usr/include/gtk-2.0/gtk/gtkprogressbar.h \
+  /usr/include/gtk-2.0/gtk/gtkradioaction.h \
+  /usr/include/gtk-2.0/gtk/gtktoggleaction.h \
+  /usr/include/gtk-2.0/gtk/gtkradiobutton.h \
+  /usr/include/gtk-2.0/gtk/gtkradiomenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkradiotoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtktooltips.h \
+  /usr/include/gtk-2.0/gtk/gtkscrolledwindow.h \
+  /usr/include/gtk-2.0/gtk/gtkviewport.h \
+  /usr/include/gtk-2.0/gtk/gtkseparatormenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkseparatortoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtksizegroup.h \
+  /usr/include/gtk-2.0/gtk/gtkspinbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkstatusbar.h \
+  /usr/include/gtk-2.0/gtk/gtkstock.h /usr/include/gtk-2.0/gtk/gtktable.h \
+  /usr/include/gtk-2.0/gtk/gtktearoffmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtktext.h \
+  /usr/include/gtk-2.0/gtk/gtktextbuffer.h \
+  /usr/include/gtk-2.0/gtk/gtktexttagtable.h \
+  /usr/include/gtk-2.0/gtk/gtktexttag.h \
+  /usr/include/gtk-2.0/gtk/gtktextiter.h \
+  /usr/include/gtk-2.0/gtk/gtktextchild.h \
+  /usr/include/gtk-2.0/gtk/gtktextmark.h \
+  /usr/include/gtk-2.0/gtk/gtktextview.h \
+  /usr/include/gtk-2.0/gtk/gtktipsquery.h \
+  /usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbar.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtktree.h \
+  /usr/include/gtk-2.0/gtk/gtktreednd.h \
+  /usr/include/gtk-2.0/gtk/gtktreeitem.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodelsort.h \
+  /usr/include/gtk-2.0/gtk/gtktreeselection.h \
+  /usr/include/gtk-2.0/gtk/gtktreestore.h \
+  /usr/include/gtk-2.0/gtk/gtkuimanager.h \
+  /usr/include/gtk-2.0/gtk/gtkvbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkversion.h \
+  /usr/include/gtk-2.0/gtk/gtkvpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkvruler.h \
+  /usr/include/gtk-2.0/gtk/gtkvscale.h \
+  /usr/include/gtk-2.0/gtk/gtkvseparator.h /usr/include/stdio.h \
+  /usr/include/bits/types.h /usr/include/bits/wordsize.h \
+  /usr/include/bits/typesizes.h /usr/include/libio.h \
+  /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
+  /usr/include/gconv.h /usr/include/bits/stdio_lim.h \
+  /usr/include/bits/sys_errlist.h /usr/include/bits/stdio.h \
+  /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
+  /usr/include/endian.h /usr/include/bits/endian.h \
+  /usr/include/sys/select.h /usr/include/bits/select.h \
+  /usr/include/bits/sigset.h /usr/include/bits/time.h \
+  /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+  /usr/include/bits/sched.h /usr/include/alloca.h /usr/include/string.h \
+  /usr/include/bits/string.h /usr/include/bits/string2.h \
+  ../../../../ltt/ltt.h ../../../../ltt/time.h ../../../../ltt/compiler.h \
+  ../../../../ltt/event.h ../../../../ltt/type.h ../../../../ltt/trace.h \
+  ../../../../ltt/facility.h ../../../../lttv/lttv/module.h \
+  ../../../../lttv/lttv/hook.h ../../../../lttv/lttv/tracecontext.h \
+  ../../../../lttv/lttv/traceset.h ../../../../lttv/lttv/attribute.h \
+  ../../../../lttv/lttv/iattribute.h ../../../../lttv/lttv/state.h \
+  ../../../../lttv/lttv/filter.h \
+  ../../../../lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h \
+  ../../../../lttv/lttv/stats.h \
+  ../../../../lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h \
+  hInterruptsInsert.xpm
+
+/usr/include/math.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/bits/huge_val.h:
+
+/usr/include/bits/mathdef.h:
+
+/usr/include/bits/mathcalls.h:
+
+/usr/include/bits/mathinline.h:
+
+/usr/include/glib-2.0/glib.h:
+
+/usr/include/glib-2.0/glib/galloca.h:
+
+/usr/include/glib-2.0/glib/gtypes.h:
+
+/usr/lib/glib-2.0/include/glibconfig.h:
+
+/usr/include/glib-2.0/glib/gmacros.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/syslimits.h:
+
+/usr/include/limits.h:
+
+/usr/include/bits/posix1_lim.h:
+
+/usr/include/bits/local_lim.h:
+
+/usr/include/linux/limits.h:
+
+/usr/include/bits/posix2_lim.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/float.h:
+
+/usr/include/glib-2.0/glib/garray.h:
+
+/usr/include/glib-2.0/glib/gasyncqueue.h:
+
+/usr/include/glib-2.0/glib/gthread.h:
+
+/usr/include/glib-2.0/glib/gerror.h:
+
+/usr/include/glib-2.0/glib/gquark.h:
+
+/usr/include/glib-2.0/glib/gatomic.h:
+
+/usr/include/glib-2.0/glib/gbacktrace.h:
+
+/usr/include/glib-2.0/glib/gcache.h:
+
+/usr/include/glib-2.0/glib/glist.h:
+
+/usr/include/glib-2.0/glib/gmem.h:
+
+/usr/include/glib-2.0/glib/gcompletion.h:
+
+/usr/include/glib-2.0/glib/gconvert.h:
+
+/usr/include/glib-2.0/glib/gdataset.h:
+
+/usr/include/glib-2.0/glib/gdate.h:
+
+/usr/include/glib-2.0/glib/gdir.h:
+
+/usr/include/glib-2.0/glib/gfileutils.h:
+
+/usr/include/glib-2.0/glib/ghash.h:
+
+/usr/include/glib-2.0/glib/ghook.h:
+
+/usr/include/glib-2.0/glib/giochannel.h:
+
+/usr/include/glib-2.0/glib/gmain.h:
+
+/usr/include/glib-2.0/glib/gslist.h:
+
+/usr/include/glib-2.0/glib/gstring.h:
+
+/usr/include/glib-2.0/glib/gunicode.h:
+
+/usr/include/glib-2.0/glib/gutils.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h:
+
+/usr/include/glib-2.0/glib/gmarkup.h:
+
+/usr/include/glib-2.0/glib/gmessages.h:
+
+/usr/include/glib-2.0/glib/gnode.h:
+
+/usr/include/glib-2.0/glib/gpattern.h:
+
+/usr/include/glib-2.0/glib/gprimes.h:
+
+/usr/include/glib-2.0/glib/gqsort.h:
+
+/usr/include/glib-2.0/glib/gqueue.h:
+
+/usr/include/glib-2.0/glib/grand.h:
+
+/usr/include/glib-2.0/glib/grel.h:
+
+/usr/include/glib-2.0/glib/gscanner.h:
+
+/usr/include/glib-2.0/glib/gshell.h:
+
+/usr/include/glib-2.0/glib/gspawn.h:
+
+/usr/include/glib-2.0/glib/gstrfuncs.h:
+
+/usr/include/glib-2.0/glib/gthreadpool.h:
+
+/usr/include/glib-2.0/glib/gtimer.h:
+
+/usr/include/glib-2.0/glib/gtree.h:
+
+/usr/include/gtk-2.0/gtk/gtk.h:
+
+/usr/include/gtk-2.0/gdk/gdk.h:
+
+/usr/include/gtk-2.0/gdk/gdkcolor.h:
+
+/usr/include/gtk-2.0/gdk/gdktypes.h:
+
+/usr/include/pango-1.0/pango/pango.h:
+
+/usr/include/pango-1.0/pango/pango-attributes.h:
+
+/usr/include/pango-1.0/pango/pango-font.h:
+
+/usr/include/pango-1.0/pango/pango-coverage.h:
+
+/usr/include/pango-1.0/pango/pango-types.h:
+
+/usr/include/glib-2.0/glib-object.h:
+
+/usr/include/glib-2.0/gobject/gboxed.h:
+
+/usr/include/glib-2.0/gobject/gtype.h:
+
+/usr/include/glib-2.0/gobject/genums.h:
+
+/usr/include/glib-2.0/gobject/gobject.h:
+
+/usr/include/glib-2.0/gobject/gvalue.h:
+
+/usr/include/glib-2.0/gobject/gparam.h:
+
+/usr/include/glib-2.0/gobject/gclosure.h:
+
+/usr/include/glib-2.0/gobject/gsignal.h:
+
+/usr/include/glib-2.0/gobject/gmarshal.h:
+
+/usr/include/glib-2.0/gobject/gparamspecs.h:
+
+/usr/include/glib-2.0/gobject/gsourceclosure.h:
+
+/usr/include/glib-2.0/gobject/gtypemodule.h:
+
+/usr/include/glib-2.0/gobject/gtypeplugin.h:
+
+/usr/include/glib-2.0/gobject/gvaluearray.h:
+
+/usr/include/glib-2.0/gobject/gvaluetypes.h:
+
+/usr/include/pango-1.0/pango/pango-break.h:
+
+/usr/include/pango-1.0/pango/pango-item.h:
+
+/usr/include/pango-1.0/pango/pango-context.h:
+
+/usr/include/pango-1.0/pango/pango-fontmap.h:
+
+/usr/include/pango-1.0/pango/pango-fontset.h:
+
+/usr/include/pango-1.0/pango/pango-engine.h:
+
+/usr/include/pango-1.0/pango/pango-glyph.h:
+
+/usr/include/pango-1.0/pango/pango-script.h:
+
+/usr/include/pango-1.0/pango/pango-enum-types.h:
+
+/usr/include/pango-1.0/pango/pango-layout.h:
+
+/usr/include/pango-1.0/pango/pango-glyph-item.h:
+
+/usr/include/pango-1.0/pango/pango-tabs.h:
+
+/usr/lib/gtk-2.0/include/gdkconfig.h:
+
+/usr/include/gtk-2.0/gdk/gdkcursor.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-features.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-loader.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-enum-types.h:
+
+/usr/include/gtk-2.0/gdk/gdkdisplay.h:
+
+/usr/include/gtk-2.0/gdk/gdkevents.h:
+
+/usr/include/gtk-2.0/gdk/gdkdnd.h:
+
+/usr/include/gtk-2.0/gdk/gdkinput.h:
+
+/usr/include/gtk-2.0/gdk/gdkdrawable.h:
+
+/usr/include/gtk-2.0/gdk/gdkgc.h:
+
+/usr/include/gtk-2.0/gdk/gdkrgb.h:
+
+/usr/include/gtk-2.0/gdk/gdkenumtypes.h:
+
+/usr/include/gtk-2.0/gdk/gdkfont.h:
+
+/usr/include/gtk-2.0/gdk/gdkimage.h:
+
+/usr/include/gtk-2.0/gdk/gdkkeys.h:
+
+/usr/include/gtk-2.0/gdk/gdkdisplaymanager.h:
+
+/usr/include/gtk-2.0/gdk/gdkpango.h:
+
+/usr/include/gtk-2.0/gdk/gdkpixbuf.h:
+
+/usr/include/gtk-2.0/gdk/gdkpixmap.h:
+
+/usr/include/gtk-2.0/gdk/gdkproperty.h:
+
+/usr/include/gtk-2.0/gdk/gdkregion.h:
+
+/usr/include/gtk-2.0/gdk/gdkscreen.h:
+
+/usr/include/gtk-2.0/gdk/gdkselection.h:
+
+/usr/include/gtk-2.0/gdk/gdkspawn.h:
+
+/usr/include/gtk-2.0/gdk/gdkvisual.h:
+
+/usr/include/gtk-2.0/gdk/gdkwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccelgroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkenums.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccellabel.h:
+
+/usr/include/gtk-2.0/gtk/gtklabel.h:
+
+/usr/include/gtk-2.0/gtk/gtkmisc.h:
+
+/usr/include/gtk-2.0/gtk/gtkwidget.h:
+
+/usr/include/gtk-2.0/gtk/gtkobject.h:
+
+/usr/include/gtk-2.0/gtk/gtktypeutils.h:
+
+/usr/include/gtk-2.0/gtk/gtktypebuiltins.h:
+
+/usr/include/gtk-2.0/gtk/gtkdebug.h:
+
+/usr/include/gtk-2.0/gtk/gtkadjustment.h:
+
+/usr/include/gtk-2.0/gtk/gtkstyle.h:
+
+/usr/include/gtk-2.0/gtk/gtksettings.h:
+
+/usr/include/gtk-2.0/gtk/gtkrc.h:
+
+/usr/include/atk-1.0/atk/atkobject.h:
+
+/usr/include/atk-1.0/atk/atkstate.h:
+
+/usr/include/atk-1.0/atk/atkrelationtype.h:
+
+/usr/include/gtk-2.0/gtk/gtkwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkbin.h:
+
+/usr/include/gtk-2.0/gtk/gtkcontainer.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenu.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenushell.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccelmap.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccessible.h:
+
+/usr/include/atk-1.0/atk/atk.h:
+
+/usr/include/atk-1.0/atk/atkaction.h:
+
+/usr/include/atk-1.0/atk/atkcomponent.h:
+
+/usr/include/atk-1.0/atk/atkutil.h:
+
+/usr/include/atk-1.0/atk/atkdocument.h:
+
+/usr/include/atk-1.0/atk/atkeditabletext.h:
+
+/usr/include/atk-1.0/atk/atktext.h:
+
+/usr/include/atk-1.0/atk/atkgobjectaccessible.h:
+
+/usr/include/atk-1.0/atk/atkhyperlink.h:
+
+/usr/include/atk-1.0/atk/atkhypertext.h:
+
+/usr/include/atk-1.0/atk/atkimage.h:
+
+/usr/include/atk-1.0/atk/atknoopobject.h:
+
+/usr/include/atk-1.0/atk/atknoopobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkregistry.h:
+
+/usr/include/atk-1.0/atk/atkobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkrelation.h:
+
+/usr/include/atk-1.0/atk/atkrelationset.h:
+
+/usr/include/atk-1.0/atk/atkselection.h:
+
+/usr/include/atk-1.0/atk/atkstateset.h:
+
+/usr/include/atk-1.0/atk/atkstreamablecontent.h:
+
+/usr/include/atk-1.0/atk/atktable.h:
+
+/usr/include/atk-1.0/atk/atkvalue.h:
+
+/usr/include/gtk-2.0/gtk/gtkaction.h:
+
+/usr/include/gtk-2.0/gtk/gtkactiongroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkitemfactory.h:
+
+/usr/include/gtk-2.0/gtk/gtkalignment.h:
+
+/usr/include/gtk-2.0/gtk/gtkarrow.h:
+
+/usr/include/gtk-2.0/gtk/gtkaspectframe.h:
+
+/usr/include/gtk-2.0/gtk/gtkframe.h:
+
+/usr/include/gtk-2.0/gtk/gtkbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkbindings.h:
+
+/usr/include/gtk-2.0/gtk/gtkbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcalendar.h:
+
+/usr/include/gtk-2.0/gtk/gtksignal.h:
+
+/usr/include/gtk-2.0/gtk/gtkmarshal.h:
+
+/usr/include/gtk-2.0/gtk/gtkcelllayout.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderer.h:
+
+/usr/include/gtk-2.0/gtk/gtkcelleditable.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeviewcolumn.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodel.h:
+
+/usr/include/gtk-2.0/gtk/gtktreesortable.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrendererpixbuf.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderertext.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderertoggle.h:
+
+/usr/include/gtk-2.0/gtk/gtkcheckbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktogglebutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcheckmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkclipboard.h:
+
+/usr/include/gtk-2.0/gtk/gtkselection.h:
+
+/usr/include/gtk-2.0/gtk/gtkclist.h:
+
+/usr/include/gtk-2.0/gtk/gtkhscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkrange.h:
+
+/usr/include/gtk-2.0/gtk/gtkvscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorsel.h:
+
+/usr/include/gtk-2.0/gtk/gtkdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkvbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorseldialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkcombo.h:
+
+/usr/include/gtk-2.0/gtk/gtkhbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkcombobox.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeview.h:
+
+/usr/include/gtk-2.0/gtk/gtkdnd.h:
+
+/usr/include/gtk-2.0/gtk/gtkcomboboxentry.h:
+
+/usr/include/gtk-2.0/gtk/gtkctree.h:
+
+/usr/include/gtk-2.0/gtk/gtkcurve.h:
+
+/usr/include/gtk-2.0/gtk/gtkdrawingarea.h:
+
+/usr/include/gtk-2.0/gtk/gtkeditable.h:
+
+/usr/include/gtk-2.0/gtk/gtkentry.h:
+
+/usr/include/gtk-2.0/gtk/gtkimcontext.h:
+
+/usr/include/gtk-2.0/gtk/gtkentrycompletion.h:
+
+/usr/include/gtk-2.0/gtk/gtkliststore.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodelfilter.h:
+
+/usr/include/gtk-2.0/gtk/gtkeventbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkexpander.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilesel.h:
+
+/usr/include/gtk-2.0/gtk/gtkfixed.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooserdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooser.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilefilter.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooserwidget.h:
+
+/usr/include/gtk-2.0/gtk/gtkfontbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkfontsel.h:
+
+/usr/include/gtk-2.0/gtk/gtkgamma.h:
+
+/usr/include/gtk-2.0/gtk/gtkgc.h:
+
+/usr/include/gtk-2.0/gtk/gtkhandlebox.h:
+
+/usr/include/gtk-2.0/gtk/gtkhbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkhpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkhruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkhscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkhseparator.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparator.h:
+
+/usr/include/gtk-2.0/gtk/gtkiconfactory.h:
+
+/usr/include/gtk-2.0/gtk/gtkicontheme.h:
+
+/usr/include/gtk-2.0/gtk/gtkimage.h:
+
+/usr/include/gtk-2.0/gtk/gtkimagemenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkimcontextsimple.h:
+
+/usr/include/gtk-2.0/gtk/gtkimmulticontext.h:
+
+/usr/include/gtk-2.0/gtk/gtkinputdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkinvisible.h:
+
+/usr/include/gtk-2.0/gtk/gtklayout.h:
+
+/usr/include/gtk-2.0/gtk/gtklist.h:
+
+/usr/include/gtk-2.0/gtk/gtklistitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkmain.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenubar.h:
+
+/usr/include/gtk-2.0/gtk/gtkmessagedialog.h:
+
+/usr/include/gtk-2.0/gtk/gtknotebook.h:
+
+/usr/include/gtk-2.0/gtk/gtkoldeditable.h:
+
+/usr/include/gtk-2.0/gtk/gtkoptionmenu.h:
+
+/usr/include/gtk-2.0/gtk/gtkpixmap.h:
+
+/usr/include/gtk-2.0/gtk/gtkplug.h:
+
+/usr/include/gtk-2.0/gtk/gtksocket.h:
+
+/usr/include/gtk-2.0/gtk/gtkpreview.h:
+
+/usr/include/gtk-2.0/gtk/gtkprogress.h:
+
+/usr/include/gtk-2.0/gtk/gtkprogressbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkradioaction.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggleaction.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiobutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiomenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiotoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktooltips.h:
+
+/usr/include/gtk-2.0/gtk/gtkscrolledwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkviewport.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparatormenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparatortoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtksizegroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkspinbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkstatusbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkstock.h:
+
+/usr/include/gtk-2.0/gtk/gtktable.h:
+
+/usr/include/gtk-2.0/gtk/gtktearoffmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktext.h:
+
+/usr/include/gtk-2.0/gtk/gtktextbuffer.h:
+
+/usr/include/gtk-2.0/gtk/gtktexttagtable.h:
+
+/usr/include/gtk-2.0/gtk/gtktexttag.h:
+
+/usr/include/gtk-2.0/gtk/gtktextiter.h:
+
+/usr/include/gtk-2.0/gtk/gtktextchild.h:
+
+/usr/include/gtk-2.0/gtk/gtktextmark.h:
+
+/usr/include/gtk-2.0/gtk/gtktextview.h:
+
+/usr/include/gtk-2.0/gtk/gtktipsquery.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbar.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktree.h:
+
+/usr/include/gtk-2.0/gtk/gtktreednd.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodelsort.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeselection.h:
+
+/usr/include/gtk-2.0/gtk/gtktreestore.h:
+
+/usr/include/gtk-2.0/gtk/gtkuimanager.h:
+
+/usr/include/gtk-2.0/gtk/gtkvbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkversion.h:
+
+/usr/include/gtk-2.0/gtk/gtkvpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkvruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkvscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkvseparator.h:
+
+/usr/include/stdio.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/include/bits/wchar.h:
+
+/usr/include/gconv.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/bits/sched.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+../../../../ltt/ltt.h:
+
+../../../../ltt/time.h:
+
+../../../../ltt/compiler.h:
+
+../../../../ltt/event.h:
+
+../../../../ltt/type.h:
+
+../../../../ltt/trace.h:
+
+../../../../ltt/facility.h:
+
+../../../../lttv/lttv/module.h:
+
+../../../../lttv/lttv/hook.h:
+
+../../../../lttv/lttv/tracecontext.h:
+
+../../../../lttv/lttv/traceset.h:
+
+../../../../lttv/lttv/attribute.h:
+
+../../../../lttv/lttv/iattribute.h:
+
+../../../../lttv/lttv/state.h:
+
+../../../../lttv/lttv/filter.h:
+
+../../../../lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h:
+
+../../../../lttv/lttv/stats.h:
+
+../../../../lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h:
+
+hInterruptsInsert.xpm:
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/.deps/systeminfo.Plo b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/.deps/systeminfo.Plo
new file mode 100644 (file)
index 0000000..c47acdf
--- /dev/null
@@ -0,0 +1,1044 @@
+systeminfo.lo systeminfo.o: systeminfo.c /usr/include/math.h \
+  /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/gnu/stubs.h /usr/include/bits/huge_val.h \
+  /usr/include/bits/mathdef.h /usr/include/bits/mathcalls.h \
+  /usr/include/bits/mathinline.h /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/syslimits.h \
+  /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+  /usr/include/bits/posix2_lim.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/gtk-2.0/gtk/gtk.h /usr/include/gtk-2.0/gdk/gdk.h \
+  /usr/include/gtk-2.0/gdk/gdkcolor.h /usr/include/gtk-2.0/gdk/gdktypes.h \
+  /usr/include/pango-1.0/pango/pango.h \
+  /usr/include/pango-1.0/pango/pango-attributes.h \
+  /usr/include/pango-1.0/pango/pango-font.h \
+  /usr/include/pango-1.0/pango/pango-coverage.h \
+  /usr/include/pango-1.0/pango/pango-types.h \
+  /usr/include/glib-2.0/glib-object.h \
+  /usr/include/glib-2.0/gobject/gboxed.h \
+  /usr/include/glib-2.0/gobject/gtype.h \
+  /usr/include/glib-2.0/gobject/genums.h \
+  /usr/include/glib-2.0/gobject/gobject.h \
+  /usr/include/glib-2.0/gobject/gvalue.h \
+  /usr/include/glib-2.0/gobject/gparam.h \
+  /usr/include/glib-2.0/gobject/gclosure.h \
+  /usr/include/glib-2.0/gobject/gsignal.h \
+  /usr/include/glib-2.0/gobject/gmarshal.h \
+  /usr/include/glib-2.0/gobject/gparamspecs.h \
+  /usr/include/glib-2.0/gobject/gsourceclosure.h \
+  /usr/include/glib-2.0/gobject/gtypemodule.h \
+  /usr/include/glib-2.0/gobject/gtypeplugin.h \
+  /usr/include/glib-2.0/gobject/gvaluearray.h \
+  /usr/include/glib-2.0/gobject/gvaluetypes.h \
+  /usr/include/pango-1.0/pango/pango-break.h \
+  /usr/include/pango-1.0/pango/pango-item.h \
+  /usr/include/pango-1.0/pango/pango-context.h \
+  /usr/include/pango-1.0/pango/pango-fontmap.h \
+  /usr/include/pango-1.0/pango/pango-fontset.h \
+  /usr/include/pango-1.0/pango/pango-engine.h \
+  /usr/include/pango-1.0/pango/pango-glyph.h \
+  /usr/include/pango-1.0/pango/pango-script.h \
+  /usr/include/pango-1.0/pango/pango-enum-types.h \
+  /usr/include/pango-1.0/pango/pango-layout.h \
+  /usr/include/pango-1.0/pango/pango-glyph-item.h \
+  /usr/include/pango-1.0/pango/pango-tabs.h \
+  /usr/lib/gtk-2.0/include/gdkconfig.h \
+  /usr/include/gtk-2.0/gdk/gdkcursor.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-features.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-loader.h \
+  /usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-enum-types.h \
+  /usr/include/gtk-2.0/gdk/gdkdisplay.h \
+  /usr/include/gtk-2.0/gdk/gdkevents.h /usr/include/gtk-2.0/gdk/gdkdnd.h \
+  /usr/include/gtk-2.0/gdk/gdkinput.h \
+  /usr/include/gtk-2.0/gdk/gdkdrawable.h /usr/include/gtk-2.0/gdk/gdkgc.h \
+  /usr/include/gtk-2.0/gdk/gdkrgb.h \
+  /usr/include/gtk-2.0/gdk/gdkenumtypes.h \
+  /usr/include/gtk-2.0/gdk/gdkfont.h /usr/include/gtk-2.0/gdk/gdkimage.h \
+  /usr/include/gtk-2.0/gdk/gdkkeys.h \
+  /usr/include/gtk-2.0/gdk/gdkdisplaymanager.h \
+  /usr/include/gtk-2.0/gdk/gdkpango.h \
+  /usr/include/gtk-2.0/gdk/gdkpixbuf.h \
+  /usr/include/gtk-2.0/gdk/gdkpixmap.h \
+  /usr/include/gtk-2.0/gdk/gdkproperty.h \
+  /usr/include/gtk-2.0/gdk/gdkregion.h \
+  /usr/include/gtk-2.0/gdk/gdkscreen.h \
+  /usr/include/gtk-2.0/gdk/gdkselection.h \
+  /usr/include/gtk-2.0/gdk/gdkspawn.h \
+  /usr/include/gtk-2.0/gdk/gdkvisual.h \
+  /usr/include/gtk-2.0/gdk/gdkwindow.h \
+  /usr/include/gtk-2.0/gtk/gtkaccelgroup.h \
+  /usr/include/gtk-2.0/gtk/gtkenums.h \
+  /usr/include/gtk-2.0/gtk/gtkaccellabel.h \
+  /usr/include/gtk-2.0/gtk/gtklabel.h /usr/include/gtk-2.0/gtk/gtkmisc.h \
+  /usr/include/gtk-2.0/gtk/gtkwidget.h \
+  /usr/include/gtk-2.0/gtk/gtkobject.h \
+  /usr/include/gtk-2.0/gtk/gtktypeutils.h \
+  /usr/include/gtk-2.0/gtk/gtktypebuiltins.h \
+  /usr/include/gtk-2.0/gtk/gtkdebug.h \
+  /usr/include/gtk-2.0/gtk/gtkadjustment.h \
+  /usr/include/gtk-2.0/gtk/gtkstyle.h \
+  /usr/include/gtk-2.0/gtk/gtksettings.h /usr/include/gtk-2.0/gtk/gtkrc.h \
+  /usr/include/atk-1.0/atk/atkobject.h \
+  /usr/include/atk-1.0/atk/atkstate.h \
+  /usr/include/atk-1.0/atk/atkrelationtype.h \
+  /usr/include/gtk-2.0/gtk/gtkwindow.h /usr/include/gtk-2.0/gtk/gtkbin.h \
+  /usr/include/gtk-2.0/gtk/gtkcontainer.h \
+  /usr/include/gtk-2.0/gtk/gtkmenu.h \
+  /usr/include/gtk-2.0/gtk/gtkmenushell.h \
+  /usr/include/gtk-2.0/gtk/gtkaccelmap.h \
+  /usr/include/gtk-2.0/gtk/gtkaccessible.h /usr/include/atk-1.0/atk/atk.h \
+  /usr/include/atk-1.0/atk/atkaction.h \
+  /usr/include/atk-1.0/atk/atkcomponent.h \
+  /usr/include/atk-1.0/atk/atkutil.h \
+  /usr/include/atk-1.0/atk/atkdocument.h \
+  /usr/include/atk-1.0/atk/atkeditabletext.h \
+  /usr/include/atk-1.0/atk/atktext.h \
+  /usr/include/atk-1.0/atk/atkgobjectaccessible.h \
+  /usr/include/atk-1.0/atk/atkhyperlink.h \
+  /usr/include/atk-1.0/atk/atkhypertext.h \
+  /usr/include/atk-1.0/atk/atkimage.h \
+  /usr/include/atk-1.0/atk/atknoopobject.h \
+  /usr/include/atk-1.0/atk/atknoopobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkregistry.h \
+  /usr/include/atk-1.0/atk/atkobjectfactory.h \
+  /usr/include/atk-1.0/atk/atkrelation.h \
+  /usr/include/atk-1.0/atk/atkrelationset.h \
+  /usr/include/atk-1.0/atk/atkselection.h \
+  /usr/include/atk-1.0/atk/atkstateset.h \
+  /usr/include/atk-1.0/atk/atkstreamablecontent.h \
+  /usr/include/atk-1.0/atk/atktable.h /usr/include/atk-1.0/atk/atkvalue.h \
+  /usr/include/gtk-2.0/gtk/gtkaction.h \
+  /usr/include/gtk-2.0/gtk/gtkactiongroup.h \
+  /usr/include/gtk-2.0/gtk/gtkitemfactory.h \
+  /usr/include/gtk-2.0/gtk/gtkalignment.h \
+  /usr/include/gtk-2.0/gtk/gtkarrow.h \
+  /usr/include/gtk-2.0/gtk/gtkaspectframe.h \
+  /usr/include/gtk-2.0/gtk/gtkframe.h /usr/include/gtk-2.0/gtk/gtkbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkbox.h \
+  /usr/include/gtk-2.0/gtk/gtkbindings.h \
+  /usr/include/gtk-2.0/gtk/gtkbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcalendar.h \
+  /usr/include/gtk-2.0/gtk/gtksignal.h \
+  /usr/include/gtk-2.0/gtk/gtkmarshal.h \
+  /usr/include/gtk-2.0/gtk/gtkcelllayout.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderer.h \
+  /usr/include/gtk-2.0/gtk/gtkcelleditable.h \
+  /usr/include/gtk-2.0/gtk/gtktreeviewcolumn.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodel.h \
+  /usr/include/gtk-2.0/gtk/gtktreesortable.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrendererpixbuf.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderertext.h \
+  /usr/include/gtk-2.0/gtk/gtkcellrenderertoggle.h \
+  /usr/include/gtk-2.0/gtk/gtkcheckbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktogglebutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcheckmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkitem.h \
+  /usr/include/gtk-2.0/gtk/gtkclipboard.h \
+  /usr/include/gtk-2.0/gtk/gtkselection.h \
+  /usr/include/gtk-2.0/gtk/gtkclist.h \
+  /usr/include/gtk-2.0/gtk/gtkhscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkrange.h \
+  /usr/include/gtk-2.0/gtk/gtkvscrollbar.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorsel.h \
+  /usr/include/gtk-2.0/gtk/gtkdialog.h /usr/include/gtk-2.0/gtk/gtkvbox.h \
+  /usr/include/gtk-2.0/gtk/gtkcolorseldialog.h \
+  /usr/include/gtk-2.0/gtk/gtkcombo.h /usr/include/gtk-2.0/gtk/gtkhbox.h \
+  /usr/include/gtk-2.0/gtk/gtkcombobox.h \
+  /usr/include/gtk-2.0/gtk/gtktreeview.h \
+  /usr/include/gtk-2.0/gtk/gtkdnd.h \
+  /usr/include/gtk-2.0/gtk/gtkcomboboxentry.h \
+  /usr/include/gtk-2.0/gtk/gtkctree.h /usr/include/gtk-2.0/gtk/gtkcurve.h \
+  /usr/include/gtk-2.0/gtk/gtkdrawingarea.h \
+  /usr/include/gtk-2.0/gtk/gtkeditable.h \
+  /usr/include/gtk-2.0/gtk/gtkentry.h \
+  /usr/include/gtk-2.0/gtk/gtkimcontext.h \
+  /usr/include/gtk-2.0/gtk/gtkentrycompletion.h \
+  /usr/include/gtk-2.0/gtk/gtkliststore.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodelfilter.h \
+  /usr/include/gtk-2.0/gtk/gtkeventbox.h \
+  /usr/include/gtk-2.0/gtk/gtkexpander.h \
+  /usr/include/gtk-2.0/gtk/gtkfilesel.h \
+  /usr/include/gtk-2.0/gtk/gtkfixed.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooserdialog.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooser.h \
+  /usr/include/gtk-2.0/gtk/gtkfilefilter.h \
+  /usr/include/gtk-2.0/gtk/gtkfilechooserwidget.h \
+  /usr/include/gtk-2.0/gtk/gtkfontbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkfontsel.h \
+  /usr/include/gtk-2.0/gtk/gtkgamma.h /usr/include/gtk-2.0/gtk/gtkgc.h \
+  /usr/include/gtk-2.0/gtk/gtkhandlebox.h \
+  /usr/include/gtk-2.0/gtk/gtkhbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkhpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkhruler.h \
+  /usr/include/gtk-2.0/gtk/gtkruler.h \
+  /usr/include/gtk-2.0/gtk/gtkhscale.h \
+  /usr/include/gtk-2.0/gtk/gtkscale.h \
+  /usr/include/gtk-2.0/gtk/gtkhseparator.h \
+  /usr/include/gtk-2.0/gtk/gtkseparator.h \
+  /usr/include/gtk-2.0/gtk/gtkiconfactory.h \
+  /usr/include/gtk-2.0/gtk/gtkicontheme.h \
+  /usr/include/gtk-2.0/gtk/gtkimage.h \
+  /usr/include/gtk-2.0/gtk/gtkimagemenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkimcontextsimple.h \
+  /usr/include/gtk-2.0/gtk/gtkimmulticontext.h \
+  /usr/include/gtk-2.0/gtk/gtkinputdialog.h \
+  /usr/include/gtk-2.0/gtk/gtkinvisible.h \
+  /usr/include/gtk-2.0/gtk/gtklayout.h /usr/include/gtk-2.0/gtk/gtklist.h \
+  /usr/include/gtk-2.0/gtk/gtklistitem.h \
+  /usr/include/gtk-2.0/gtk/gtkmain.h \
+  /usr/include/gtk-2.0/gtk/gtkmenubar.h \
+  /usr/include/gtk-2.0/gtk/gtkmessagedialog.h \
+  /usr/include/gtk-2.0/gtk/gtknotebook.h \
+  /usr/include/gtk-2.0/gtk/gtkoldeditable.h \
+  /usr/include/gtk-2.0/gtk/gtkoptionmenu.h \
+  /usr/include/gtk-2.0/gtk/gtkpixmap.h /usr/include/gtk-2.0/gtk/gtkplug.h \
+  /usr/include/gtk-2.0/gtk/gtksocket.h \
+  /usr/include/gtk-2.0/gtk/gtkpreview.h \
+  /usr/include/gtk-2.0/gtk/gtkprogress.h \
+  /usr/include/gtk-2.0/gtk/gtkprogressbar.h \
+  /usr/include/gtk-2.0/gtk/gtkradioaction.h \
+  /usr/include/gtk-2.0/gtk/gtktoggleaction.h \
+  /usr/include/gtk-2.0/gtk/gtkradiobutton.h \
+  /usr/include/gtk-2.0/gtk/gtkradiomenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkradiotoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtktooltips.h \
+  /usr/include/gtk-2.0/gtk/gtkscrolledwindow.h \
+  /usr/include/gtk-2.0/gtk/gtkviewport.h \
+  /usr/include/gtk-2.0/gtk/gtkseparatormenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtkseparatortoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtksizegroup.h \
+  /usr/include/gtk-2.0/gtk/gtkspinbutton.h \
+  /usr/include/gtk-2.0/gtk/gtkstatusbar.h \
+  /usr/include/gtk-2.0/gtk/gtkstock.h /usr/include/gtk-2.0/gtk/gtktable.h \
+  /usr/include/gtk-2.0/gtk/gtktearoffmenuitem.h \
+  /usr/include/gtk-2.0/gtk/gtktext.h \
+  /usr/include/gtk-2.0/gtk/gtktextbuffer.h \
+  /usr/include/gtk-2.0/gtk/gtktexttagtable.h \
+  /usr/include/gtk-2.0/gtk/gtktexttag.h \
+  /usr/include/gtk-2.0/gtk/gtktextiter.h \
+  /usr/include/gtk-2.0/gtk/gtktextchild.h \
+  /usr/include/gtk-2.0/gtk/gtktextmark.h \
+  /usr/include/gtk-2.0/gtk/gtktextview.h \
+  /usr/include/gtk-2.0/gtk/gtktipsquery.h \
+  /usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbar.h \
+  /usr/include/gtk-2.0/gtk/gtktoolbutton.h \
+  /usr/include/gtk-2.0/gtk/gtktoolitem.h \
+  /usr/include/gtk-2.0/gtk/gtktree.h \
+  /usr/include/gtk-2.0/gtk/gtktreednd.h \
+  /usr/include/gtk-2.0/gtk/gtktreeitem.h \
+  /usr/include/gtk-2.0/gtk/gtktreemodelsort.h \
+  /usr/include/gtk-2.0/gtk/gtktreeselection.h \
+  /usr/include/gtk-2.0/gtk/gtktreestore.h \
+  /usr/include/gtk-2.0/gtk/gtkuimanager.h \
+  /usr/include/gtk-2.0/gtk/gtkvbbox.h \
+  /usr/include/gtk-2.0/gtk/gtkversion.h \
+  /usr/include/gtk-2.0/gtk/gtkvpaned.h \
+  /usr/include/gtk-2.0/gtk/gtkvruler.h \
+  /usr/include/gtk-2.0/gtk/gtkvscale.h \
+  /usr/include/gtk-2.0/gtk/gtkvseparator.h /usr/include/stdio.h \
+  /usr/include/bits/types.h /usr/include/bits/wordsize.h \
+  /usr/include/bits/typesizes.h /usr/include/libio.h \
+  /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
+  /usr/include/gconv.h /usr/include/bits/stdio_lim.h \
+  /usr/include/bits/sys_errlist.h /usr/include/bits/stdio.h \
+  /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
+  /usr/include/endian.h /usr/include/bits/endian.h \
+  /usr/include/sys/select.h /usr/include/bits/select.h \
+  /usr/include/bits/sigset.h /usr/include/bits/time.h \
+  /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+  /usr/include/bits/sched.h /usr/include/alloca.h /usr/include/string.h \
+  /usr/include/bits/string.h /usr/include/bits/string2.h \
+  ../../../../ltt/ltt.h ../../../../ltt/time.h ../../../../ltt/compiler.h \
+  ../../../../ltt/event.h ../../../../ltt/type.h ../../../../ltt/trace.h \
+  ../../../../ltt/facility.h ../../../../lttv/lttv/module.h \
+  ../../../../lttv/lttv/hook.h ../../../../lttv/lttv/tracecontext.h \
+  ../../../../lttv/lttv/traceset.h ../../../../lttv/lttv/attribute.h \
+  ../../../../lttv/lttv/iattribute.h ../../../../lttv/lttv/state.h \
+  ../../../../lttv/lttv/filter.h \
+  ../../../../lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h \
+  ../../../../lttv/lttv/stats.h \
+  ../../../../lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h \
+  hSystemInfoInsert.xpm
+
+/usr/include/math.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/bits/huge_val.h:
+
+/usr/include/bits/mathdef.h:
+
+/usr/include/bits/mathcalls.h:
+
+/usr/include/bits/mathinline.h:
+
+/usr/include/glib-2.0/glib.h:
+
+/usr/include/glib-2.0/glib/galloca.h:
+
+/usr/include/glib-2.0/glib/gtypes.h:
+
+/usr/lib/glib-2.0/include/glibconfig.h:
+
+/usr/include/glib-2.0/glib/gmacros.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/syslimits.h:
+
+/usr/include/limits.h:
+
+/usr/include/bits/posix1_lim.h:
+
+/usr/include/bits/local_lim.h:
+
+/usr/include/linux/limits.h:
+
+/usr/include/bits/posix2_lim.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/float.h:
+
+/usr/include/glib-2.0/glib/garray.h:
+
+/usr/include/glib-2.0/glib/gasyncqueue.h:
+
+/usr/include/glib-2.0/glib/gthread.h:
+
+/usr/include/glib-2.0/glib/gerror.h:
+
+/usr/include/glib-2.0/glib/gquark.h:
+
+/usr/include/glib-2.0/glib/gatomic.h:
+
+/usr/include/glib-2.0/glib/gbacktrace.h:
+
+/usr/include/glib-2.0/glib/gcache.h:
+
+/usr/include/glib-2.0/glib/glist.h:
+
+/usr/include/glib-2.0/glib/gmem.h:
+
+/usr/include/glib-2.0/glib/gcompletion.h:
+
+/usr/include/glib-2.0/glib/gconvert.h:
+
+/usr/include/glib-2.0/glib/gdataset.h:
+
+/usr/include/glib-2.0/glib/gdate.h:
+
+/usr/include/glib-2.0/glib/gdir.h:
+
+/usr/include/glib-2.0/glib/gfileutils.h:
+
+/usr/include/glib-2.0/glib/ghash.h:
+
+/usr/include/glib-2.0/glib/ghook.h:
+
+/usr/include/glib-2.0/glib/giochannel.h:
+
+/usr/include/glib-2.0/glib/gmain.h:
+
+/usr/include/glib-2.0/glib/gslist.h:
+
+/usr/include/glib-2.0/glib/gstring.h:
+
+/usr/include/glib-2.0/glib/gunicode.h:
+
+/usr/include/glib-2.0/glib/gutils.h:
+
+/usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h:
+
+/usr/include/glib-2.0/glib/gmarkup.h:
+
+/usr/include/glib-2.0/glib/gmessages.h:
+
+/usr/include/glib-2.0/glib/gnode.h:
+
+/usr/include/glib-2.0/glib/gpattern.h:
+
+/usr/include/glib-2.0/glib/gprimes.h:
+
+/usr/include/glib-2.0/glib/gqsort.h:
+
+/usr/include/glib-2.0/glib/gqueue.h:
+
+/usr/include/glib-2.0/glib/grand.h:
+
+/usr/include/glib-2.0/glib/grel.h:
+
+/usr/include/glib-2.0/glib/gscanner.h:
+
+/usr/include/glib-2.0/glib/gshell.h:
+
+/usr/include/glib-2.0/glib/gspawn.h:
+
+/usr/include/glib-2.0/glib/gstrfuncs.h:
+
+/usr/include/glib-2.0/glib/gthreadpool.h:
+
+/usr/include/glib-2.0/glib/gtimer.h:
+
+/usr/include/glib-2.0/glib/gtree.h:
+
+/usr/include/gtk-2.0/gtk/gtk.h:
+
+/usr/include/gtk-2.0/gdk/gdk.h:
+
+/usr/include/gtk-2.0/gdk/gdkcolor.h:
+
+/usr/include/gtk-2.0/gdk/gdktypes.h:
+
+/usr/include/pango-1.0/pango/pango.h:
+
+/usr/include/pango-1.0/pango/pango-attributes.h:
+
+/usr/include/pango-1.0/pango/pango-font.h:
+
+/usr/include/pango-1.0/pango/pango-coverage.h:
+
+/usr/include/pango-1.0/pango/pango-types.h:
+
+/usr/include/glib-2.0/glib-object.h:
+
+/usr/include/glib-2.0/gobject/gboxed.h:
+
+/usr/include/glib-2.0/gobject/gtype.h:
+
+/usr/include/glib-2.0/gobject/genums.h:
+
+/usr/include/glib-2.0/gobject/gobject.h:
+
+/usr/include/glib-2.0/gobject/gvalue.h:
+
+/usr/include/glib-2.0/gobject/gparam.h:
+
+/usr/include/glib-2.0/gobject/gclosure.h:
+
+/usr/include/glib-2.0/gobject/gsignal.h:
+
+/usr/include/glib-2.0/gobject/gmarshal.h:
+
+/usr/include/glib-2.0/gobject/gparamspecs.h:
+
+/usr/include/glib-2.0/gobject/gsourceclosure.h:
+
+/usr/include/glib-2.0/gobject/gtypemodule.h:
+
+/usr/include/glib-2.0/gobject/gtypeplugin.h:
+
+/usr/include/glib-2.0/gobject/gvaluearray.h:
+
+/usr/include/glib-2.0/gobject/gvaluetypes.h:
+
+/usr/include/pango-1.0/pango/pango-break.h:
+
+/usr/include/pango-1.0/pango/pango-item.h:
+
+/usr/include/pango-1.0/pango/pango-context.h:
+
+/usr/include/pango-1.0/pango/pango-fontmap.h:
+
+/usr/include/pango-1.0/pango/pango-fontset.h:
+
+/usr/include/pango-1.0/pango/pango-engine.h:
+
+/usr/include/pango-1.0/pango/pango-glyph.h:
+
+/usr/include/pango-1.0/pango/pango-script.h:
+
+/usr/include/pango-1.0/pango/pango-enum-types.h:
+
+/usr/include/pango-1.0/pango/pango-layout.h:
+
+/usr/include/pango-1.0/pango/pango-glyph-item.h:
+
+/usr/include/pango-1.0/pango/pango-tabs.h:
+
+/usr/lib/gtk-2.0/include/gdkconfig.h:
+
+/usr/include/gtk-2.0/gdk/gdkcursor.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-features.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-loader.h:
+
+/usr/include/gtk-2.0/gdk-pixbuf/gdk-pixbuf-enum-types.h:
+
+/usr/include/gtk-2.0/gdk/gdkdisplay.h:
+
+/usr/include/gtk-2.0/gdk/gdkevents.h:
+
+/usr/include/gtk-2.0/gdk/gdkdnd.h:
+
+/usr/include/gtk-2.0/gdk/gdkinput.h:
+
+/usr/include/gtk-2.0/gdk/gdkdrawable.h:
+
+/usr/include/gtk-2.0/gdk/gdkgc.h:
+
+/usr/include/gtk-2.0/gdk/gdkrgb.h:
+
+/usr/include/gtk-2.0/gdk/gdkenumtypes.h:
+
+/usr/include/gtk-2.0/gdk/gdkfont.h:
+
+/usr/include/gtk-2.0/gdk/gdkimage.h:
+
+/usr/include/gtk-2.0/gdk/gdkkeys.h:
+
+/usr/include/gtk-2.0/gdk/gdkdisplaymanager.h:
+
+/usr/include/gtk-2.0/gdk/gdkpango.h:
+
+/usr/include/gtk-2.0/gdk/gdkpixbuf.h:
+
+/usr/include/gtk-2.0/gdk/gdkpixmap.h:
+
+/usr/include/gtk-2.0/gdk/gdkproperty.h:
+
+/usr/include/gtk-2.0/gdk/gdkregion.h:
+
+/usr/include/gtk-2.0/gdk/gdkscreen.h:
+
+/usr/include/gtk-2.0/gdk/gdkselection.h:
+
+/usr/include/gtk-2.0/gdk/gdkspawn.h:
+
+/usr/include/gtk-2.0/gdk/gdkvisual.h:
+
+/usr/include/gtk-2.0/gdk/gdkwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccelgroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkenums.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccellabel.h:
+
+/usr/include/gtk-2.0/gtk/gtklabel.h:
+
+/usr/include/gtk-2.0/gtk/gtkmisc.h:
+
+/usr/include/gtk-2.0/gtk/gtkwidget.h:
+
+/usr/include/gtk-2.0/gtk/gtkobject.h:
+
+/usr/include/gtk-2.0/gtk/gtktypeutils.h:
+
+/usr/include/gtk-2.0/gtk/gtktypebuiltins.h:
+
+/usr/include/gtk-2.0/gtk/gtkdebug.h:
+
+/usr/include/gtk-2.0/gtk/gtkadjustment.h:
+
+/usr/include/gtk-2.0/gtk/gtkstyle.h:
+
+/usr/include/gtk-2.0/gtk/gtksettings.h:
+
+/usr/include/gtk-2.0/gtk/gtkrc.h:
+
+/usr/include/atk-1.0/atk/atkobject.h:
+
+/usr/include/atk-1.0/atk/atkstate.h:
+
+/usr/include/atk-1.0/atk/atkrelationtype.h:
+
+/usr/include/gtk-2.0/gtk/gtkwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkbin.h:
+
+/usr/include/gtk-2.0/gtk/gtkcontainer.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenu.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenushell.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccelmap.h:
+
+/usr/include/gtk-2.0/gtk/gtkaccessible.h:
+
+/usr/include/atk-1.0/atk/atk.h:
+
+/usr/include/atk-1.0/atk/atkaction.h:
+
+/usr/include/atk-1.0/atk/atkcomponent.h:
+
+/usr/include/atk-1.0/atk/atkutil.h:
+
+/usr/include/atk-1.0/atk/atkdocument.h:
+
+/usr/include/atk-1.0/atk/atkeditabletext.h:
+
+/usr/include/atk-1.0/atk/atktext.h:
+
+/usr/include/atk-1.0/atk/atkgobjectaccessible.h:
+
+/usr/include/atk-1.0/atk/atkhyperlink.h:
+
+/usr/include/atk-1.0/atk/atkhypertext.h:
+
+/usr/include/atk-1.0/atk/atkimage.h:
+
+/usr/include/atk-1.0/atk/atknoopobject.h:
+
+/usr/include/atk-1.0/atk/atknoopobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkregistry.h:
+
+/usr/include/atk-1.0/atk/atkobjectfactory.h:
+
+/usr/include/atk-1.0/atk/atkrelation.h:
+
+/usr/include/atk-1.0/atk/atkrelationset.h:
+
+/usr/include/atk-1.0/atk/atkselection.h:
+
+/usr/include/atk-1.0/atk/atkstateset.h:
+
+/usr/include/atk-1.0/atk/atkstreamablecontent.h:
+
+/usr/include/atk-1.0/atk/atktable.h:
+
+/usr/include/atk-1.0/atk/atkvalue.h:
+
+/usr/include/gtk-2.0/gtk/gtkaction.h:
+
+/usr/include/gtk-2.0/gtk/gtkactiongroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkitemfactory.h:
+
+/usr/include/gtk-2.0/gtk/gtkalignment.h:
+
+/usr/include/gtk-2.0/gtk/gtkarrow.h:
+
+/usr/include/gtk-2.0/gtk/gtkaspectframe.h:
+
+/usr/include/gtk-2.0/gtk/gtkframe.h:
+
+/usr/include/gtk-2.0/gtk/gtkbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkbindings.h:
+
+/usr/include/gtk-2.0/gtk/gtkbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcalendar.h:
+
+/usr/include/gtk-2.0/gtk/gtksignal.h:
+
+/usr/include/gtk-2.0/gtk/gtkmarshal.h:
+
+/usr/include/gtk-2.0/gtk/gtkcelllayout.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderer.h:
+
+/usr/include/gtk-2.0/gtk/gtkcelleditable.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeviewcolumn.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodel.h:
+
+/usr/include/gtk-2.0/gtk/gtktreesortable.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrendererpixbuf.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderertext.h:
+
+/usr/include/gtk-2.0/gtk/gtkcellrenderertoggle.h:
+
+/usr/include/gtk-2.0/gtk/gtkcheckbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktogglebutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcheckmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkclipboard.h:
+
+/usr/include/gtk-2.0/gtk/gtkselection.h:
+
+/usr/include/gtk-2.0/gtk/gtkclist.h:
+
+/usr/include/gtk-2.0/gtk/gtkhscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkrange.h:
+
+/usr/include/gtk-2.0/gtk/gtkvscrollbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorsel.h:
+
+/usr/include/gtk-2.0/gtk/gtkdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkvbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkcolorseldialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkcombo.h:
+
+/usr/include/gtk-2.0/gtk/gtkhbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkcombobox.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeview.h:
+
+/usr/include/gtk-2.0/gtk/gtkdnd.h:
+
+/usr/include/gtk-2.0/gtk/gtkcomboboxentry.h:
+
+/usr/include/gtk-2.0/gtk/gtkctree.h:
+
+/usr/include/gtk-2.0/gtk/gtkcurve.h:
+
+/usr/include/gtk-2.0/gtk/gtkdrawingarea.h:
+
+/usr/include/gtk-2.0/gtk/gtkeditable.h:
+
+/usr/include/gtk-2.0/gtk/gtkentry.h:
+
+/usr/include/gtk-2.0/gtk/gtkimcontext.h:
+
+/usr/include/gtk-2.0/gtk/gtkentrycompletion.h:
+
+/usr/include/gtk-2.0/gtk/gtkliststore.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodelfilter.h:
+
+/usr/include/gtk-2.0/gtk/gtkeventbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkexpander.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilesel.h:
+
+/usr/include/gtk-2.0/gtk/gtkfixed.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooserdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooser.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilefilter.h:
+
+/usr/include/gtk-2.0/gtk/gtkfilechooserwidget.h:
+
+/usr/include/gtk-2.0/gtk/gtkfontbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkfontsel.h:
+
+/usr/include/gtk-2.0/gtk/gtkgamma.h:
+
+/usr/include/gtk-2.0/gtk/gtkgc.h:
+
+/usr/include/gtk-2.0/gtk/gtkhandlebox.h:
+
+/usr/include/gtk-2.0/gtk/gtkhbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkhpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkhruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkhscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkhseparator.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparator.h:
+
+/usr/include/gtk-2.0/gtk/gtkiconfactory.h:
+
+/usr/include/gtk-2.0/gtk/gtkicontheme.h:
+
+/usr/include/gtk-2.0/gtk/gtkimage.h:
+
+/usr/include/gtk-2.0/gtk/gtkimagemenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkimcontextsimple.h:
+
+/usr/include/gtk-2.0/gtk/gtkimmulticontext.h:
+
+/usr/include/gtk-2.0/gtk/gtkinputdialog.h:
+
+/usr/include/gtk-2.0/gtk/gtkinvisible.h:
+
+/usr/include/gtk-2.0/gtk/gtklayout.h:
+
+/usr/include/gtk-2.0/gtk/gtklist.h:
+
+/usr/include/gtk-2.0/gtk/gtklistitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkmain.h:
+
+/usr/include/gtk-2.0/gtk/gtkmenubar.h:
+
+/usr/include/gtk-2.0/gtk/gtkmessagedialog.h:
+
+/usr/include/gtk-2.0/gtk/gtknotebook.h:
+
+/usr/include/gtk-2.0/gtk/gtkoldeditable.h:
+
+/usr/include/gtk-2.0/gtk/gtkoptionmenu.h:
+
+/usr/include/gtk-2.0/gtk/gtkpixmap.h:
+
+/usr/include/gtk-2.0/gtk/gtkplug.h:
+
+/usr/include/gtk-2.0/gtk/gtksocket.h:
+
+/usr/include/gtk-2.0/gtk/gtkpreview.h:
+
+/usr/include/gtk-2.0/gtk/gtkprogress.h:
+
+/usr/include/gtk-2.0/gtk/gtkprogressbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkradioaction.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggleaction.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiobutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiomenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkradiotoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktooltips.h:
+
+/usr/include/gtk-2.0/gtk/gtkscrolledwindow.h:
+
+/usr/include/gtk-2.0/gtk/gtkviewport.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparatormenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtkseparatortoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtksizegroup.h:
+
+/usr/include/gtk-2.0/gtk/gtkspinbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtkstatusbar.h:
+
+/usr/include/gtk-2.0/gtk/gtkstock.h:
+
+/usr/include/gtk-2.0/gtk/gtktable.h:
+
+/usr/include/gtk-2.0/gtk/gtktearoffmenuitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktext.h:
+
+/usr/include/gtk-2.0/gtk/gtktextbuffer.h:
+
+/usr/include/gtk-2.0/gtk/gtktexttagtable.h:
+
+/usr/include/gtk-2.0/gtk/gtktexttag.h:
+
+/usr/include/gtk-2.0/gtk/gtktextiter.h:
+
+/usr/include/gtk-2.0/gtk/gtktextchild.h:
+
+/usr/include/gtk-2.0/gtk/gtktextmark.h:
+
+/usr/include/gtk-2.0/gtk/gtktextview.h:
+
+/usr/include/gtk-2.0/gtk/gtktipsquery.h:
+
+/usr/include/gtk-2.0/gtk/gtktoggletoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbar.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolbutton.h:
+
+/usr/include/gtk-2.0/gtk/gtktoolitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktree.h:
+
+/usr/include/gtk-2.0/gtk/gtktreednd.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeitem.h:
+
+/usr/include/gtk-2.0/gtk/gtktreemodelsort.h:
+
+/usr/include/gtk-2.0/gtk/gtktreeselection.h:
+
+/usr/include/gtk-2.0/gtk/gtktreestore.h:
+
+/usr/include/gtk-2.0/gtk/gtkuimanager.h:
+
+/usr/include/gtk-2.0/gtk/gtkvbbox.h:
+
+/usr/include/gtk-2.0/gtk/gtkversion.h:
+
+/usr/include/gtk-2.0/gtk/gtkvpaned.h:
+
+/usr/include/gtk-2.0/gtk/gtkvruler.h:
+
+/usr/include/gtk-2.0/gtk/gtkvscale.h:
+
+/usr/include/gtk-2.0/gtk/gtkvseparator.h:
+
+/usr/include/stdio.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/include/bits/wchar.h:
+
+/usr/include/gconv.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/time.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/bits/sched.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+../../../../ltt/ltt.h:
+
+../../../../ltt/time.h:
+
+../../../../ltt/compiler.h:
+
+../../../../ltt/event.h:
+
+../../../../ltt/type.h:
+
+../../../../ltt/trace.h:
+
+../../../../ltt/facility.h:
+
+../../../../lttv/lttv/module.h:
+
+../../../../lttv/lttv/hook.h:
+
+../../../../lttv/lttv/tracecontext.h:
+
+../../../../lttv/lttv/traceset.h:
+
+../../../../lttv/lttv/attribute.h:
+
+../../../../lttv/lttv/iattribute.h:
+
+../../../../lttv/lttv/state.h:
+
+../../../../lttv/lttv/filter.h:
+
+../../../../lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h:
+
+../../../../lttv/lttv/stats.h:
+
+../../../../lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h:
+
+hSystemInfoInsert.xpm:
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/Makefile.am
new file mode 100644 (file)
index 0000000..28a357d
--- /dev/null
@@ -0,0 +1,38 @@
+# This file is part of the Linux Trace Toolkit viewer
+# Copyright (C) 2003-2004 Mathieu Desnoyers
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+# MA 02111-1307, USA.
+
+
+
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libinterrupts.la
+libinterrupts_la_LDFLAGS = -module
+libinterrupts_la_SOURCES = interrupts.c
+
+EXTRA_DIST = \
+               hInterruptsInsert.xpm
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/hInterruptsInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/hInterruptsInsert.xpm
new file mode 100644 (file)
index 0000000..838bb3f
--- /dev/null
@@ -0,0 +1,27 @@
+/* XPM */
+static char * hInterruptsInsert_xpm[] = {
+"22 22 2 1",
+"      c None",
+".     c #800080",
+"                      ",
+"                      ",
+"     ..........       ",
+"    .............     ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"        .....         ",
+"    .............     ",
+"     ..........       ",
+"                      ",
+"                      "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/interrupts.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/interrupts/interrupts.c
new file mode 100644 (file)
index 0000000..1afe46a
--- /dev/null
@@ -0,0 +1,509 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2005 Peter Ho
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+
+#include <math.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/filter.h>
+#include <lttvwindow/lttvwindow.h>
+#include <ltt/time.h>
+
+#include "hInterruptsInsert.xpm" 
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+#define NO_ITEMS 0
+  
+typedef struct {
+       guint cpu_id;
+       guint id;
+       guint frequency;
+       LttTime total_duration; 
+}Irq;
+
+typedef struct {
+       guint id;
+       guint cpu_id;
+       LttTime event_time;
+}irq_entry;
+
+enum type_t {
+   IRQ_ENTRY,
+   IRQ_EXIT            
+};
+
+/** Array containing instanced objects. Used when module is unloaded */
+static GSList *interrupt_data_list = NULL ;
+
+typedef struct _InterruptEventData {
+
+  Tab       * tab;
+  LttvHooks  * event_hooks;
+  LttvHooks  * hooks_trace_after;
+  LttvHooks  * hooks_trace_before;
+  TimeWindow   time_window;            // time window
+  GtkWidget * scroll_win;
+  /* Model containing list data */
+  GtkListStore *store_m;
+  GtkWidget *hbox_v;
+  /* Widget to display the data in a columned list */
+  GtkWidget *tree_v;
+  /* Selection handler */
+  GtkTreeSelection *select_c;
+  GtkWidget *container;
+  GArray *interrupt_counters;
+  GArray *active_irq_entry ;
+} InterruptEventData ;
+
+
+static gboolean interrupt_update_time_window(void * hook_data, void * call_data);
+// Event Viewer's constructor hook
+GtkWidget *interrupts(Tab *tab);
+// Event Viewer's constructor
+InterruptEventData *system_info(Tab *tab);
+// Event Viewer's destructor
+void interrupt_destructor(InterruptEventData *event_viewer_data);
+void gui_events_free(InterruptEventData *event_viewer_data);
+static void request_event(  InterruptEventData *event_data);  
+  /* Prototype for selection handler callback */
+static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data);
+
+static gboolean trace_header(void *hook_data, void *call_data);
+static gboolean parse_event(void *hook_data, void *call_data);
+static gboolean interrupt_show(void *hook_data, void *call_data);
+static void calcul_duration(LttTime time_exit,  guint cpu_id,  InterruptEventData *event_data);
+static void sum_interrupt_data(irq_entry *e, LttTime time_exit, GArray *interrupt_counters);
+/* Enumeration of the columns */
+enum{
+  CPUID_COLUMN,
+  IRQ_ID_COLUMN,
+  FREQUENCY_COLUMN,
+  DURATION_COLUMN,
+  N_COLUMNS
+};
+
+
+/**
+ * Event Viewer's constructor hook
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the list.
+ * @param parent_window A pointer to the parent window.
+ * @return The widget created.
+ */
+GtkWidget *interrupts(Tab * tab){
+  InterruptEventData* event_data = system_info(tab) ;
+  if(event_data)
+    return event_data->hbox_v;
+  else 
+    return NULL; 
+}
+
+/**
+ * Event Viewer's constructor
+ *
+ * This constructor is used to create InterruptEventData data structure.
+ * @return The Event viewer data created.
+ */
+InterruptEventData *system_info(Tab *tab)
+{
+  LttTime end;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  InterruptEventData* event_viewer_data = g_new(InterruptEventData,1) ;
+  g_info("system_info \n");
+  
+  event_viewer_data->tab = tab;
+  event_viewer_data->time_window  =  lttvwindow_get_time_window(tab);
+  event_viewer_data->interrupt_counters = g_array_new(FALSE, FALSE, sizeof(Irq));
+  event_viewer_data->active_irq_entry   =  g_array_new(FALSE, FALSE, sizeof(irq_entry));
+  
+  lttvwindow_register_time_window_notify(tab,
+                                         interrupt_update_time_window,
+                                         event_viewer_data);   
+                                               
+  event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (event_viewer_data->scroll_win);
+  gtk_scrolled_window_set_policy(
+      GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win), 
+      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC/*GTK_POLICY_NEVER*/);
+  /* Create a model for storing the data list */
+  event_viewer_data->store_m = gtk_list_store_new (
+    N_COLUMNS,      /* Total number of columns     */
+    G_TYPE_INT,     /* CPUID                       */
+    G_TYPE_INT,     /* IRQ_ID                      */
+    G_TYPE_INT,     /* Frequency                  */
+    G_TYPE_UINT64   /* Duration                    */
+    );  
+  event_viewer_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m)); 
+   
+  g_object_unref (G_OBJECT (event_viewer_data->store_m));
+    
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("CPUID",
+                 renderer,
+                 "text", CPUID_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+
+   
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("IrqId",
+                 renderer,
+                 "text", IRQ_ID_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column,  220);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Frequency",
+                 renderer,
+                 "text", FREQUENCY_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 1.0);
+  gtk_tree_view_column_set_fixed_width (column, 220);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Duration (nsec)",
+                 renderer,
+                 "text", DURATION_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 145);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v), column);
+
+  event_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v));
+  gtk_tree_selection_set_mode (event_viewer_data->select_c, GTK_SELECTION_SINGLE);
+   
+  gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win), event_viewer_data->tree_v);
+   
+  event_viewer_data->hbox_v = gtk_hbox_new(0, 0);
+  gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v), event_viewer_data->scroll_win, TRUE, TRUE, 0);
+  gtk_widget_show(event_viewer_data->hbox_v);
+  gtk_widget_show(event_viewer_data->tree_v);
+
+   interrupt_data_list = g_slist_append(interrupt_data_list, event_viewer_data);
+  
+  request_event(event_viewer_data);
+  return event_viewer_data;
+}
+  
+void v_scroll_cb(GtkAdjustment *adjustment, gpointer data){
+  InterruptEventData *event_data = (InterruptEventData*)data;
+  GtkTreePath *tree_path;
+  g_info("enter v_scroll_cb\n");
+}
+void gui_events_free(InterruptEventData *event_viewer_data)
+{
+  Tab *tab = event_viewer_data->tab;
+
+  if(event_viewer_data){
+    lttv_hooks_remove(event_viewer_data->event_hooks,parse_event);
+    lttv_hooks_destroy(event_viewer_data->event_hooks);
+   
+    interrupt_data_list = g_slist_remove(interrupt_data_list, event_viewer_data);
+    g_free(event_viewer_data);
+  }
+}
+
+void interrupt_destructor(InterruptEventData *event_viewer_data)
+{
+  /* May already been done by GTK window closing */
+  g_info("enter interrupt_destructor \n");
+  if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){
+    gtk_widget_destroy(event_viewer_data->hbox_v);
+  }
+}
+   
+static guint64 get_event_detail(LttEvent *e, LttField *f){
+
+  LttType *type;
+  LttField *element;
+  GQuark name;
+  int nb, i;
+  guint64  irq_id;
+  type = ltt_field_type(f);
+  nb = ltt_type_member_number(type);
+  for(i = 0 ; i < nb-1 ; i++) {
+       element = ltt_field_member(f,i);
+       ltt_type_member_type(type, i, &name);
+       irq_id = ltt_event_get_long_unsigned(e,element);
+  }
+  return  irq_id;
+} 
+
+
+
+
+gboolean trace_header(void *hook_data, void *call_data){
+
+  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+  LttEvent *e;
+  LttTime event_time;
+  return FALSE;
+}
+
+static gboolean interrupt_show(void *hook_data, void *call_data){
+  
+  gint i;      
+  Irq element; 
+  LttTime average_duration;
+  GtkTreeIter    iter;
+  guint64 real_data;
+  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  GArray *interrupt_counters = event_data->interrupt_counters;  
+  g_info("interrupts: interrupt_show() \n");
+  gtk_list_store_clear(event_data->store_m);
+  for(i = 0; i < interrupt_counters->len; i++){  
+    element = g_array_index(interrupt_counters,Irq,i);  
+    real_data = element.total_duration.tv_sec;
+    real_data *= NANOSECONDS_PER_SECOND;
+    real_data += element.total_duration.tv_nsec;
+    //printf("total_duration:%ld\n",  element.total_duration.tv_nsec);
+    gtk_list_store_append (event_data->store_m, &iter);
+    gtk_list_store_set (event_data->store_m, &iter,
+      CPUID_COLUMN, element.cpu_id,
+      IRQ_ID_COLUMN,  element.id,
+      FREQUENCY_COLUMN, element.frequency,
+      DURATION_COLUMN, real_data,
+      -1);
+  } 
+  
+  if(event_data->interrupt_counters->len)
+     g_array_remove_range (event_data->interrupt_counters,0,event_data->interrupt_counters->len);
+   
+  if(event_data->active_irq_entry->len)
+    g_array_remove_range (event_data->active_irq_entry,0,event_data->active_irq_entry->len);
+  return FALSE;
+}
+
+static void sum_interrupt_data(irq_entry *e, LttTime time_exit, GArray *interrupt_counters){
+  Irq irq;
+  Irq *element; 
+  guint i;
+  LttTime duration;
+  gboolean  notFound = FALSE;
+  memset ((void*)&irq, 0,sizeof(Irq));
+  
+  //printf("time_exit: %ld.%ld\n",time_exit.tv_sec,time_exit.tv_nsec); 
+  if(interrupt_counters->len == NO_ITEMS){
+    irq.cpu_id = e->cpu_id;
+    irq.id    =  e->id;
+    irq.frequency++;
+    irq.total_duration =  ltt_time_sub(time_exit, e->event_time);
+    g_array_append_val (interrupt_counters, irq);
+  }
+  else{
+    for(i = 0; i < interrupt_counters->len; i++){
+      element = &g_array_index(interrupt_counters,Irq,i);
+      if(element->id == e->id){
+       notFound = TRUE;
+       duration =  ltt_time_sub(time_exit, e->event_time);
+       element->total_duration = ltt_time_add(element->total_duration, duration);
+       element->frequency++;
+      }
+    }
+    if(!notFound){
+      irq.cpu_id = e->cpu_id;
+      irq.id    =  e->id;
+      irq.frequency++;
+      irq.total_duration =  ltt_time_sub(time_exit, e->event_time);
+      g_array_append_val (interrupt_counters, irq);
+    }
+  } 
+}
+static void calcul_duration(LttTime time_exit,  guint cpu_id,InterruptEventData *event_data){
+  
+  gint i, irq_id;
+  irq_entry *element; 
+  LttTime duration;
+  GArray *interrupt_counters = event_data->interrupt_counters;
+  GArray *active_irq_entry = event_data->active_irq_entry;
+  for(i = 0; i < active_irq_entry->len; i++){
+    element = &g_array_index(active_irq_entry,irq_entry,i);
+    if(element->cpu_id == cpu_id){
+      sum_interrupt_data(element,time_exit,  interrupt_counters);    
+      g_array_remove_index(active_irq_entry, i);
+     // printf("array length:%d\n",active_irq_entry->len);
+      break;
+    }
+  }
+}
+
+gboolean parse_event(void *hook_data, void *call_data){
+
+  LttTime  event_time; 
+  LttEvent *e;
+  LttField *field;
+  LttEventType *event_type;
+  unsigned cpu_id;
+  irq_entry entry;
+  irq_entry *element; 
+  guint i;
+ // g_info("interrupts: parse_event() \n");
+  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  GArray* active_irq_entry  = event_data->active_irq_entry; 
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+  //e = tfc->e; 
+  e = ltt_tracefile_get_event(tfc->tf);
+  
+  field = ltt_event_field(e);
+  event_time = ltt_event_time(e);
+  event_type = ltt_event_eventtype(e);
+  cpu_id = ltt_event_cpu_id(e);
+  GString * detail_event = g_string_new("");
+  if ((ltt_time_compare(event_time,event_data->time_window.start_time) == TRUE) &&    
+     (ltt_time_compare(event_data->time_window.end_time,event_time) == TRUE)){
+       if (strcmp( g_quark_to_string(ltt_eventtype_name(event_type)),"irq_entry") == 0) {  
+           entry.id = get_event_detail(e, field);
+           entry.cpu_id = cpu_id;
+           entry.event_time =  event_time;
+           g_array_append_val (active_irq_entry, entry);
+           
+       }
+       if(strcmp( g_quark_to_string(ltt_eventtype_name(event_type)),"irq_exit") == 0) {
+         //printf("event_time: %ld.%ld\n",event_time.tv_sec,event_time.tv_nsec);       
+         calcul_duration( event_time,  cpu_id, event_data);
+        }
+   } 
+   g_string_free(detail_event, TRUE);
+   return FALSE;
+}
+
+static void request_event(  InterruptEventData *event_data){
+
+  event_data->event_hooks = lttv_hooks_new();
+  lttv_hooks_add(event_data->event_hooks, parse_event, event_data, LTTV_PRIO_DEFAULT);
+  event_data->hooks_trace_after = lttv_hooks_new();
+  lttv_hooks_add(event_data->hooks_trace_after, interrupt_show, event_data, LTTV_PRIO_DEFAULT);
+    
+  event_data->hooks_trace_before = lttv_hooks_new();
+  lttv_hooks_add(event_data->hooks_trace_before, trace_header, event_data, LTTV_PRIO_DEFAULT);
+
+  EventsRequest *events_request = g_new(EventsRequest, 1); 
+  events_request->owner       = event_data; 
+  events_request->viewer_data = event_data; 
+  events_request->servicing   = FALSE;     
+  events_request->start_time  = event_data->time_window.start_time; 
+  events_request->start_position  = NULL;
+  events_request->stop_flag       = FALSE;
+  events_request->end_time        = event_data->time_window.end_time;
+  events_request->num_events      = G_MAXUINT;      
+  events_request->end_position     = NULL; 
+  events_request->trace           = 0;    
+  events_request->hooks           = NULL; 
+  events_request->before_chunk_traceset = NULL; 
+  events_request->before_chunk_trace    = event_data->hooks_trace_before; 
+  events_request->before_chunk_tracefile= NULL; 
+  events_request->event                        = event_data->event_hooks; 
+  events_request->event_by_id          = NULL; 
+  events_request->after_chunk_tracefile = NULL; 
+  events_request->after_chunk_trace     = NULL;   
+  events_request->after_chunk_traceset = NULL; 
+  events_request->before_request       = NULL; 
+  events_request->after_request                = event_data->hooks_trace_after; 
+  
+  lttvwindow_events_request(event_data->tab, events_request);   
+}
+
+gboolean interrupt_update_time_window(void * hook_data, void * call_data){
+  InterruptEventData *event_data = (InterruptEventData *) hook_data;
+  const TimeWindowNotifyData *time_window_nofify_data =  ((const TimeWindowNotifyData *)call_data);
+  event_data->time_window = *time_window_nofify_data->new_time_window;
+  g_info("interrupts: interrupt_update_time_window()\n");
+  Tab *tab = event_data->tab;
+  lttvwindow_events_request_remove_all(tab, event_data);
+  request_event(event_data);
+   
+  
+    return FALSE;
+}
+
+/**
+ * plugin's init function
+ *
+ * This function initializes the Event Viewer functionnality through the
+ * gtkTraceSet API.
+ */
+static void init() {
+  g_info("interrupts: init()");
+  
+  lttvwindow_register_constructor("interrupts",
+                                  "/",
+                                  "Insert  Interrupts View",
+                                  hInterruptsInsert_xpm,
+                                  "Insert Interrupts View",
+                                  interrupts);
+   
+}
+
+void interrupt_destroy_walk(gpointer data, gpointer user_data){
+  g_info("interrupt_destroy_walk");
+  interrupt_destructor((InterruptEventData*)data);
+
+}
+
+/**
+ * plugin's destroy function
+ *
+ * This function releases the memory reserved by the module and unregisters
+ * everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+  g_info("Destroy  interrupts");
+  g_slist_foreach(interrupt_data_list, interrupt_destroy_walk, NULL );
+  g_slist_free(interrupt_data_list); 
+  lttvwindow_unregister_constructor(interrupts);
+  
+}
+
+LTTV_MODULE("interrupts", "interrupts info view", \
+    "Graphical module to display interrupts performance", \
+           init, destroy, "lttvwindow")
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/Makefile.am
new file mode 100644 (file)
index 0000000..fabc84a
--- /dev/null
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = lttvwindow
+
+install-data-local:
+       @$(NORMAL_INSTALL)
+       if test -d $(srcdir)/pixmaps; then \
+         $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/pixmaps; \
+         for pixmap in $(srcdir)/pixmaps/*; do \
+           if test -f $$pixmap; then \
+             $(INSTALL_DATA) $$pixmap $(DESTDIR)$(pkgdatadir)/pixmaps; \
+           fi \
+         done \
+       fi
+
+dist-hook:
+       if test -d pixmaps; then \
+         mkdir $(distdir)/pixmaps; \
+         for pixmap in pixmaps/*; do \
+           if test -f $$pixmap; then \
+             cp -p $$pixmap $(distdir)/pixmaps; \
+           fi \
+         done \
+       fi
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/glade/lttvwindow.glade b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/glade/lttvwindow.glade
new file mode 100644 (file)
index 0000000..0d4cd97
--- /dev/null
@@ -0,0 +1,760 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="MWindow">
+  <property name="width_request">100</property>
+  <property name="height_request">50</property>
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Main window</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">600</property>
+  <property name="default_height">400</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <signal name="destroy" handler="on_MWindow_destroy" last_modification_time="Tue, 10 Jun 2003 16:31:35 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="MVbox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+       <widget class="GtkHBox" id="MMenuBox">
+         <property name="visible">True</property>
+         <property name="homogeneous">False</property>
+         <property name="spacing">0</property>
+
+         <child>
+           <widget class="GtkMenuBar" id="MenuMain">
+             <property name="visible">True</property>
+
+             <child>
+               <widget class="GtkMenuItem" id="FileMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_File</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="FileMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="FileMenuNewTitle">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">New</property>
+                         <property name="use_underline">True</property>
+
+                         <child>
+                           <widget class="GtkMenu" id="FileMenuNewTitle_menu">
+
+                             <child>
+                               <widget class="GtkMenuItem" id="EmptyTraceset">
+                                 <property name="visible">True</property>
+                                 <property name="label" translatable="yes">Empty trace set</property>
+                                 <property name="use_underline">True</property>
+                                 <signal name="activate" handler="on_empty_traceset_activate" last_modification_time="Tue, 10 Jun 2003 15:03:01 GMT"/>
+                               </widget>
+                             </child>
+
+                             <child>
+                               <widget class="GtkMenuItem" id="CloneTraceset">
+                                 <property name="visible">True</property>
+                                 <property name="label" translatable="yes">Clone trace set</property>
+                                 <property name="use_underline">True</property>
+                                 <signal name="activate" handler="on_clone_traceset_activate" last_modification_time="Tue, 10 Jun 2003 15:03:22 GMT"/>
+                               </widget>
+                             </child>
+
+                             <child>
+                               <widget class="GtkMenuItem" id="FileMenuNewSep">
+                                 <property name="visible">True</property>
+                               </widget>
+                             </child>
+
+                             <child>
+                               <widget class="GtkMenuItem" id="Tab">
+                                 <property name="visible">True</property>
+                                 <property name="label" translatable="yes">Tab</property>
+                                 <property name="use_underline">True</property>
+                                 <signal name="activate" handler="on_tab_activate" last_modification_time="Tue, 10 Jun 2003 15:03:37 GMT"/>
+                               </widget>
+                             </child>
+                           </widget>
+                         </child>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="OpenTraceset">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Open</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_open_activate" last_modification_time="Tue, 10 Jun 2003 15:03:47 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Close">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Close</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_close_activate" last_modification_time="Tue, 10 Jun 2003 15:03:56 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="CloseTab">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Close Tab</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_close_tab_activate" last_modification_time="Tue, 10 Jun 2003 15:04:06 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="FileMenuSeparator1">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="AddTrace">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Add Trace</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_add_trace_activate" last_modification_time="Tue, 10 Jun 2003 15:04:14 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="RemoveTrace">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Remove Trace</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_remove_trace_activate" last_modification_time="Tue, 10 Jun 2003 15:04:24 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Save">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Save</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_save_activate" last_modification_time="Tue, 10 Jun 2003 15:04:36 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="SaveAs">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Save As</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_save_as_activate" last_modification_time="Tue, 10 Jun 2003 15:04:45 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="FileMenuSeparator2">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Quit">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Quit</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_quit_activate" last_modification_time="Tue, 10 Jun 2003 15:04:53 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="EditMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_Edit</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="EditMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Cut">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-cut</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_cut_activate" last_modification_time="Tue, 10 Jun 2003 15:05:00 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Copy">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-copy</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_copy_activate" last_modification_time="Tue, 10 Jun 2003 15:05:06 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Paste">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-paste</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_paste_activate" last_modification_time="Tue, 10 Jun 2003 15:05:14 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Delete">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-delete</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_delete_activate" last_modification_time="Tue, 10 Jun 2003 15:05:22 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="ViewMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_View</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="ViewMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ZoomIn">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Zoom in</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_zoom_in_activate" last_modification_time="Tue, 10 Jun 2003 15:05:30 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ZoomOut">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Zoom out</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_zoom_out_activate" last_modification_time="Tue, 10 Jun 2003 15:05:37 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ZoomExtended">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Zoom extended</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_zoom_extended_activate" last_modification_time="Tue, 10 Jun 2003 15:05:44 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ViewMenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="GoToTime">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Go to time</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_go_to_time_activate" last_modification_time="Tue, 10 Jun 2003 15:05:50 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ShowTimeFrame">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Show time frame</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_show_time_frame_activate" last_modification_time="Tue, 10 Jun 2003 15:06:00 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="ToolMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">Tools</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="ToolMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="MoveViewerUp">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Move viewer up</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_move_viewer_up_activate" last_modification_time="Tue, 10 Jun 2003 15:06:05 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="MoveViewerDown">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Move viewer down</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_move_viewer_down_activate" last_modification_time="Tue, 10 Jun 2003 15:06:14 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="RemoveViewer">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Remove viewer</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_remove_viewer_activate" last_modification_time="Tue, 10 Jun 2003 15:06:21 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ToolMenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="insert_viewer_test">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Insert viewer test</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_insert_viewer_test_activate" last_modification_time="Mon, 16 Jun 2003 16:43:52 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="PluginMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">Plugins</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="PluginMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="LoadModule">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Load module</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_load_module_activate" last_modification_time="Tue, 10 Jun 2003 15:06:30 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="UnloadModule">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Unload module</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_unload_module_activate" last_modification_time="Tue, 10 Jun 2003 15:06:39 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="AddModuleSearchPath">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Add module search path</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_add_module_search_path_activate" last_modification_time="Tue, 10 Jun 2003 15:06:50 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="OptionMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">Options</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="OptionMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Color">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Color</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_color_activate" last_modification_time="Tue, 10 Jun 2003 15:06:58 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="OptMenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="OpenFilter">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Filter</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_filter_activate" last_modification_time="Tue, 10 Jun 2003 15:07:04 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="SaveConfiguration">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Save configuration</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_save_configuration_activate" last_modification_time="Tue, 10 Jun 2003 15:07:12 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkMenuBar" id="MenuHelp">
+             <property name="visible">True</property>
+
+             <child>
+               <widget class="GtkMenuItem" id="HelpMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_Help</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="HelpMenu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Content">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Content</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_content_activate" last_modification_time="Tue, 10 Jun 2003 15:07:19 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="HelpmenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="About">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">About...</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_about_activate" last_modification_time="Tue, 10 Jun 2003 15:07:28 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+             <property name="pack_type">GTK_PACK_END</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkToolbar" id="MToolbar1">
+         <property name="visible">True</property>
+         <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+         <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+         <property name="tooltips">True</property>
+
+         <child>
+           <widget class="button" id="tlbEmptyTraceset">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">New window with empty trace set</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">filenew.png</property>
+             <signal name="clicked" handler="on_button_new_clicked" last_modification_time="Thu, 05 Jun 2003 18:24:14 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbOpenTraceset">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">open a trace set</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">fileopen.png</property>
+             <signal name="clicked" handler="on_button_open_clicked" last_modification_time="Thu, 05 Jun 2003 18:24:37 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbAddTrace">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Add a trace </property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">edit_add_22.png</property>
+             <signal name="clicked" handler="on_button_add_trace_clicked" last_modification_time="Thu, 05 Jun 2003 18:30:00 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbRemoveTrace">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Remove a trace</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">edit_remove_22.png</property>
+             <signal name="clicked" handler="on_button_remove_trace_clicked" last_modification_time="Thu, 05 Jun 2003 18:30:09 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbSave">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">save the current trace set</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">filesave.png</property>
+             <signal name="clicked" handler="on_button_save_clicked" last_modification_time="Thu, 05 Jun 2003 18:25:30 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbSaveAs">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">save as </property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">filesaveas.png</property>
+             <signal name="clicked" handler="on_button_save_as_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:10 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbZoomIn">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Zoom in</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">stock_zoom_in_24.png</property>
+             <property name="new_group">True</property>
+             <signal name="clicked" handler="on_button_zoom_in_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:01 GMT"/>
+           </widget>
+           <packing>
+             <property name="new_group">True</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbZoomOut">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Zoom out</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">stock_zoom_out_24.png</property>
+             <signal name="clicked" handler="on_button_zoom_out_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:32 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbZoomExtended">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Zoom extended</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">stock_zoom_fit_24.png</property>
+             <signal name="clicked" handler="on_button_zoom_extended_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:48 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbGoToTime">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Go to time</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">gtk-jump-to.png</property>
+             <signal name="clicked" handler="on_button_go_to_time_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:07 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbShowTimeFrame">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Show time frame</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">mini-display.xpm</property>
+             <signal name="clicked" handler="on_button_show_time_frame_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:21 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbMoveViewerUp">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Move up current viewer</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">1uparrow.png</property>
+             <property name="new_group">True</property>
+             <signal name="clicked" handler="on_button_move_up_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:41 GMT"/>
+           </widget>
+           <packing>
+             <property name="new_group">True</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbMoveViewerDown">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Move down current viewer</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">1downarrow.png</property>
+             <signal name="clicked" handler="on_button_move_down_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:59 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbRemoveViewer">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Delete current viewer</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">remove.png</property>
+             <signal name="clicked" handler="on_button_delete_viewer_clicked" last_modification_time="Thu, 05 Jun 2003 18:29:26 GMT"/>
+           </widget>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkToolbar" id="MToolbar2">
+         <property name="visible">True</property>
+         <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+         <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
+         <property name="tooltips">True</property>
+
+         <child>
+           <placeholder/>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkNotebook" id="MNotebook">
+         <property name="visible">True</property>
+         <property name="can_focus">True</property>
+         <property name="show_tabs">True</property>
+         <property name="show_border">True</property>
+         <property name="tab_pos">GTK_POS_TOP</property>
+         <property name="scrollable">False</property>
+         <property name="enable_popup">False</property>
+         <signal name="switch_page" handler="on_MNotebook_switch_page" last_modification_time="Tue, 17 Jun 2003 17:00:29 GMT"/>
+
+         <child>
+           <placeholder/>
+         </child>
+
+         <child>
+           <widget class="GtkLabel" id="label1">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">False</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+           </widget>
+           <packing>
+             <property name="type">tab</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkStatusbar" id="MStatusbar">
+         <property name="visible">True</property>
+         <property name="has_resize_grip">True</property>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/glade/lttvwindow.gladep b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/glade/lttvwindow.gladep
new file mode 100644 (file)
index 0000000..3158684
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+  <name>MainWin</name>
+  <program_name>mainwin</program_name>
+  <gnome_support>FALSE</gnome_support>
+  <gettext_support>FALSE</gettext_support>
+  <output_build_files>FALSE</output_build_files>
+  <backup_source_files>FALSE</backup_source_files>
+</glade-project>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/Makefile.am
new file mode 100644 (file)
index 0000000..25ca2ec
--- /dev/null
@@ -0,0 +1,43 @@
+## Process this file with automake to produce Makefile.in
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS)
+
+INCLUDES = \
+       -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+       -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+       @PACKAGE_CFLAGS@ \
+       $(DEFAULT_INCLUDES)
+
+#libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = liblttvwindow.la
+
+
+liblttvwindow_la_SOURCES = \
+       toolbar.c\
+       menu.c\
+       lttvwindow.c \
+       lttvwindowtraces.c \
+       init_module.c \
+       support.c \
+       interface.c \
+       callbacks.c
+
+noinst_HEADERS = \
+       support.h \
+       interface.h \
+       callbacks.h\
+       mainwindow-private.h
+
+lttvwindowinclude_HEADERS = \
+       lttvwindow.h\
+       lttvwindowtraces.h\
+       mainwindow.h\
+       menu.h\
+       toolbar.h
+
+liblttvwindow_la_LIBADD = @PACKAGE_LIBS@ $(INTLLIBS)
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c
new file mode 100644 (file)
index 0000000..03b8afb
--- /dev/null
@@ -0,0 +1,4566 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang, Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <limits.h> // for PATH_MAX
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <ltt/time.h>
+#include <ltt/event.h>
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttv/iattribute.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+#include <lttvwindow/mainwindow.h>
+#include <lttvwindow/mainwindow-private.h>
+#include <lttvwindow/menu.h>
+#include <lttvwindow/toolbar.h>
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+
+
+static LttTime lttvwindow_default_time_width = { 1, 0 };
+#define CLIP_BUF 256 // size of clipboard buffer
+
+extern LttvTrace *g_init_trace ;
+
+
+/** Array containing instanced objects. */
+extern GSList * g_main_window_list;
+
+/** MD : keep old directory. */
+static char remember_plugins_dir[PATH_MAX] = "";
+static char remember_trace_dir[PATH_MAX] = "";
+
+
+MainWindow * get_window_data_struct(GtkWidget * widget);
+char * get_load_module(MainWindow *mw,
+    char ** load_module_name, int nb_module);
+char * get_unload_module(MainWindow *mw,
+    char ** loaded_module_name, int nb_module);
+char * get_remove_trace(MainWindow *mw, char ** all_trace_name, int nb_trace);
+char * get_selection(MainWindow *mw,
+    char ** all_name, int nb, char *title, char * column_title);
+Tab* create_tab(MainWindow * mw, Tab *copy_tab,
+                 GtkNotebook * notebook, char * label);
+
+static void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
+
+Tab *create_new_tab(GtkWidget* widget, gpointer user_data);
+
+static gboolean lttvwindow_process_pending_requests(Tab *tab);
+
+enum {
+  CHECKBOX_COLUMN,
+  NAME_COLUMN,
+  TOTAL_COLUMNS
+};
+
+enum
+{
+  MODULE_COLUMN,
+  N_COLUMNS
+};
+
+/* Pasting routines */
+
+static void MEventBox1a_receive(GtkClipboard *clipboard,
+                          const gchar *text,
+                          gpointer data)
+{
+  if(text == NULL) return;
+  Tab *tab = (Tab *)data;
+  gchar buffer[CLIP_BUF];
+  gchar *ptr = buffer, *ptr_ssec, *ptr_snsec, *ptr_esec, *ptr_ensec;
+
+  strncpy(buffer, text, CLIP_BUF);
+  /* start */
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_ssec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+  ptr++;
+
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_snsec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+
+  /* end */ 
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_esec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+  ptr++;
+
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_ensec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
+                            (double)strtoul(ptr_ssec, NULL, 10));
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
+                            (double)strtoul(ptr_snsec, NULL, 10));
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
+                            (double)strtoul(ptr_esec, NULL, 10));
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
+                            (double)strtoul(ptr_ensec, NULL, 10));
+}
+
+static gboolean on_MEventBox1a_paste(GtkWidget *widget, GdkEventButton *event,
+                                gpointer data)
+{
+  Tab *tab = (Tab*)data;
+
+  GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
+                                                     GDK_SELECTION_PRIMARY);
+  gtk_clipboard_request_text(clip,
+                             (GtkClipboardTextReceivedFunc)MEventBox1a_receive,
+                             (gpointer)tab);
+  return 0;
+}
+
+
+/* Start */
+static void MEventBox1b_receive(GtkClipboard *clipboard,
+                          const gchar *text,
+                          gpointer data)
+{
+  if(text == NULL) return;
+  Tab *tab = (Tab *)data;
+  gchar buffer[CLIP_BUF];
+  gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
+
+  strncpy(buffer, text, CLIP_BUF);
+  
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_sec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+  ptr++;
+
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_nsec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
+                            (double)strtoul(ptr_sec, NULL, 10));
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
+                            (double)strtoul(ptr_nsec, NULL, 10));
+}
+
+/* Start */
+static gboolean on_MEventBox1b_paste(GtkWidget *widget, GdkEventButton *event,
+                                gpointer data)
+{
+  Tab *tab = (Tab*)data;
+
+  GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
+                                                     GDK_SELECTION_PRIMARY);
+  gtk_clipboard_request_text(clip,
+                             (GtkClipboardTextReceivedFunc)MEventBox1b_receive,
+                             (gpointer)tab);
+  return 0;
+}
+
+/* End */
+static void MEventBox3b_receive(GtkClipboard *clipboard,
+                          const gchar *text,
+                          gpointer data)
+{
+  if(text == NULL) return;
+  Tab *tab = (Tab *)data;
+  gchar buffer[CLIP_BUF];
+  gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
+
+  strncpy(buffer, text, CLIP_BUF);
+  
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_sec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+  ptr++;
+
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_nsec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
+                            (double)strtoul(ptr_sec, NULL, 10));
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
+                            (double)strtoul(ptr_nsec, NULL, 10));
+}
+
+/* End */
+static gboolean on_MEventBox3b_paste(GtkWidget *widget, GdkEventButton *event,
+                                gpointer data)
+{
+  Tab *tab = (Tab*)data;
+
+  GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
+                                                     GDK_SELECTION_PRIMARY);
+  gtk_clipboard_request_text(clip,
+                             (GtkClipboardTextReceivedFunc)MEventBox3b_receive,
+                             (gpointer)tab);
+  return 0;
+}
+
+/* Current */
+static void MEventBox5b_receive(GtkClipboard *clipboard,
+                          const gchar *text,
+                          gpointer data)
+{
+  if(text == NULL) return;
+  Tab *tab = (Tab *)data;
+  gchar buffer[CLIP_BUF];
+  gchar *ptr = buffer, *ptr_sec, *ptr_nsec;
+
+  strncpy(buffer, text, CLIP_BUF);
+  
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_sec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+  ptr++;
+
+  while(!isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                       /* remove leading junk */
+  ptr_nsec = ptr;
+  while(isdigit(*ptr) && ptr < buffer+CLIP_BUF-1) ptr++;
+                                                 /* read all the first number */
+  *ptr = '\0';
+
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
+                            (double)strtoul(ptr_sec, NULL, 10));
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
+                            (double)strtoul(ptr_nsec, NULL, 10));
+}
+
+/* Current */
+static gboolean on_MEventBox5b_paste(GtkWidget *widget, GdkEventButton *event,
+                                gpointer data)
+{
+  Tab *tab = (Tab*)data;
+
+  GtkClipboard *clip = gtk_clipboard_get_for_display(gdk_display_get_default(),
+                                                     GDK_SELECTION_PRIMARY);
+  gtk_clipboard_request_text(clip,
+                             (GtkClipboardTextReceivedFunc)MEventBox5b_receive,
+                             (gpointer)tab);
+  return 0;
+}
+
+
+static gboolean viewer_grab_focus(GtkWidget *widget, GdkEventButton *event,
+                                  gpointer data)
+{
+  GtkWidget *viewer = GTK_WIDGET(data);
+  GtkWidget *viewer_container = gtk_widget_get_parent(viewer);
+
+  g_debug("FOCUS GRABBED");
+  g_object_set_data(G_OBJECT(viewer_container), "focused_viewer", viewer);
+  return 0;
+}
+
+
+static void connect_focus_recursive(GtkWidget *widget,
+                                    GtkWidget *viewer)
+{
+  if(GTK_IS_CONTAINER(widget)) {
+    gtk_container_forall(GTK_CONTAINER(widget),
+                         (GtkCallback)connect_focus_recursive,
+                         viewer);
+
+  }
+  if(GTK_IS_TREE_VIEW(widget)) {
+    gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(widget), TRUE);
+  }
+  gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK);
+  g_signal_connect (G_OBJECT(widget),
+                    "button-press-event",
+                    G_CALLBACK (viewer_grab_focus),
+                    (gpointer)viewer);
+}
+
+/* Stop all the processings and call gtk_main_quit() */
+static void mainwindow_quit()
+{
+  lttvwindowtraces_unregister_requests(g_quark_from_string("stats"));
+  lttvwindowtraces_unregister_requests(g_quark_from_string("state"));
+  lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("stats"));
+  lttvwindowtraces_unregister_computation_hooks(g_quark_from_string("state"));
+
+  gtk_main_quit();
+}
+
+
+/* insert_viewer function constructs an instance of a viewer first,
+ * then inserts the widget of the instance into the container of the
+ * main window
+ */
+
+void
+insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
+{
+  insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
+}
+
+
+/* internal functions */
+void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
+{
+  GtkWidget * viewer_container;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+  GtkWidget * viewer;
+  TimeInterval * time_interval;
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+  
+  if(!page) {
+    tab = create_new_tab(widget, NULL);
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  viewer_container = tab->viewer_container;
+
+  viewer = (GtkWidget*)constructor(tab);
+  if(viewer)
+  {
+    //gtk_multivpaned_widget_add(GTK_MULTIVPANED(multivpaned), viewer); 
+    
+    gtk_box_pack_end(GTK_BOX(viewer_container),
+                     viewer,
+                     TRUE,
+                     TRUE,
+                     0);
+
+    /* We want to connect the viewer_grab_focus to EVERY
+     * child of this widget. The little trick is to get each child
+     * of each GTK_CONTAINER, even subchildren.
+     */
+    connect_focus_recursive(viewer, viewer);
+  }
+}
+
+/**
+ * Function to set/update traceset for the viewers
+ * @param tab viewer's tab 
+ * @param traceset traceset of the main window.
+ * return value :
+ *  0 : traceset updated
+ *  1 : no traceset hooks to update; not an error.
+ */
+
+int SetTraceset(Tab * tab, LttvTraceset *traceset)
+{
+  LttvTracesetContext *tsc =
+        LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  TimeWindow new_time_window = tab->time_window;
+  LttTime new_current_time = tab->current_time;
+
+  /* Set the tab's time window and current time if
+   * out of bounds */
+  if(ltt_time_compare(tab->time_window.start_time, time_span.start_time) < 0
+     || ltt_time_compare(tab->time_window.end_time,
+                           time_span.end_time) > 0) {
+    new_time_window.start_time = time_span.start_time;
+    
+    new_current_time = time_span.start_time;
+    
+    LttTime tmp_time;
+    
+    if(ltt_time_compare(lttvwindow_default_time_width,
+          ltt_time_sub(time_span.end_time, time_span.start_time)) < 0
+        ||
+       ltt_time_compare(time_span.end_time, time_span.start_time) == 0)
+      tmp_time = lttvwindow_default_time_width;
+    else
+      tmp_time = time_span.end_time;
+
+    new_time_window.time_width = tmp_time ;
+    new_time_window.time_width_double = ltt_time_to_double(tmp_time);
+    new_time_window.end_time = ltt_time_add(new_time_window.start_time,
+                                            new_time_window.time_width) ;
+  }
+
+#if 0
+  /* Set scrollbar */
+  GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
+  LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
+      
+  g_object_set(G_OBJECT(adjustment),
+               "lower",
+                 0.0, /* lower */
+               "upper",
+               ltt_time_to_double(upper) 
+                 * NANOSECONDS_PER_SECOND, /* upper */
+               "step_increment",
+               ltt_time_to_double(tab->time_window.time_width)
+                             / SCROLL_STEP_PER_PAGE
+                             * NANOSECONDS_PER_SECOND, /* step increment */
+               "page_increment",
+               ltt_time_to_double(tab->time_window.time_width) 
+                 * NANOSECONDS_PER_SECOND, /* page increment */
+               "page_size",
+               ltt_time_to_double(tab->time_window.time_width) 
+                 * NANOSECONDS_PER_SECOND, /* page size */
+               NULL);
+  gtk_adjustment_changed(adjustment);
+
+  g_object_set(G_OBJECT(adjustment),
+               "value",
+               ltt_time_to_double(
+                ltt_time_sub(tab->time_window.start_time, time_span.start_time))
+                   * NANOSECONDS_PER_SECOND, /* value */
+               NULL);
+  gtk_adjustment_value_changed(adjustment);
+
+  /* set the time bar. The value callbacks will change their nsec themself */
+  /* start seconds */
+  gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
+                            (double)time_span.start_time.tv_sec,
+                            (double)time_span.end_time.tv_sec);
+
+  /* end seconds */
+  gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
+                            (double)time_span.start_time.tv_sec,
+                            (double)time_span.end_time.tv_sec);
+
+   /* current seconds */
+  gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
+                            (double)time_span.start_time.tv_sec,
+                            (double)time_span.end_time.tv_sec);
+#endif //0
+  
+  /* Finally, call the update hooks of the viewers */
+  LttvHooks * tmp;
+  LttvAttributeValue value;
+  gint retval = 0;
+
+  g_assert( lttv_iattribute_find_by_path(tab->attributes,
+     "hooks/updatetraceset", LTTV_POINTER, &value));
+
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) retval = 1;
+  else lttv_hooks_call(tmp,traceset);
+
+  time_change_manager(tab, new_time_window);
+  current_time_change_manager(tab, new_current_time);
+
+  return retval;
+}
+
+/**
+ * Function to set/update filter for the viewers
+ * @param tab viewer's tab 
+ * @param filter filter of the main window.
+ * return value :
+ * -1 : error
+ *  0 : filters updated
+ *  1 : no filter hooks to update; not an error.
+ */
+#if 0
+int SetFilter(Tab * tab, gpointer filter)
+{
+  LttvHooks * tmp;
+  LttvAttributeValue value;
+
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+     "hooks/updatefilter", LTTV_POINTER, &value));
+
+  tmp = (LttvHooks*)*(value.v_pointer);
+
+  if(tmp == NULL) return 1;
+  lttv_hooks_call(tmp,filter);
+
+  return 0;
+}
+#endif //0
+
+
+/**
+ * Function to redraw each viewer belonging to the current tab 
+ * @param tab viewer's tab 
+ */
+
+void update_traceset(Tab *tab)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatetraceset", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_call(tmp, NULL);
+}
+
+
+/* get_label function is used to get user input, it displays an input
+ * box, which allows user to input a string 
+ */
+
+void get_label_string (GtkWidget * text, gchar * label) 
+{
+  GtkEntry * entry = (GtkEntry*)text;
+  if(strlen(gtk_entry_get_text(entry))!=0)
+    strcpy(label,gtk_entry_get_text(entry)); 
+}
+
+gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
+{
+  GtkWidget * dialogue;
+  GtkWidget * text;
+  GtkWidget * label;
+  gint id;
+
+  dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
+                                        GTK_DIALOG_MODAL,
+                                        GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
+                                        GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
+                                        NULL); 
+
+  label = gtk_label_new(label_str);
+  gtk_widget_show(label);
+
+  text = gtk_entry_new();
+  gtk_widget_show(text);
+
+  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
+  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
+
+  id = gtk_dialog_run(GTK_DIALOG(dialogue));
+  switch(id){
+    case GTK_RESPONSE_ACCEPT:
+      get_label_string(text,str);
+      gtk_widget_destroy(dialogue);
+      break;
+    case GTK_RESPONSE_REJECT:
+    default:
+      gtk_widget_destroy(dialogue);
+      return FALSE;
+  }
+  return TRUE;
+}
+
+
+/* get_window_data_struct function is actually a lookup function,
+ * given a widget which is in the tree of the main window, it will
+ * return the MainWindow data structure associated with main window
+ */
+
+MainWindow * get_window_data_struct(GtkWidget * widget)
+{
+  GtkWidget * mw;
+  MainWindow * mw_data;
+
+  mw = lookup_widget(widget, "MWindow");
+  if(mw == NULL){
+    g_info("Main window does not exist\n");
+    return NULL;
+  }
+  
+  mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"main_window_data");
+  if(mw_data == NULL){
+    g_warning("Main window data does not exist\n");
+    return NULL;
+  }
+  return mw_data;
+}
+
+
+/* create_new_window function, just constructs a new main window
+ */
+
+void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
+{
+  MainWindow * parent = get_window_data_struct(widget);
+
+  if(clone){
+    g_info("Clone : use the same traceset\n");
+    construct_main_window(parent);
+  }else{
+    g_info("Empty : traceset is set to NULL\n");
+    construct_main_window(NULL);
+  }
+}
+
+/* Get the currently focused viewer.
+ * If no viewer is focused, use the first one.
+ *
+ * If no viewer available, return NULL.
+ */
+GtkWidget *viewer_container_focus(GtkWidget *container)
+{
+  GtkWidget *widget;
+
+  widget = (GtkWidget*)g_object_get_data(G_OBJECT(container),
+                                         "focused_viewer");
+
+  if(widget == NULL) {
+    g_debug("no widget focused");
+    GList *children = gtk_container_get_children(GTK_CONTAINER(container));
+
+    if(children != NULL)
+      widget = GTK_WIDGET(children->data);
+      g_object_set_data(G_OBJECT(container),
+                        "focused_viewer",
+                        widget);
+  }
+  
+  return widget;
+
+
+}
+
+gint viewer_container_position(GtkWidget *container, GtkWidget *child)
+{
+
+  if(child == NULL) return -1;
+
+  gint pos;
+  GValue value;
+  memset(&value, 0, sizeof(GValue));
+  g_value_init(&value, G_TYPE_INT);
+  gtk_container_child_get_property(GTK_CONTAINER(container),
+                                   child,
+                                   "position",
+                                   &value);
+  pos = g_value_get_int(&value);
+
+  return pos;
+}
+
+
+/* move_*_viewer functions move the selected view up/down in 
+ * the current tab
+ */
+
+void move_down_viewer(GtkWidget * widget, gpointer user_data)
+{
+  MainWindow * mw = get_window_data_struct(widget);
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+
+  Tab *tab;
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  //gtk_multivpaned_widget_move_up(GTK_MULTIVPANED(tab->multivpaned));
+
+  /* change the position in the vbox */
+  GtkWidget *focus_widget;
+  gint position;
+  focus_widget = viewer_container_focus(tab->viewer_container);
+  position = viewer_container_position(tab->viewer_container, focus_widget);
+
+  if(position > 0) {
+    /* can move up one position */
+    gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
+                          focus_widget,
+                          position-1);
+  }
+  
+}
+
+void move_up_viewer(GtkWidget * widget, gpointer user_data)
+{
+  MainWindow * mw = get_window_data_struct(widget);
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  //gtk_multivpaned_widget_move_down(GTK_MULTIVPANED(tab->multivpaned));
+  /* change the position in the vbox */
+  GtkWidget *focus_widget;
+  gint position;
+  focus_widget = viewer_container_focus(tab->viewer_container);
+  position = viewer_container_position(tab->viewer_container, focus_widget);
+
+  if(position != -1 &&
+  position <
+       g_list_length(gtk_container_get_children(
+                        GTK_CONTAINER(tab->viewer_container)))-1
+      ) {
+    /* can move down one position */
+    gtk_box_reorder_child(GTK_BOX(tab->viewer_container),
+                          focus_widget,
+                          position+1);
+  }
+}
+
+
+/* delete_viewer deletes the selected viewer in the current tab
+ */
+
+void delete_viewer(GtkWidget * widget, gpointer user_data)
+{
+  MainWindow * mw = get_window_data_struct(widget);
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  //gtk_multivpaned_widget_delete(GTK_MULTIVPANED(tab->multivpaned));
+
+  GtkWidget *focus_widget = viewer_container_focus(tab->viewer_container);
+  
+  if(focus_widget != NULL)
+    gtk_widget_destroy(focus_widget);
+
+  g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
+}
+
+
+/* open_traceset will open a traceset saved in a file
+ * Right now, it is not finished yet, (not working)
+ * FIXME
+ */
+
+void open_traceset(GtkWidget * widget, gpointer user_data)
+{
+  char ** dir;
+  gint id;
+  LttvTraceset * traceset;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  GtkFileSelection * file_selector = 
+    (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
+
+  gtk_file_selection_hide_fileop_buttons(file_selector);
+  
+  gtk_window_set_transient_for(GTK_WINDOW(file_selector),
+      GTK_WINDOW(mw_data->mwindow));
+
+  id = gtk_dialog_run(GTK_DIALOG(file_selector));
+  switch(id){
+    case GTK_RESPONSE_ACCEPT:
+    case GTK_RESPONSE_OK:
+      dir = gtk_file_selection_get_selections (file_selector);
+      traceset = lttv_traceset_load(dir[0]);
+      g_info("Open a trace set %s\n", dir[0]); 
+      //Not finished yet
+      g_strfreev(dir);
+    case GTK_RESPONSE_REJECT:
+    case GTK_RESPONSE_CANCEL:
+    default:
+      gtk_widget_destroy((GtkWidget*)file_selector);
+      break;
+  }
+
+}
+
+/* lttvwindow_process_pending_requests
+ * 
+ * This internal function gets called by g_idle, taking care of the pending
+ * requests. It is responsible for concatenation of time intervals and position
+ * requests. It does it with the following algorithm organizing process traceset
+ * calls. Here is the detailed description of the way it works :
+ *
+ * - Events Requests Servicing Algorithm
+ *
+ *   Data structures necessary :
+ *
+ *   List of requests added to context : list_in
+ *   List of requests not added to context : list_out
+ *
+ *   Initial state :
+ *
+ *   list_in : empty
+ *   list_out : many events requests
+ *
+ *  FIXME : insert rest of algorithm here
+ *
+ */
+
+#define list_out tab->events_requests
+
+gboolean lttvwindow_process_pending_requests(Tab *tab)
+{
+  GtkWidget* widget;
+  LttvTracesetContext *tsc;
+  LttvTracefileContext *tfc;
+  GSList *list_in = NULL;
+  LttTime end_time;
+  guint end_nb_events;
+  guint count;
+  LttvTracesetContextPosition *end_position;
+  
+  if(tab == NULL) {
+    g_critical("Foreground processing : tab does not exist. Processing removed.");
+    return FALSE;
+  }
+
+  /* There is no events requests pending : we should never have been called! */
+  g_assert(g_slist_length(list_out) != 0);
+
+  tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+
+  //set the cursor to be X shape, indicating that the computer is busy in doing its job
+#if 0
+  new = gdk_cursor_new(GDK_X_CURSOR);
+  widget = lookup_widget(tab->mw->mwindow, "MToolbar1");
+  win = gtk_widget_get_parent_window(widget);  
+  gdk_window_set_cursor(win, new);
+  gdk_cursor_unref(new);  
+  gdk_window_stick(win);
+  gdk_window_unstick(win);
+#endif //0
+
+  g_debug("SIZE events req len  : %d", g_slist_length(list_out));
+  
+  /* Preliminary check for no trace in traceset */
+  /* Unregister the routine if empty, empty list_out too */
+  if(lttv_traceset_number(tsc->ts) == 0) {
+
+    /* - For each req in list_out */
+    GSList *iter = list_out;
+
+    while(iter != NULL) {
+
+      gboolean remove = FALSE;
+      gboolean free_data = FALSE;
+      EventsRequest *events_request = (EventsRequest *)iter->data;
+      
+      /* - Call end request for req */
+      if(events_request->servicing == TRUE)
+        lttv_hooks_call(events_request->after_request, (gpointer)tsc);
+      
+      /* - remove req from list_out */
+      /* Destroy the request */
+      remove = TRUE;
+      free_data = TRUE;
+
+      /* Go to next */
+      if(remove)
+      {
+        GSList *remove_iter = iter;
+
+        iter = g_slist_next(iter);
+        if(free_data) events_request_free((EventsRequest*)remove_iter->data);
+        list_out = g_slist_remove_link(list_out, remove_iter);
+      } else { // not remove
+        iter = g_slist_next(iter);
+      }
+    }
+  }
+  
+  /* 0.1 Lock Traces */
+  {
+    guint iter_trace=0;
+    
+    for(iter_trace=0; 
+        iter_trace<lttv_traceset_number(tsc->ts);
+        iter_trace++) {
+      LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
+
+      if(lttvwindowtraces_lock(trace_v) != 0) {
+        g_critical("Foreground processing : Unable to get trace lock");
+        return TRUE; /* Cannot get lock, try later */
+      }
+    }
+  }
+
+  /* 0.2 Seek tracefiles positions to context position */
+  //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
+  lttv_process_traceset_synchronize_tracefiles(tsc);
+  
+  
+  /* Events processing algorithm implementation */
+  /* Warning : the gtk_events_pending takes a LOT of cpu time. So what we do
+   * instead is to leave the control to GTK and take it back.
+   */
+  /* A. Servicing loop */
+  //while( (g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
+  if((g_slist_length(list_in) != 0 || g_slist_length(list_out) != 0)) {
+    /* Servicing */
+    /* 1. If list_in is empty (need a seek) */
+    if( g_slist_length(list_in) ==  0 ) {
+
+      /* list in is empty, need a seek */
+      {
+        /* 1.1 Add requests to list_in */
+        GSList *ltime = NULL;
+        GSList *lpos = NULL;
+        GSList *iter = NULL;
+        
+        /* 1.1.1 Find all time requests with the lowest start time in list_out
+         * (ltime)
+         */
+        if(g_slist_length(list_out) > 0)
+          ltime = g_slist_append(ltime, g_slist_nth_data(list_out, 0));
+        for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
+          /* Find all time requests with the lowest start time in list_out */
+          EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
+          EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
+
+          int comp;
+          comp = ltt_time_compare(event_request_ltime->start_time,
+                                  event_request_list_out->start_time);
+          if(comp == 0)
+            ltime = g_slist_append(ltime, event_request_list_out);
+          else if(comp > 0) {
+            /* Remove all elements from ltime, and add current */
+            while(ltime != NULL)
+              ltime = g_slist_delete_link(ltime, g_slist_nth(ltime, 0));
+            ltime = g_slist_append(ltime, event_request_list_out);
+          }
+        }
+        
+        /* 1.1.2 Find all position requests with the lowest position in list_out
+         * (lpos)
+         */
+        if(g_slist_length(list_out) > 0)
+          lpos = g_slist_append(lpos, g_slist_nth_data(list_out, 0));
+        for(iter=g_slist_nth(list_out,1);iter!=NULL;iter=g_slist_next(iter)) {
+          /* Find all position requests with the lowest position in list_out */
+          EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
+          EventsRequest *event_request_list_out = (EventsRequest*)iter->data;
+
+          int comp;
+          if(event_request_lpos->start_position != NULL
+              && event_request_list_out->start_position != NULL)
+          {
+            comp = lttv_traceset_context_pos_pos_compare
+                                 (event_request_lpos->start_position,
+                                  event_request_list_out->start_position);
+          } else {
+            comp = -1;
+          }
+          if(comp == 0)
+            lpos = g_slist_append(lpos, event_request_list_out);
+          else if(comp > 0) {
+            /* Remove all elements from lpos, and add current */
+            while(lpos != NULL)
+              lpos = g_slist_delete_link(lpos, g_slist_nth(lpos, 0));
+            lpos = g_slist_append(lpos, event_request_list_out);
+          }
+        }
+        
+        {
+          EventsRequest *event_request_lpos = (EventsRequest*)g_slist_nth_data(lpos, 0);
+          EventsRequest *event_request_ltime = (EventsRequest*)g_slist_nth_data(ltime, 0);
+          LttTime lpos_start_time;
+          
+          if(event_request_lpos != NULL 
+              && event_request_lpos->start_position != NULL) {
+            lpos_start_time = lttv_traceset_context_position_get_time(
+                                      event_request_lpos->start_position);
+          }
+          
+          /* 1.1.3 If lpos.start time < ltime */
+          if(event_request_lpos != NULL
+              && event_request_lpos->start_position != NULL
+              && ltt_time_compare(lpos_start_time,
+                              event_request_ltime->start_time)<0) {
+            /* Add lpos to list_in, remove them from list_out */
+            for(iter=lpos;iter!=NULL;iter=g_slist_next(iter)) {
+              /* Add to list_in */
+              EventsRequest *event_request_lpos = 
+                                    (EventsRequest*)iter->data;
+
+              list_in = g_slist_append(list_in, event_request_lpos);
+              /* Remove from list_out */
+              list_out = g_slist_remove(list_out, event_request_lpos);
+            }
+          } else {
+            /* 1.1.4 (lpos.start time >= ltime) */
+            /* Add ltime to list_in, remove them from list_out */
+
+            for(iter=ltime;iter!=NULL;iter=g_slist_next(iter)) {
+              /* Add to list_in */
+              EventsRequest *event_request_ltime = 
+                                    (EventsRequest*)iter->data;
+
+              list_in = g_slist_append(list_in, event_request_ltime);
+              /* Remove from list_out */
+              list_out = g_slist_remove(list_out, event_request_ltime);
+            }
+          }
+        }
+        g_slist_free(lpos);
+        g_slist_free(ltime);
+      }
+
+      /* 1.2 Seek */
+      {
+        tfc = lttv_traceset_context_get_current_tfc(tsc);
+        g_assert(g_slist_length(list_in)>0);
+        EventsRequest *events_request = g_slist_nth_data(list_in, 0);
+        guint seek_count;
+
+        /* 1.2.1 If first request in list_in is a time request */
+        if(events_request->start_position == NULL) {
+          /* - If first req in list_in start time != current time */
+          if(tfc == NULL || ltt_time_compare(events_request->start_time,
+                              tfc->timestamp) != 0)
+            /* - Seek to that time */
+            g_debug("SEEK TIME : %lu, %lu", events_request->start_time.tv_sec,
+              events_request->start_time.tv_nsec);
+            //lttv_process_traceset_seek_time(tsc, events_request->start_time);
+            lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
+                                                  events_request->start_time);
+
+            /* Process the traceset with only state hooks */
+            seek_count =
+               lttv_process_traceset_middle(tsc,
+                                            events_request->start_time,
+                                            G_MAXUINT, NULL);
+#ifdef DEBUG
+            g_assert(seek_count < LTTV_STATE_SAVE_INTERVAL);
+#endif //DEBUG
+
+
+        } else {
+          LttTime pos_time;
+          /* Else, the first request in list_in is a position request */
+          /* If first req in list_in pos != current pos */
+          g_assert(events_request->start_position != NULL);
+          g_debug("SEEK POS time : %lu, %lu", 
+                 lttv_traceset_context_position_get_time(
+                      events_request->start_position).tv_sec,
+                 lttv_traceset_context_position_get_time(
+                      events_request->start_position).tv_nsec);
+
+          g_debug("SEEK POS context time : %lu, %lu", 
+               lttv_traceset_context_get_current_tfc(tsc)->timestamp.tv_sec,
+               lttv_traceset_context_get_current_tfc(tsc)->timestamp.tv_nsec);
+          g_assert(events_request->start_position != NULL);
+          if(lttv_traceset_context_ctx_pos_compare(tsc,
+                     events_request->start_position) != 0) {
+            /* 1.2.2.1 Seek to that position */
+            g_debug("SEEK POSITION");
+            //lttv_process_traceset_seek_position(tsc, events_request->start_position);
+            pos_time = lttv_traceset_context_position_get_time(
+                                     events_request->start_position);
+            
+            lttv_state_traceset_seek_time_closest(LTTV_TRACESET_STATE(tsc),
+                                                  pos_time);
+
+            /* Process the traceset with only state hooks */
+            seek_count =
+               lttv_process_traceset_middle(tsc,
+                                            ltt_time_infinite,
+                                            G_MAXUINT,
+                                            events_request->start_position);
+            g_assert(lttv_traceset_context_ctx_pos_compare(tsc,
+                         events_request->start_position) == 0);
+
+
+          }
+        }
+      }
+
+      /* 1.3 Add hooks and call before request for all list_in members */
+      {
+        GSList *iter = NULL;
+
+        for(iter=list_in;iter!=NULL;iter=g_slist_next(iter)) {
+          EventsRequest *events_request = (EventsRequest*)iter->data;
+          /* 1.3.1 If !servicing */
+          if(events_request->servicing == FALSE) {
+            /* - begin request hooks called
+             * - servicing = TRUE
+             */
+            lttv_hooks_call(events_request->before_request, (gpointer)tsc);
+            events_request->servicing = TRUE;
+          }
+          /* 1.3.2 call before chunk
+           * 1.3.3 events hooks added
+           */
+          if(events_request->trace == -1)
+            lttv_process_traceset_begin(tsc,
+                events_request->before_chunk_traceset,
+                events_request->before_chunk_trace,
+                events_request->before_chunk_tracefile,
+                events_request->event,
+                events_request->event_by_id);
+          else {
+            guint nb_trace = lttv_traceset_number(tsc->ts);
+            g_assert((guint)events_request->trace < nb_trace &&
+                      events_request->trace > -1);
+            LttvTraceContext *tc = tsc->traces[events_request->trace];
+
+            lttv_hooks_call(events_request->before_chunk_traceset, tsc);
+
+            lttv_trace_context_add_hooks(tc,
+                                         events_request->before_chunk_trace,
+                                         events_request->before_chunk_tracefile,
+                                         events_request->event,
+                                         events_request->event_by_id);
+          }
+        }
+      }
+    } else {
+      /* 2. Else, list_in is not empty, we continue a read */
+      
+      {
+        /* 2.0 For each req of list_in */
+        GSList *iter = list_in;
+    
+        while(iter != NULL) {
+
+          EventsRequest *events_request = (EventsRequest *)iter->data;
+          
+          /* - Call before chunk
+           * - events hooks added
+           */
+          if(events_request->trace == -1)
+            lttv_process_traceset_begin(tsc,
+                events_request->before_chunk_traceset,
+                events_request->before_chunk_trace,
+                events_request->before_chunk_tracefile,
+                events_request->event,
+                events_request->event_by_id);
+          else {
+            guint nb_trace = lttv_traceset_number(tsc->ts);
+            g_assert((guint)events_request->trace < nb_trace &&
+                      events_request->trace > -1);
+            LttvTraceContext *tc = tsc->traces[events_request->trace];
+
+            lttv_hooks_call(events_request->before_chunk_traceset, tsc);
+
+            lttv_trace_context_add_hooks(tc,
+                                         events_request->before_chunk_trace,
+                                         events_request->before_chunk_tracefile,
+                                         events_request->event,
+                                         events_request->event_by_id);
+          }
+
+          iter = g_slist_next(iter);
+        }
+      }
+
+      {
+        tfc = lttv_traceset_context_get_current_tfc(tsc);
+      
+        /* 2.1 For each req of list_out */
+        GSList *iter = list_out;
+    
+        while(iter != NULL) {
+
+          gboolean remove = FALSE;
+          gboolean free_data = FALSE;
+          EventsRequest *events_request = (EventsRequest *)iter->data;
+          
+          /* if req.start time == current context time 
+           * or req.start position == current position*/
+          if(  ltt_time_compare(events_request->start_time,
+                              tfc->timestamp) == 0 
+             ||
+               (events_request->start_position != NULL 
+               &&
+               lttv_traceset_context_ctx_pos_compare(tsc,
+                       events_request->start_position) == 0)
+             ) {
+            /* - Add to list_in, remove from list_out */
+            list_in = g_slist_append(list_in, events_request);
+            remove = TRUE;
+            free_data = FALSE;
+
+            /* - If !servicing */
+            if(events_request->servicing == FALSE) {
+              /* - begin request hooks called
+               * - servicing = TRUE
+               */
+              lttv_hooks_call(events_request->before_request, (gpointer)tsc);
+              events_request->servicing = TRUE;
+            }
+            /* call before chunk
+             * events hooks added
+             */
+            if(events_request->trace == -1)
+              lttv_process_traceset_begin(tsc,
+                  events_request->before_chunk_traceset,
+                  events_request->before_chunk_trace,
+                  events_request->before_chunk_tracefile,
+                  events_request->event,
+                  events_request->event_by_id);
+            else {
+              guint nb_trace = lttv_traceset_number(tsc->ts);
+              g_assert((guint)events_request->trace < nb_trace &&
+                        events_request->trace > -1);
+              LttvTraceContext *tc = tsc->traces[events_request->trace];
+
+              lttv_hooks_call(events_request->before_chunk_traceset, tsc);
+
+              lttv_trace_context_add_hooks(tc,
+                                           events_request->before_chunk_trace,
+                                           events_request->before_chunk_tracefile,
+                                           events_request->event,
+                                           events_request->event_by_id);
+          }
+
+
+          }
+
+          /* Go to next */
+          if(remove)
+          {
+            GSList *remove_iter = iter;
+
+            iter = g_slist_next(iter);
+            if(free_data) events_request_free((EventsRequest*)remove_iter->data);
+            list_out = g_slist_remove_link(list_out, remove_iter);
+          } else { // not remove
+            iter = g_slist_next(iter);
+          }
+        }
+      }
+    }
+
+    /* 3. Find end criterions */
+    {
+      /* 3.1 End time */
+      GSList *iter;
+      
+      /* 3.1.1 Find lowest end time in list_in */
+      g_assert(g_slist_length(list_in)>0);
+      end_time = ((EventsRequest*)g_slist_nth_data(list_in,0))->end_time;
+      
+      for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
+        EventsRequest *events_request = (EventsRequest*)iter->data;
+
+        if(ltt_time_compare(events_request->end_time,
+                            end_time) < 0)
+          end_time = events_request->end_time;
+      }
+       
+      /* 3.1.2 Find lowest start time in list_out */
+      for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
+        EventsRequest *events_request = (EventsRequest*)iter->data;
+
+        if(ltt_time_compare(events_request->start_time,
+                            end_time) < 0)
+          end_time = events_request->start_time;
+      }
+    }
+
+    {
+      /* 3.2 Number of events */
+
+      /* 3.2.1 Find lowest number of events in list_in */
+      GSList *iter;
+
+      end_nb_events = ((EventsRequest*)g_slist_nth_data(list_in,0))->num_events;
+
+      for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
+        EventsRequest *events_request = (EventsRequest*)iter->data;
+
+        if(events_request->num_events < end_nb_events)
+          end_nb_events = events_request->num_events;
+      }
+
+      /* 3.2.2 Use min(CHUNK_NUM_EVENTS, min num events in list_in) as
+       * num_events */
+      
+      end_nb_events = MIN(CHUNK_NUM_EVENTS, end_nb_events);
+    }
+
+    {
+      /* 3.3 End position */
+
+      /* 3.3.1 Find lowest end position in list_in */
+      GSList *iter;
+
+      end_position =((EventsRequest*)g_slist_nth_data(list_in,0))->end_position;
+
+      for(iter=g_slist_nth(list_in,1);iter!=NULL;iter=g_slist_next(iter)) {
+        EventsRequest *events_request = (EventsRequest*)iter->data;
+
+        if(events_request->end_position != NULL && end_position != NULL &&
+            lttv_traceset_context_pos_pos_compare(events_request->end_position,
+                                                 end_position) <0)
+          end_position = events_request->end_position;
+      }
+    }
+    
+    {  
+      /* 3.3.2 Find lowest start position in list_out */
+      GSList *iter;
+
+      for(iter=list_out;iter!=NULL;iter=g_slist_next(iter)) {
+        EventsRequest *events_request = (EventsRequest*)iter->data;
+
+        if(events_request->end_position != NULL && end_position != NULL &&
+            lttv_traceset_context_pos_pos_compare(events_request->end_position,
+                                                 end_position) <0)
+          end_position = events_request->end_position;
+      }
+    }
+
+    {
+      /* 4. Call process traceset middle */
+      g_debug("Calling process traceset middle with %p, %lu sec %lu nsec, %u nb ev, %p end pos", tsc, end_time.tv_sec, end_time.tv_nsec, end_nb_events, end_position);
+      count = lttv_process_traceset_middle(tsc, end_time, end_nb_events, end_position);
+
+      tfc = lttv_traceset_context_get_current_tfc(tsc);
+      if(tfc != NULL)
+        g_debug("Context time after middle : %lu, %lu", tfc->timestamp.tv_sec,
+                                                        tfc->timestamp.tv_nsec);
+      else
+        g_debug("End of trace reached after middle.");
+
+    }
+    {
+      /* 5. After process traceset middle */
+      tfc = lttv_traceset_context_get_current_tfc(tsc);
+
+      /* - if current context time > traceset.end time */
+      if(tfc == NULL || ltt_time_compare(tfc->timestamp,
+                                         tsc->time_span.end_time) > 0) {
+        /* - For each req in list_in */
+        GSList *iter = list_in;
+    
+        while(iter != NULL) {
+
+          gboolean remove = FALSE;
+          gboolean free_data = FALSE;
+          EventsRequest *events_request = (EventsRequest *)iter->data;
+          
+          /* - Remove events hooks for req
+           * - Call end chunk for req
+           */
+
+          if(events_request->trace == -1) 
+               lttv_process_traceset_end(tsc,
+                                         events_request->after_chunk_traceset,
+                                         events_request->after_chunk_trace,
+                                         events_request->after_chunk_tracefile,
+                                         events_request->event,
+                                         events_request->event_by_id);
+
+          else {
+            guint nb_trace = lttv_traceset_number(tsc->ts);
+            g_assert(events_request->trace < nb_trace &&
+                      events_request->trace > -1);
+            LttvTraceContext *tc = tsc->traces[events_request->trace];
+
+            lttv_trace_context_remove_hooks(tc,
+                                         events_request->after_chunk_trace,
+                                         events_request->after_chunk_tracefile,
+                                         events_request->event,
+                                         events_request->event_by_id);
+            lttv_hooks_call(events_request->after_chunk_traceset, tsc);
+
+
+          }
+
+          /* - Call end request for req */
+          lttv_hooks_call(events_request->after_request, (gpointer)tsc);
+          
+          /* - remove req from list_in */
+          /* Destroy the request */
+          remove = TRUE;
+          free_data = TRUE;
+
+          /* Go to next */
+          if(remove)
+          {
+            GSList *remove_iter = iter;
+
+            iter = g_slist_next(iter);
+            if(free_data) events_request_free((EventsRequest*)remove_iter->data);
+            list_in = g_slist_remove_link(list_in, remove_iter);
+          } else { // not remove
+            iter = g_slist_next(iter);
+          }
+        }
+      }
+      {
+        /* 5.1 For each req in list_in */
+        GSList *iter = list_in;
+    
+        while(iter != NULL) {
+
+          gboolean remove = FALSE;
+          gboolean free_data = FALSE;
+          EventsRequest *events_request = (EventsRequest *)iter->data;
+          
+          /* - Remove events hooks for req
+           * - Call end chunk for req
+           */
+          if(events_request->trace == -1) 
+               lttv_process_traceset_end(tsc,
+                                         events_request->after_chunk_traceset,
+                                         events_request->after_chunk_trace,
+                                         events_request->after_chunk_tracefile,
+                                         events_request->event,
+                                         events_request->event_by_id);
+
+          else {
+            guint nb_trace = lttv_traceset_number(tsc->ts);
+            g_assert(events_request->trace < nb_trace &&
+                      events_request->trace > -1);
+            LttvTraceContext *tc = tsc->traces[events_request->trace];
+
+            lttv_trace_context_remove_hooks(tc,
+                                         events_request->after_chunk_trace,
+                                         events_request->after_chunk_tracefile,
+                                         events_request->event,
+                                         events_request->event_by_id);
+
+            lttv_hooks_call(events_request->after_chunk_traceset, tsc);
+          }
+
+          /* - req.num -= count */
+          g_assert(events_request->num_events >= count);
+          events_request->num_events -= count;
+          
+          g_assert(tfc != NULL);
+          /* - if req.num == 0
+           *   or
+           *     current context time >= req.end time
+           *   or
+           *     req.end pos == current pos
+           *   or
+           *     req.stop_flag == TRUE
+           */
+          if(   events_request->num_events == 0
+              ||
+                events_request->stop_flag == TRUE
+              ||
+                ltt_time_compare(tfc->timestamp,
+                                         events_request->end_time) >= 0
+              ||
+                  (events_request->end_position != NULL 
+                 &&
+                  lttv_traceset_context_ctx_pos_compare(tsc,
+                            events_request->end_position) == 0)
+
+              ) {
+            g_assert(events_request->servicing == TRUE);
+            /* - Call end request for req
+             * - remove req from list_in */
+            lttv_hooks_call(events_request->after_request, (gpointer)tsc);
+            /* - remove req from list_in */
+            /* Destroy the request */
+            remove = TRUE;
+            free_data = TRUE;
+          }
+          
+          /* Go to next */
+          if(remove)
+          {
+            GSList *remove_iter = iter;
+
+            iter = g_slist_next(iter);
+            if(free_data) events_request_free((EventsRequest*)remove_iter->data);
+            list_in = g_slist_remove_link(list_in, remove_iter);
+          } else { // not remove
+            iter = g_slist_next(iter);
+          }
+        }
+      }
+    }
+  }
+  /* End of removed servicing loop : leave control to GTK instead. */
+  //  if(gtk_events_pending()) break;
+  //}
+
+  /* B. When interrupted between chunks */
+
+  {
+    GSList *iter = list_in;
+    
+    /* 1. for each request in list_in */
+    while(iter != NULL) {
+
+      gboolean remove = FALSE;
+      gboolean free_data = FALSE;
+      EventsRequest *events_request = (EventsRequest *)iter->data;
+      
+      /* 1.1. Use current postition as start position */
+      if(events_request->start_position != NULL)
+        lttv_traceset_context_position_destroy(events_request->start_position);
+      events_request->start_position = lttv_traceset_context_position_new(tsc);
+      lttv_traceset_context_position_save(tsc, events_request->start_position);
+
+      /* 1.2. Remove start time */
+      events_request->start_time = ltt_time_infinite;
+      
+      /* 1.3. Move from list_in to list_out */
+      remove = TRUE;
+      free_data = FALSE;
+      list_out = g_slist_append(list_out, events_request);
+
+      /* Go to next */
+      if(remove)
+      {
+        GSList *remove_iter = iter;
+
+        iter = g_slist_next(iter);
+        if(free_data) events_request_free((EventsRequest*)remove_iter->data);
+        list_in = g_slist_remove_link(list_in, remove_iter);
+      } else { // not remove
+        iter = g_slist_next(iter);
+      }
+    }
+
+
+  }
+  /* C Unlock Traces */
+  {
+    lttv_process_traceset_get_sync_data(tsc);
+    //lttv_traceset_context_position_save(tsc, sync_position);
+    
+    guint iter_trace;
+    
+    for(iter_trace=0; 
+        iter_trace<lttv_traceset_number(tsc->ts);
+        iter_trace++) {
+      LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
+
+      lttvwindowtraces_unlock(trace_v);
+    }
+  }
+#if 0
+  //set the cursor back to normal
+  gdk_window_set_cursor(win, NULL);  
+#endif //0
+
+  g_assert(g_slist_length(list_in) == 0);
+
+  if( g_slist_length(list_out) == 0 ) {
+    /* Put tab's request pending flag back to normal */
+    tab->events_request_pending = FALSE;
+    g_debug("remove the idle fct");
+    return FALSE; /* Remove the idle function */
+  }
+  g_debug("leave the idle fct");
+  return TRUE; /* Leave the idle function */
+
+  /* We do not use simili-round-robin, it may require to read 1 meg buffers
+   * again and again if many tracesets use the same tracefiles. */
+  /* Hack for round-robin idle functions */
+  /* It will put the idle function at the end of the pool */
+  /*g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
+                  (GSourceFunc)execute_events_requests,
+                  tab,
+                  NULL);
+  return FALSE;
+  */
+}
+
+#undef list_out
+
+
+static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
+{
+  LttvTraceset *traceset = tab->traceset_info->traceset;
+  guint i;
+  guint num_traces = lttv_traceset_number(traceset);
+
+ //Verify if trace is already present.
+  for(i=0; i<num_traces; i++)
+  {
+    LttvTrace * trace = lttv_traceset_get(traceset, i);
+    if(trace == trace_v)
+      return;
+  }
+
+  //Keep a reference to the traces so they are not freed.
+  for(i=0; i<lttv_traceset_number(traceset); i++)
+  {
+    LttvTrace * trace = lttv_traceset_get(traceset, i);
+    lttv_trace_ref(trace);
+  }
+
+  //remove state update hooks
+  lttv_state_remove_event_hooks(
+     (LttvTracesetState*)tab->traceset_info->traceset_context);
+
+  lttv_context_fini(LTTV_TRACESET_CONTEXT(
+          tab->traceset_info->traceset_context));
+  g_object_unref(tab->traceset_info->traceset_context);
+
+  lttv_traceset_add(traceset, trace_v);
+  lttv_trace_ref(trace_v);  /* local ref */
+
+  /* Create new context */
+  tab->traceset_info->traceset_context =
+                          g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+  lttv_context_init(
+            LTTV_TRACESET_CONTEXT(tab->traceset_info->
+                                      traceset_context),
+            traceset); 
+
+
+  //add state update hooks
+  lttv_state_add_event_hooks(
+  (LttvTracesetState*)tab->traceset_info->traceset_context);
+  //Remove local reference to the traces.
+  for(i=0; i<lttv_traceset_number(traceset); i++)
+  {
+    LttvTrace * trace = lttv_traceset_get(traceset, i);
+    lttv_trace_unref(trace);
+  }
+
+  //FIXME
+  //add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
+}
+
+/* add_trace adds a trace into the current traceset. It first displays a 
+ * directory selection dialogue to let user choose a trace, then recreates
+ * tracset_context, and redraws all the viewer of the current tab 
+ */
+
+void add_trace(GtkWidget * widget, gpointer user_data)
+{
+  LttTrace *trace;
+  LttvTrace * trace_v;
+  LttvTraceset * traceset;
+  const char * dir;
+  char abs_path[PATH_MAX];
+  gint id;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+
+  if(!page) {
+    tab = create_new_tab(widget, NULL);
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
+  GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
+  gtk_widget_hide( (file_selector)->file_list->parent) ;
+  gtk_file_selection_hide_fileop_buttons(file_selector);
+  gtk_window_set_transient_for(GTK_WINDOW(file_selector),
+      GTK_WINDOW(mw_data->mwindow));
+  
+  if(remember_trace_dir[0] != '\0')
+    gtk_file_selection_set_filename(file_selector, remember_trace_dir);
+  
+  id = gtk_dialog_run(GTK_DIALOG(file_selector));
+  switch(id){
+    case GTK_RESPONSE_ACCEPT:
+    case GTK_RESPONSE_OK:
+      dir = gtk_file_selection_get_filename (file_selector);
+      strncpy(remember_trace_dir, dir, PATH_MAX);
+      strncat(remember_trace_dir, "/", PATH_MAX);
+      if(!dir || strlen(dir) == 0){
+       gtk_widget_destroy((GtkWidget*)file_selector);
+       break;
+      }
+      get_absolute_pathname(dir, abs_path);
+      trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
+      if(trace_v == NULL) {
+        trace = ltt_trace_open(abs_path);
+        if(trace == NULL) {
+          g_warning("cannot open trace %s", abs_path);
+
+          GtkWidget *dialogue = 
+            gtk_message_dialog_new(
+              GTK_WINDOW(gtk_widget_get_toplevel(widget)),
+              GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+              GTK_MESSAGE_ERROR,
+              GTK_BUTTONS_OK,
+              "Cannot open trace : maybe you should enter in the trace "
+              "directory to select it ?");
+          gtk_dialog_run(GTK_DIALOG(dialogue));
+          gtk_widget_destroy(dialogue);
+
+        } else {
+          trace_v = lttv_trace_new(trace);
+          lttvwindowtraces_add_trace(trace_v);
+          lttvwindow_add_trace(tab, trace_v);
+        }
+      } else {
+        lttvwindow_add_trace(tab, trace_v);
+      }
+
+      gtk_widget_destroy((GtkWidget*)file_selector);
+      
+      //update current tab
+      //update_traceset(mw_data);
+
+      /* Call the updatetraceset hooks */
+      
+      traceset = tab->traceset_info->traceset;
+      SetTraceset(tab, traceset);
+      // in expose now call_pending_read_hooks(mw_data);
+      
+      //lttvwindow_report_current_time(mw_data,&(tab->current_time));
+      break;
+    case GTK_RESPONSE_REJECT:
+    case GTK_RESPONSE_CANCEL:
+    default:
+      gtk_widget_destroy((GtkWidget*)file_selector);
+      break;
+  }
+}
+
+/* remove_trace removes a trace from the current traceset if all viewers in 
+ * the current tab are not interested in the trace. It first displays a 
+ * dialogue, which shows all traces in the current traceset, to let user choose 
+ * a trace, then it checks if all viewers unselect the trace, if it is true, 
+ * it will remove the trace,  recreate the traceset_contex,
+ * and redraws all the viewer of the current tab. If there is on trace in the
+ * current traceset, it will delete all viewers of the current tab
+ *
+ * It destroys the filter tree. FIXME... we should request for an update
+ * instead.
+ */
+
+void remove_trace(GtkWidget *widget, gpointer user_data)
+{
+  LttTrace *trace;
+  LttvTrace * trace_v;
+  LttvTraceset * traceset;
+  gint i, j, nb_trace, index=-1;
+  char ** name, *remove_trace_name;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  nb_trace =lttv_traceset_number(tab->traceset_info->traceset); 
+  name = g_new(char*,nb_trace);
+  for(i = 0; i < nb_trace; i++){
+    trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
+    trace = lttv_trace(trace_v);
+    name[i] = g_quark_to_string(ltt_trace_name(trace));
+  }
+
+  remove_trace_name = get_remove_trace(mw_data, name, nb_trace);
+
+
+  if(remove_trace_name){
+
+    /* yuk, cut n paste from old code.. should be better (MD)*/
+    for(i = 0; i<nb_trace; i++) {
+      if(strcmp(remove_trace_name,name[i]) == 0){
+        index = i;
+      }
+    }
+    
+    traceset = tab->traceset_info->traceset;
+    //Keep a reference to the traces so they are not freed.
+    for(j=0; j<lttv_traceset_number(traceset); j++)
+    {
+      LttvTrace * trace = lttv_traceset_get(traceset, j);
+      lttv_trace_ref(trace);
+    }
+
+    //remove state update hooks
+    lttv_state_remove_event_hooks(
+         (LttvTracesetState*)tab->traceset_info->traceset_context);
+    lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
+    g_object_unref(tab->traceset_info->traceset_context);
+
+    trace_v = lttv_traceset_get(traceset, index);
+
+    lttv_traceset_remove(traceset, index);
+    lttv_trace_unref(trace_v);  // Remove local reference
+
+    if(lttv_trace_get_ref_number(trace_v) <= 1) {
+      /* ref 1 : lttvwindowtraces only*/
+      ltt_trace_close(lttv_trace(trace_v));
+      /* lttvwindowtraces_remove_trace takes care of destroying
+       * the traceset linked with the trace_v and also of destroying
+       * the trace_v at the same time.
+       */
+      lttvwindowtraces_remove_trace(trace_v);
+    }
+    
+    tab->traceset_info->traceset_context =
+      g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+    lttv_context_init(
+          LTTV_TRACESET_CONTEXT(tab->
+              traceset_info->traceset_context),traceset);      
+      //add state update hooks
+    lttv_state_add_event_hooks(
+      (LttvTracesetState*)tab->traceset_info->traceset_context);
+
+    //Remove local reference to the traces.
+    for(j=0; j<lttv_traceset_number(traceset); j++)
+    {
+      LttvTrace * trace = lttv_traceset_get(traceset, j);
+      lttv_trace_unref(trace);
+    }
+
+    SetTraceset(tab, (gpointer)traceset);
+  }
+  g_free(name);
+}
+
+#if 0
+void remove_trace(GtkWidget * widget, gpointer user_data)
+{
+  LttTrace *trace;
+  LttvTrace * trace_v;
+  LttvTraceset * traceset;
+  gint i, j, nb_trace;
+  char ** name, *remove_trace_name;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  LttvTracesetSelector * s;
+  LttvTraceSelector * t;
+  GtkWidget * w; 
+  gboolean selected;
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  nb_trace =lttv_traceset_number(tab->traceset_info->traceset); 
+  name = g_new(char*,nb_trace);
+  for(i = 0; i < nb_trace; i++){
+    trace_v = lttv_traceset_get(tab->traceset_info->traceset, i);
+    trace = lttv_trace(trace_v);
+    name[i] = ltt_trace_name(trace);
+  }
+
+  remove_trace_name = get_remove_trace(name, nb_trace);
+
+  if(remove_trace_name){
+    for(i=0; i<nb_trace; i++){
+      if(strcmp(remove_trace_name,name[i]) == 0){
+             //unselect the trace from the current viewer
+        //FIXME
+       w = gtk_multivpaned_get_widget(GTK_MULTIVPANED(tab->multivpaned));
+       if(w){
+         s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
+         if(s){
+           t = lttv_traceset_selector_trace_get(s,i);
+           lttv_trace_selector_set_selected(t, FALSE);
+         }
+
+          //check if other viewers select the trace
+          w = gtk_multivpaned_get_first_widget(GTK_MULTIVPANED(tab->multivpaned));
+          while(w){
+            s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
+            if(s){
+              t = lttv_traceset_selector_trace_get(s,i);
+              selected = lttv_trace_selector_get_selected(t);
+              if(selected)break;
+            }
+            w = gtk_multivpaned_get_next_widget(GTK_MULTIVPANED(tab->multivpaned));
+          }
+        }else selected = FALSE;
+
+        //if no viewer selects the trace, remove it
+        if(!selected){
+          remove_trace_from_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), i);
+
+          traceset = tab->traceset_info->traceset;
+         //Keep a reference to the traces so they are not freed.
+          for(j=0; j<lttv_traceset_number(traceset); j++)
+          {
+            LttvTrace * trace = lttv_traceset_get(traceset, j);
+            lttv_trace_ref(trace);
+          }
+
+          //remove state update hooks
+          lttv_state_remove_event_hooks(
+               (LttvTracesetState*)tab->traceset_info->traceset_context);
+          lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context));
+          g_object_unref(tab->traceset_info->traceset_context);
+
+
+          trace_v = lttv_traceset_get(traceset, i);
+
+          if(lttv_trace_get_ref_number(trace_v) <= 2) {
+            /* ref 2 : traceset, local */
+            lttvwindowtraces_remove_trace(trace_v);
+            ltt_trace_close(lttv_trace(trace_v));
+          }
+          
+          lttv_traceset_remove(traceset, i);
+          lttv_trace_unref(trace_v);  // Remove local reference
+
+          if(!lttv_trace_get_ref_number(trace_v))
+             lttv_trace_destroy(trace_v);
+          
+          tab->traceset_info->traceset_context =
+            g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+          lttv_context_init(
+                LTTV_TRACESET_CONTEXT(tab->
+                    traceset_info->traceset_context),traceset);      
+            //add state update hooks
+          lttv_state_add_event_hooks(
+            (LttvTracesetState*)tab->traceset_info->traceset_context);
+
+          //Remove local reference to the traces.
+          for(j=0; j<lttv_traceset_number(traceset); j++)
+          {
+            LttvTrace * trace = lttv_traceset_get(traceset, j);
+            lttv_trace_unref(trace);
+          }
+
+
+          //update current tab
+          //update_traceset(mw_data);
+          //if(nb_trace > 1){
+
+            SetTraceset(tab, (gpointer)traceset);
+            // in expose now call_pending_read_hooks(mw_data);
+
+            //lttvwindow_report_current_time(mw_data,&(tab->current_time));
+          //}else{
+          //  if(tab){
+          //    while(tab->multi_vpaned->num_children){
+          //      gtk_multi_vpaned_widget_delete(tab->multi_vpaned);
+          //    }    
+          //  }            
+          //}
+        }
+        break;
+      }
+    }
+  }
+
+  g_free(name);
+}
+#endif //0
+
+/* Redraw all the viewers in the current tab */
+void redraw(GtkWidget *widget, gpointer user_data)
+{
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  LttvHooks * tmp;
+  LttvAttributeValue value;
+
+  g_assert(lttv_iattribute_find_by_path(tab->attributes, "hooks/redraw", LTTV_POINTER, &value));
+
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp != NULL)
+    lttv_hooks_call(tmp,NULL);
+}
+
+
+void continue_processing(GtkWidget *widget, gpointer user_data)
+{
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  LttvHooks * tmp;
+  LttvAttributeValue value;
+
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+     "hooks/continue", LTTV_POINTER, &value));
+
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp != NULL)
+    lttv_hooks_call(tmp,NULL);
+}
+
+/* Stop the processing for the calling main window's current tab.
+ * It removes every processing requests that are in its list. It does not call
+ * the end request hooks, because the request is not finished.
+ */
+
+void stop_processing(GtkWidget *widget, gpointer user_data)
+{
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+  GSList *iter = tab->events_requests;
+  
+  while(iter != NULL) {
+    GSList *remove_iter = iter;
+    iter = g_slist_next(iter);
+    
+    g_free(remove_iter->data);
+    tab->events_requests = 
+                       g_slist_remove_link(tab->events_requests, remove_iter);
+  }
+  tab->events_request_pending = FALSE;
+  g_idle_remove_by_data(tab);
+  g_assert(g_slist_length(tab->events_requests) == 0);
+}
+
+
+/* save will save the traceset to a file
+ * Not implemented yet FIXME
+ */
+
+void save(GtkWidget * widget, gpointer user_data)
+{
+  g_info("Save\n");
+}
+
+void save_as(GtkWidget * widget, gpointer user_data)
+{
+  g_info("Save as\n");
+}
+
+
+/* zoom will change the time_window of all the viewers of the 
+ * current tab, and redisplay them. The main functionality is to 
+ * determine the new time_window of the current tab
+ */
+
+void zoom(GtkWidget * widget, double size)
+{
+  TimeInterval time_span;
+  TimeWindow new_time_window;
+  LttTime    current_time, time_delta;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  LttvTracesetContext *tsc;
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+
+  if(!page) {
+    return;
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  if(size == 1) return;
+
+  tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  time_span = tsc->time_span;
+  new_time_window =  tab->time_window;
+  current_time = tab->current_time;
+  
+  time_delta = ltt_time_sub(time_span.end_time,time_span.start_time);
+  if(size == 0){
+    new_time_window.start_time = time_span.start_time;
+    new_time_window.time_width = time_delta;
+    new_time_window.time_width_double = ltt_time_to_double(time_delta);
+    new_time_window.end_time = ltt_time_add(new_time_window.start_time,
+                                            new_time_window.time_width) ;
+  }else{
+    new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
+    new_time_window.time_width_double = 
+                   ltt_time_to_double(new_time_window.time_width);
+    if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
+    { /* Case where zoom out is bigger than trace length */
+      new_time_window.start_time = time_span.start_time;
+      new_time_window.time_width = time_delta;
+      new_time_window.time_width_double = ltt_time_to_double(time_delta);
+      new_time_window.end_time = ltt_time_add(new_time_window.start_time,
+                                            new_time_window.time_width) ;
+    }
+    else
+    {
+      /* Center the image on the current time */
+      new_time_window.start_time = 
+        ltt_time_sub(current_time,
+            ltt_time_from_double(new_time_window.time_width_double/2.0));
+      new_time_window.end_time = ltt_time_add(new_time_window.start_time,
+                                            new_time_window.time_width) ;
+      /* If on borders, don't fall off */
+      if(ltt_time_compare(new_time_window.start_time, time_span.start_time) <0)
+      {
+        new_time_window.start_time = time_span.start_time;
+        new_time_window.end_time = ltt_time_add(new_time_window.start_time,
+                                            new_time_window.time_width) ;
+      }
+      else 
+      {
+        if(ltt_time_compare(new_time_window.end_time,
+                            time_span.end_time) > 0)
+        {
+          new_time_window.start_time = 
+                  ltt_time_sub(time_span.end_time, new_time_window.time_width);
+
+          new_time_window.end_time = ltt_time_add(new_time_window.start_time,
+                                                  new_time_window.time_width) ;
+        }
+      }
+      
+    }
+  }
+
+ if(ltt_time_compare(new_time_window.time_width, ltt_time_zero) == 0) {
+    g_warning("Zoom more than 1 ns impossible");
+ } else {
+   time_change_manager(tab, new_time_window);
+  }
+}
+
+void zoom_in(GtkWidget * widget, gpointer user_data)
+{
+  zoom(widget, 2);
+}
+
+void zoom_out(GtkWidget * widget, gpointer user_data)
+{
+  zoom(widget, 0.5);
+}
+
+void zoom_extended(GtkWidget * widget, gpointer user_data)
+{
+  zoom(widget, 0);
+}
+
+void go_to_time(GtkWidget * widget, gpointer user_data)
+{
+  g_info("Go to time\n");  
+}
+
+void show_time_frame(GtkWidget * widget, gpointer user_data)
+{
+  g_info("Show time frame\n");  
+}
+
+
+/* callback function */
+
+void
+on_empty_traceset_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  create_new_window((GtkWidget*)menuitem, user_data, FALSE);
+}
+
+
+void
+on_clone_traceset_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  create_new_window((GtkWidget*)menuitem, user_data, TRUE);
+}
+
+
+/* create_new_tab calls create_tab to construct a new tab in the main window
+ */
+
+Tab *create_new_tab(GtkWidget* widget, gpointer user_data){
+  gchar label[PATH_MAX];
+  MainWindow * mw_data = get_window_data_struct(widget);
+
+  GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
+  if(notebook == NULL){
+    g_info("Notebook does not exist\n");
+    return NULL;
+  }
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *copy_tab;
+
+  if(!page) {
+    copy_tab = NULL;
+  } else {
+    copy_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+  
+  strcpy(label,"Page");
+  if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))    
+    return (create_tab (mw_data, copy_tab, notebook, label));
+  else
+    return NULL;
+}
+
+void
+on_tab_activate                        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  create_new_tab((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_open_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  open_traceset((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_close_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+  main_window_destructor(mw_data);  
+}
+
+
+/* remove the current tab from the main window
+ */
+
+void
+on_close_tab_activate                  (GtkWidget       *widget,
+                                        gpointer         user_data)
+{
+  gint page_num;
+  GtkWidget * notebook;
+  GtkWidget * page;
+  MainWindow * mw_data = get_window_data_struct(widget);
+  notebook = lookup_widget(widget, "MNotebook");
+  if(notebook == NULL){
+    g_info("Notebook does not exist\n");
+    return;
+  }
+
+  page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
+  
+  gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
+
+}
+
+void
+on_close_tab_X_clicked                 (GtkWidget       *widget,
+                                        gpointer         user_data)
+{
+  gint page_num;
+  GtkWidget *notebook = lookup_widget(widget, "MNotebook");
+  if(notebook == NULL){
+    g_info("Notebook does not exist\n");
+    return;
+  }
+  if((page_num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), widget)) != -1)
+    gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page_num);
+
+}
+
+
+void
+on_add_trace_activate                  (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  add_trace((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_remove_trace_activate               (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  remove_trace((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_save_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  save((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_save_as_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  save_as((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_quit_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  mainwindow_quit();
+}
+
+
+void
+on_cut_activate                        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Cut\n");
+}
+
+
+void
+on_copy_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Copye\n");
+}
+
+
+void
+on_paste_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Paste\n");
+}
+
+
+void
+on_delete_activate                     (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Delete\n");
+}
+
+
+void
+on_zoom_in_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+   zoom_in((GtkWidget*)menuitem, user_data); 
+}
+
+
+void
+on_zoom_out_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+   zoom_out((GtkWidget*)menuitem, user_data); 
+}
+
+
+void
+on_zoom_extended_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+   zoom_extended((GtkWidget*)menuitem, user_data); 
+}
+
+
+void
+on_go_to_time_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+   go_to_time((GtkWidget*)menuitem, user_data); 
+}
+
+
+void
+on_show_time_frame_activate            (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+   show_time_frame((GtkWidget*)menuitem, user_data); 
+}
+
+
+void
+on_move_viewer_up_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  move_up_viewer((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_move_viewer_down_activate           (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  move_down_viewer((GtkWidget*)menuitem, user_data);
+}
+
+
+void
+on_remove_viewer_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  delete_viewer((GtkWidget*)menuitem, user_data);
+}
+
+void
+on_trace_facility_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Trace facility selector: %s\n");  
+}
+
+
+/* Dispaly a file selection dialogue to let user select a library, then call
+ * lttv_library_load().
+ */
+
+void
+on_load_library_activate                (GtkMenuItem     *menuitem,
+                                         gpointer         user_data)
+{
+  GError *error = NULL;
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+
+  gchar load_module_path_alter[PATH_MAX];
+  {
+    GPtrArray *name;
+    guint nb,i;
+    gchar *load_module_path;
+    name = g_ptr_array_new();
+    nb = lttv_library_path_number();
+    /* ask for the library path */
+
+    for(i=0;i<nb;i++){
+      gchar *path;
+      path = lttv_library_path_get(i);
+      g_ptr_array_add(name, path);
+    }
+
+    load_module_path = get_selection(mw_data,
+                             (char **)(name->pdata), name->len,
+                             "Select a library path", "Library paths");
+    if(load_module_path != NULL)
+      strncpy(load_module_path_alter, load_module_path, PATH_MAX-1); // -1 for /
+
+    g_ptr_array_free(name, TRUE);
+
+    if(load_module_path == NULL) return;
+  }
+
+  {
+    /* Make sure the module path ends with a / */
+    gchar *ptr = load_module_path_alter;
+
+    ptr = strchr(ptr, '\0');
+
+    if(*(ptr-1) != '/') {
+      *ptr = '/';
+      *(ptr+1) = '\0';
+    }
+  }
+
+  {
+    /* Ask for the library to load : list files in the previously selected
+     * directory */
+    gchar str[PATH_MAX];
+    gchar ** dir;
+    gint id;
+    GtkFileSelection * file_selector =
+      (GtkFileSelection *)gtk_file_selection_new("Select a module");
+    gtk_file_selection_set_filename(file_selector, load_module_path_alter);
+    gtk_file_selection_hide_fileop_buttons(file_selector);
+    
+    gtk_window_set_transient_for(GTK_WINDOW(file_selector),
+        GTK_WINDOW(mw_data->mwindow));
+
+    str[0] = '\0';
+    id = gtk_dialog_run(GTK_DIALOG(file_selector));
+    switch(id){
+      case GTK_RESPONSE_ACCEPT:
+      case GTK_RESPONSE_OK:
+        dir = gtk_file_selection_get_selections (file_selector);
+        strncpy(str,dir[0],PATH_MAX);
+        strncpy(remember_plugins_dir,dir[0],PATH_MAX);
+        /* only keep file name */
+        gchar *str1;
+        str1 = strrchr(str,'/');
+        if(str1)str1++;
+        else{
+          str1 = strrchr(str,'\\');
+          str1++;
+        }
+#if 0
+        /* remove "lib" */
+        if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
+          str1=str1+3;
+         remove info after . */
+        {
+          gchar *str2 = str1;
+
+          str2 = strrchr(str2, '.');
+          if(str2 != NULL) *str2 = '\0';
+        }
+        lttv_module_require(str1, &error);
+#endif //0   
+        lttv_library_load(str1, &error);
+        if(error != NULL) g_warning("%s", error->message);
+        else g_info("Load library: %s\n", str);
+        g_strfreev(dir);
+      case GTK_RESPONSE_REJECT:
+      case GTK_RESPONSE_CANCEL:
+      default:
+        gtk_widget_destroy((GtkWidget*)file_selector);
+        break;
+    }
+
+  }
+
+
+
+}
+
+
+/* Display all loaded modules, let user to select a module to unload
+ * by calling lttv_module_unload
+ */
+
+void
+on_unload_library_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+
+  LttvLibrary *library = NULL;
+
+  GPtrArray *name;
+  guint nb,i;
+  gchar *lib_name;
+  name = g_ptr_array_new();
+  nb = lttv_library_number();
+  LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
+  /* ask for the library name */
+
+  for(i=0;i<nb;i++){
+    LttvLibrary *iter_lib = lttv_library_get(i);
+    lttv_library_info(iter_lib, &lib_info[i]);
+    
+    gchar *path = lib_info[i].name;
+    g_ptr_array_add(name, path);
+  }
+  lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
+                           "Select a library", "Libraries");
+  if(lib_name != NULL) {
+    for(i=0;i<nb;i++){
+      if(strcmp(lib_name, lib_info[i].name) == 0) {
+        library = lttv_library_get(i);
+        break;
+      }
+    }
+  }
+  g_ptr_array_free(name, TRUE);
+  g_free(lib_info);
+
+  if(lib_name == NULL) return;
+
+  if(library != NULL) lttv_library_unload(library);
+}
+
+
+/* Dispaly a file selection dialogue to let user select a module, then call
+ * lttv_module_require().
+ */
+
+void
+on_load_module_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  GError *error = NULL;
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+
+  LttvLibrary *library = NULL;
+  {
+    GPtrArray *name;
+    guint nb,i;
+    gchar *lib_name;
+    name = g_ptr_array_new();
+    nb = lttv_library_number();
+    LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
+    /* ask for the library name */
+
+    for(i=0;i<nb;i++){
+      LttvLibrary *iter_lib = lttv_library_get(i);
+      lttv_library_info(iter_lib, &lib_info[i]);
+      
+      gchar *path = lib_info[i].name;
+      g_ptr_array_add(name, path);
+    }
+    lib_name = get_selection(mw_data,(char **)(name->pdata), name->len,
+                             "Select a library", "Libraries");
+    if(lib_name != NULL) {
+      for(i=0;i<nb;i++){
+        if(strcmp(lib_name, lib_info[i].name) == 0) {
+          library = lttv_library_get(i);
+          break;
+        }
+      }
+    }
+    g_ptr_array_free(name, TRUE);
+    g_free(lib_info);
+
+    if(lib_name == NULL) return;
+  }
+
+  //LttvModule *module;
+  gchar module_name_out[PATH_MAX];
+  {
+    /* Ask for the module to load : list modules in the selected lib */
+    GPtrArray *name;
+    guint nb,i;
+    gchar *module_name;
+    nb = lttv_library_module_number(library);
+    LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
+    name = g_ptr_array_new();
+    /* ask for the module name */
+
+    for(i=0;i<nb;i++){
+      LttvModule *iter_module = lttv_library_module_get(library, i);
+      lttv_module_info(iter_module, &module_info[i]);
+
+      gchar *path = module_info[i].name;
+      g_ptr_array_add(name, path);
+    }
+    module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
+                             "Select a module", "Modules");
+    if(module_name != NULL) {
+      for(i=0;i<nb;i++){
+        if(strcmp(module_name, module_info[i].name) == 0) {
+          strncpy(module_name_out, module_name, PATH_MAX);
+          //module = lttv_library_module_get(i);
+          break;
+        }
+      }
+    }
+
+    g_ptr_array_free(name, TRUE);
+    g_free(module_info);
+
+    if(module_name == NULL) return;
+  }
+  
+  lttv_module_require(module_name_out, &error);
+  if(error != NULL) g_warning("%s", error->message);
+  else g_info("Load module: %s", module_name_out);
+
+
+#if 0
+  {
+
+
+    gchar str[PATH_MAX];
+    gchar ** dir;
+    gint id;
+    GtkFileSelection * file_selector =
+      (GtkFileSelection *)gtk_file_selection_new("Select a module");
+    gtk_file_selection_set_filename(file_selector, load_module_path_alter);
+    gtk_file_selection_hide_fileop_buttons(file_selector);
+    
+    str[0] = '\0';
+    id = gtk_dialog_run(GTK_DIALOG(file_selector));
+    switch(id){
+      case GTK_RESPONSE_ACCEPT:
+      case GTK_RESPONSE_OK:
+        dir = gtk_file_selection_get_selections (file_selector);
+        strncpy(str,dir[0],PATH_MAX);
+        strncpy(remember_plugins_dir,dir[0],PATH_MAX);
+        {
+          /* only keep file name */
+          gchar *str1;
+          str1 = strrchr(str,'/');
+          if(str1)str1++;
+          else{
+            str1 = strrchr(str,'\\');
+            str1++;
+          }
+#if 0
+        /* remove "lib" */
+        if(*str1 == 'l' && *(str1+1)== 'i' && *(str1+2)=='b')
+          str1=str1+3;
+         remove info after . */
+        {
+          gchar *str2 = str1;
+
+          str2 = strrchr(str2, '.');
+          if(str2 != NULL) *str2 = '\0';
+        }
+        lttv_module_require(str1, &error);
+#endif //0   
+        lttv_library_load(str1, &error);
+        if(error != NULL) g_warning(error->message);
+        else g_info("Load library: %s\n", str);
+        g_strfreev(dir);
+      case GTK_RESPONSE_REJECT:
+      case GTK_RESPONSE_CANCEL:
+      default:
+        gtk_widget_destroy((GtkWidget*)file_selector);
+        break;
+    }
+
+  }
+#endif //0
+
+
+}
+
+
+
+/* Display all loaded modules, let user to select a module to unload
+ * by calling lttv_module_unload
+ */
+
+void
+on_unload_module_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  GError *error = NULL;
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+
+  LttvLibrary *library;
+  {
+    GPtrArray *name;
+    guint nb,i;
+    gchar *lib_name;
+    name = g_ptr_array_new();
+    nb = lttv_library_number();
+    LttvLibraryInfo *lib_info = g_new(LttvLibraryInfo,nb);
+    /* ask for the library name */
+
+    for(i=0;i<nb;i++){
+      LttvLibrary *iter_lib = lttv_library_get(i);
+      lttv_library_info(iter_lib, &lib_info[i]);
+      
+      gchar *path = lib_info[i].name;
+      g_ptr_array_add(name, path);
+    }
+    lib_name = get_selection(mw_data, (char **)(name->pdata), name->len,
+                             "Select a library", "Libraries");
+    if(lib_name != NULL) {
+      for(i=0;i<nb;i++){
+        if(strcmp(lib_name, lib_info[i].name) == 0) {
+          library = lttv_library_get(i);
+          break;
+        }
+      }
+    }
+    g_ptr_array_free(name, TRUE);
+    g_free(lib_info);
+
+    if(lib_name == NULL) return;
+  }
+
+  LttvModule *module = NULL;
+  {
+    /* Ask for the module to load : list modules in the selected lib */
+    GPtrArray *name;
+    guint nb,i;
+    gchar *module_name;
+    nb = lttv_library_module_number(library);
+    LttvModuleInfo *module_info = g_new(LttvModuleInfo,nb);
+    name = g_ptr_array_new();
+    /* ask for the module name */
+
+    for(i=0;i<nb;i++){
+      LttvModule *iter_module = lttv_library_module_get(library, i);
+      lttv_module_info(iter_module, &module_info[i]);
+
+      gchar *path = module_info[i].name;
+      if(module_info[i].use_count > 0) g_ptr_array_add(name, path);
+    }
+    module_name = get_selection(mw_data, (char **)(name->pdata), name->len,
+                             "Select a module", "Modules");
+    if(module_name != NULL) {
+      for(i=0;i<nb;i++){
+        if(strcmp(module_name, module_info[i].name) == 0) {
+          module = lttv_library_module_get(library, i);
+          break;
+        }
+      }
+    }
+
+    g_ptr_array_free(name, TRUE);
+    g_free(module_info);
+
+    if(module_name == NULL) return;
+  }
+  
+  LttvModuleInfo module_info;
+  lttv_module_info(module, &module_info);
+  g_info("Release module: %s\n", module_info.name);
+  lttv_module_release(module);
+}
+
+
+/* Display a directory dialogue to let user select a path for library searching
+ */
+
+void
+on_add_library_search_path_activate     (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+  //GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select library path");
+  GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a trace");
+  gtk_widget_hide( (file_selector)->file_list->parent) ;
+
+  gtk_window_set_transient_for(GTK_WINDOW(file_selector),
+      GTK_WINDOW(mw_data->mwindow));
+
+  const char * dir;
+  gint id;
+
+  if(remember_plugins_dir[0] != '\0')
+    gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
+
+  id = gtk_dialog_run(GTK_DIALOG(file_selector));
+  switch(id){
+    case GTK_RESPONSE_ACCEPT:
+    case GTK_RESPONSE_OK:
+      dir = gtk_file_selection_get_filename (file_selector);
+      strncpy(remember_plugins_dir,dir,PATH_MAX);
+      strncat(remember_plugins_dir,"/",PATH_MAX);
+      lttv_library_path_add(dir);
+    case GTK_RESPONSE_REJECT:
+    case GTK_RESPONSE_CANCEL:
+    default:
+      gtk_widget_destroy((GtkWidget*)file_selector);
+      break;
+  }
+}
+
+
+/* Display a directory dialogue to let user select a path for library searching
+ */
+
+void
+on_remove_library_search_path_activate     (GtkMenuItem     *menuitem,
+                                            gpointer         user_data)
+{
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
+
+  const char *lib_path;
+  {
+    GPtrArray *name;
+    guint nb,i;
+    gchar *lib_name;
+    name = g_ptr_array_new();
+    nb = lttv_library_path_number();
+    /* ask for the library name */
+
+    for(i=0;i<nb;i++){
+      gchar *path = lttv_library_path_get(i);
+      g_ptr_array_add(name, path);
+    }
+    lib_path = get_selection(mw_data, (char **)(name->pdata), name->len,
+                             "Select a library path", "Library paths");
+
+    g_ptr_array_free(name, TRUE);
+
+    if(lib_path == NULL) return;
+  }
+  
+  lttv_library_path_remove(lib_path);
+}
+
+void
+on_color_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Color\n");
+}
+
+
+void
+on_save_configuration_activate         (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Save configuration\n");
+}
+
+
+void
+on_content_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  g_info("Content\n");
+}
+
+
+static void 
+on_about_close_activate                (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  GtkWidget *about_widget = GTK_WIDGET(user_data);
+
+  gtk_widget_destroy(about_widget);
+}
+
+void
+on_about_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  MainWindow *main_window = get_window_data_struct(GTK_WIDGET(menuitem));
+  GtkWidget *window_widget = main_window->mwindow;
+  GtkWidget *about_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  GtkWindow *about_window = GTK_WINDOW(about_widget);
+  gint window_width, window_height;
+  
+  gtk_window_set_title(about_window, "About Linux Trace Toolkit");
+
+  gtk_window_set_resizable(about_window, FALSE);
+  gtk_window_set_transient_for(GTK_WINDOW(window_widget), about_window);
+  gtk_window_set_destroy_with_parent(about_window, TRUE);
+  gtk_window_set_modal(about_window, FALSE);
+
+  /* Put the about window at the center of the screen */
+  gtk_window_get_size(about_window, &window_width, &window_height);
+  gtk_window_move (about_window,
+                   (gdk_screen_width() - window_width)/2,
+                   (gdk_screen_height() - window_height)/2);
+  GtkWidget *vbox = gtk_vbox_new(FALSE, 1);
+
+  gtk_container_add(GTK_CONTAINER(about_widget), vbox);
+
+    
+  /* Text to show */
+  GtkWidget *label1 = gtk_label_new("");
+  gtk_misc_set_padding(GTK_MISC(label1), 10, 20);
+  gtk_label_set_markup(GTK_LABEL(label1), "\
+<big>Linux Trace Toolkit</big>");
+  gtk_label_set_justify(GTK_LABEL(label1), GTK_JUSTIFY_CENTER);
+  
+  GtkWidget *label2 = gtk_label_new("");
+  gtk_misc_set_padding(GTK_MISC(label2), 10, 20);
+  gtk_label_set_markup(GTK_LABEL(label2), "\
+Contributors :\n\
+\n\
+Michel Dagenais (New trace format, lttv main)\n\
+Mathieu Desnoyers (Kernel Tracer, Directory structure, build with automake/conf,\n\
+                   lttv gui, control flow view, gui cooperative trace reading\n\
+                   scheduler with interruptible foreground and background\n\
+                   computation, detailed event list (rewrite), trace reading\n\
+                   library (rewrite))\n\
+Benoit Des Ligneris, Eric Clement (Cluster adaptation, work in progress)\n\
+Xang-Xiu Yang (new trace reading library and converter, lttv gui, \n\
+               detailed event list and statistics view)\n\
+Tom Zanussi (RelayFS)\n\
+\n\
+Strongly inspired from the original Linux Trace Toolkit Visualizer made by\n\
+Karim Yaghmour");
+
+  GtkWidget *label3 = gtk_label_new("");
+  gtk_label_set_markup(GTK_LABEL(label3), "\
+Linux Trace Toolkit Viewer, Copyright (C) 2004\n\
+                                                Michel Dagenais\n\
+                                                Mathieu Desnoyers\n\
+                                                Xang-Xiu Yang\n\
+Linux Trace Toolkit comes with ABSOLUTELY NO WARRANTY.\n\
+This is free software, and you are welcome to redistribute it\n\
+under certain conditions. See COPYING for details.");
+  gtk_misc_set_padding(GTK_MISC(label3), 10, 20);
+
+  gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
+  gtk_box_pack_start_defaults(GTK_BOX(vbox), label2);
+  gtk_box_pack_start_defaults(GTK_BOX(vbox), label3);
+
+  GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
+  gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+  GtkWidget *close_button = gtk_button_new_with_mnemonic("_Close");
+  gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(close_button), 20);
+
+  g_signal_connect(G_OBJECT(close_button), "clicked",
+      G_CALLBACK(on_about_close_activate),
+      (gpointer)about_widget);
+  
+  gtk_widget_show_all(about_widget);
+}
+
+
+void
+on_button_new_clicked                  (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  create_new_window((GtkWidget*)button, user_data, TRUE);
+}
+
+void
+on_button_new_tab_clicked              (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  create_new_tab((GtkWidget*)button, user_data);
+}
+
+void
+on_button_open_clicked                 (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  open_traceset((GtkWidget*)button, user_data);
+}
+
+
+void
+on_button_add_trace_clicked            (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  add_trace((GtkWidget*)button, user_data);
+}
+
+
+void
+on_button_remove_trace_clicked         (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  remove_trace((GtkWidget*)button, user_data);
+}
+
+void
+on_button_redraw_clicked               (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  redraw((GtkWidget*)button, user_data);
+}
+
+void
+on_button_continue_processing_clicked  (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  continue_processing((GtkWidget*)button, user_data);
+}
+
+void
+on_button_stop_processing_clicked      (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  stop_processing((GtkWidget*)button, user_data);
+}
+
+
+
+void
+on_button_save_clicked                 (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  save((GtkWidget*)button, user_data);
+}
+
+
+void
+on_button_save_as_clicked              (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  save_as((GtkWidget*)button, user_data);
+}
+
+
+void
+on_button_zoom_in_clicked              (GtkButton       *button,
+                                        gpointer         user_data)
+{
+   zoom_in((GtkWidget*)button, user_data); 
+}
+
+
+void
+on_button_zoom_out_clicked             (GtkButton       *button,
+                                        gpointer         user_data)
+{
+   zoom_out((GtkWidget*)button, user_data); 
+}
+
+
+void
+on_button_zoom_extended_clicked        (GtkButton       *button,
+                                        gpointer         user_data)
+{
+   zoom_extended((GtkWidget*)button, user_data); 
+}
+
+
+void
+on_button_go_to_time_clicked           (GtkButton       *button,
+                                        gpointer         user_data)
+{
+   go_to_time((GtkWidget*)button, user_data); 
+}
+
+
+void
+on_button_show_time_frame_clicked      (GtkButton       *button,
+                                        gpointer         user_data)
+{
+   show_time_frame((GtkWidget*)button, user_data); 
+}
+
+
+void
+on_button_move_up_clicked              (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  move_up_viewer((GtkWidget*)button, user_data);
+}
+
+
+void
+on_button_move_down_clicked            (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  move_down_viewer((GtkWidget*)button, user_data);
+}
+
+
+void
+on_button_delete_viewer_clicked        (GtkButton       *button,
+                                        gpointer         user_data)
+{
+  delete_viewer((GtkWidget*)button, user_data);
+}
+
+void
+on_MWindow_destroy                     (GtkWidget       *widget,
+                                        gpointer         user_data)
+{
+  MainWindow *main_window = get_window_data_struct(widget);
+  LttvIAttribute *attributes = main_window->attributes;
+  LttvAttributeValue value;
+  //This is unnecessary, since widgets will be destroyed
+  //by the main window widget anyway.
+  //remove_all_menu_toolbar_constructors(main_window, NULL);
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+           "viewers/menu", LTTV_POINTER, &value));
+  lttv_menus_destroy((LttvMenus*)*(value.v_pointer));
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+           "viewers/toolbar", LTTV_POINTER, &value));
+  lttv_toolbars_destroy((LttvToolbars*)*(value.v_pointer));
+
+  g_object_unref(main_window->attributes);
+  g_main_window_list = g_slist_remove(g_main_window_list, main_window);
+
+  g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
+  if(g_slist_length(g_main_window_list) == 0)
+    mainwindow_quit();
+}
+
+gboolean    
+on_MWindow_configure                   (GtkWidget         *widget,
+                                        GdkEventConfigure *event,
+                                        gpointer           user_data)
+{
+  MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
+       
+       // MD : removed time width modification upon resizing of the main window.
+       // The viewers will redraw themselves completely, without time interval
+       // modification.
+/*  while(tab){
+    if(mw_data->window_width){
+      time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
+      time_win = tab->time_window;
+      ratio = width / mw_data->window_width;
+      tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
+      time = ltt_time_sub(time_span->endTime, time_win.start_time);
+      if(ltt_time_compare(time, tab->time_window.time_width) < 0){
+       tab->time_window.time_width = time;
+      }
+    } 
+    tab = tab->next;
+  }
+
+  mw_data->window_width = (int)width;
+       */
+  return FALSE;
+}
+
+/* Set current tab
+ */
+
+void
+on_MNotebook_switch_page               (GtkNotebook     *notebook,
+                                        GtkNotebookPage *page,
+                                        guint            page_num,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void time_change_manager               (Tab *tab,
+                                        TimeWindow new_time_window)
+{
+  /* Only one source of time change */
+  if(tab->time_manager_lock == TRUE) return;
+
+  tab->time_manager_lock = TRUE;
+
+  LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  LttTime start_time = new_time_window.start_time;
+  LttTime end_time = new_time_window.end_time;
+
+  g_assert(ltt_time_compare(start_time, end_time) < 0);
+  
+  /* Set scrollbar */
+  GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
+  LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
+#if 0  
+  gtk_range_set_increments(GTK_RANGE(tab->scrollbar),
+               ltt_time_to_double(new_time_window.time_width)
+                             / SCROLL_STEP_PER_PAGE
+                             * NANOSECONDS_PER_SECOND, /* step increment */
+               ltt_time_to_double(new_time_window.time_width) 
+                 * NANOSECONDS_PER_SECOND); /* page increment */
+  gtk_range_set_range(GTK_RANGE(tab->scrollbar),
+                 0.0, /* lower */
+               ltt_time_to_double(upper) 
+                 * NANOSECONDS_PER_SECOND); /* upper */
+#endif //0
+  g_object_set(G_OBJECT(adjustment),
+               "lower",
+                 0.0, /* lower */
+               "upper",
+               ltt_time_to_double(upper), /* upper */
+               "step_increment",
+               new_time_window.time_width_double
+                             / SCROLL_STEP_PER_PAGE, /* step increment */
+               "page_increment",
+               new_time_window.time_width_double, 
+                                                     /* page increment */
+               "page_size",
+               new_time_window.time_width_double, /* page size */
+               NULL);
+  gtk_adjustment_changed(adjustment);
+
+ // g_object_set(G_OBJECT(adjustment),
+ //              "value",
+ //              ltt_time_to_double(
+ //               ltt_time_sub(start_time, time_span.start_time))
+ //                 , /* value */
+ //              NULL);
+  //gtk_adjustment_value_changed(adjustment);
+  gtk_range_set_value(GTK_RANGE(tab->scrollbar),
+               ltt_time_to_double(
+                ltt_time_sub(start_time, time_span.start_time)) /* value */);
+
+  /* set the time bar. */
+  /* start seconds */
+  gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
+                            (double)time_span.start_time.tv_sec,
+                            (double)time_span.end_time.tv_sec);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry1),
+                            (double)start_time.tv_sec);
+
+  /* start nanoseconds */
+  if(start_time.tv_sec == time_span.start_time.tv_sec) {
+    /* can be both beginning and end at the same time. */
+    if(start_time.tv_sec == time_span.end_time.tv_sec) {
+      /* If we are at the end, max nsec to end..  -1 (not zero length) */
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
+                                (double)time_span.start_time.tv_nsec,
+                                (double)time_span.end_time.tv_nsec-1);
+    } else {
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
+                                (double)time_span.start_time.tv_nsec,
+                                (double)NANOSECONDS_PER_SECOND-1);
+    }
+  } else if(start_time.tv_sec == time_span.end_time.tv_sec) {
+      /* If we are at the end, max nsec to end..  -1 (not zero length) */
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
+                                0.0,
+                                (double)time_span.end_time.tv_nsec-1);
+  } else /* anywhere else */
+    gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry2),
+                              0.0,
+                              (double)NANOSECONDS_PER_SECOND-1);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry2),
+                            (double)start_time.tv_nsec);
+
+  /* end seconds */
+  gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
+                            (double)time_span.start_time.tv_sec,
+                            (double)time_span.end_time.tv_sec);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry3),
+                            (double)end_time.tv_sec);
+
+  /* end nanoseconds */
+  if(end_time.tv_sec == time_span.start_time.tv_sec) {
+    /* can be both beginning and end at the same time. */
+    if(end_time.tv_sec == time_span.end_time.tv_sec) {
+      /* If we are at the end, max nsec to end.. */
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
+                                (double)time_span.start_time.tv_nsec+1,
+                                (double)time_span.end_time.tv_nsec);
+    } else {
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
+                                (double)time_span.start_time.tv_nsec+1,
+                                (double)NANOSECONDS_PER_SECOND-1);
+    }
+  }
+  else if(end_time.tv_sec == time_span.end_time.tv_sec) {
+    /* If we are at the end, max nsec to end.. */
+    gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
+                              0.0,
+                              (double)time_span.end_time.tv_nsec);
+  }
+  else /* anywhere else */
+    gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry4),
+                              0.0,
+                              (double)NANOSECONDS_PER_SECOND-1);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry4),
+                            (double)end_time.tv_nsec);
+
+  /* call viewer hooks for new time window */
+  set_time_window(tab, &new_time_window);
+
+  tab->time_manager_lock = FALSE;
+}
+
+
+/* value changed for frame start s
+ *
+ * Check time span : if ns is out of range, clip it the nearest good value.
+ */
+void
+on_MEntry1_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data)
+{
+  Tab *tab =(Tab *)user_data;
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  gint value = gtk_spin_button_get_value_as_int(spinbutton);
+
+  TimeWindow new_time_window = tab->time_window;
+  LttTime end_time = new_time_window.end_time;
+
+  new_time_window.start_time.tv_sec = value;
+
+  /* start nanoseconds */
+  if(new_time_window.start_time.tv_sec == time_span.start_time.tv_sec) {
+    if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
+      if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
+        new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
+      if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
+        new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
+    } else {
+      if(new_time_window.start_time.tv_nsec < time_span.start_time.tv_nsec)
+        new_time_window.start_time.tv_nsec = time_span.start_time.tv_nsec;
+    }
+  }
+  else if(new_time_window.start_time.tv_sec == time_span.end_time.tv_sec) {
+    if(new_time_window.start_time.tv_nsec > time_span.end_time.tv_nsec)
+      new_time_window.start_time.tv_nsec = time_span.end_time.tv_nsec-1;
+  }
+
+  if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
+    /* Then, we must push back end time : keep the same time width
+     * if possible, else end traceset time */
+    end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
+                                         new_time_window.time_width),
+                            time_span.end_time);
+  }
+
+  /* Fix the time width to fit start time and end time */
+  new_time_window.time_width = ltt_time_sub(end_time,
+                                            new_time_window.start_time);
+  new_time_window.time_width_double =
+              ltt_time_to_double(new_time_window.time_width);
+
+  new_time_window.end_time = end_time;
+
+  time_change_manager(tab, new_time_window);
+
+}
+
+void
+on_MEntry2_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data)
+{
+  Tab *tab =(Tab *)user_data;
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  gint value = gtk_spin_button_get_value_as_int(spinbutton);
+
+  TimeWindow new_time_window = tab->time_window;
+  LttTime end_time = new_time_window.end_time;
+
+  new_time_window.start_time.tv_nsec = value;
+
+  if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
+    /* Then, we must push back end time : keep the same time width
+     * if possible, else end traceset time */
+    end_time = LTT_TIME_MIN(ltt_time_add(new_time_window.start_time,
+                                         new_time_window.time_width),
+                            time_span.end_time);
+  }
+
+  /* Fix the time width to fit start time and end time */
+  new_time_window.time_width = ltt_time_sub(end_time,
+                                            new_time_window.start_time);
+  new_time_window.time_width_double =
+              ltt_time_to_double(new_time_window.time_width);
+
+  new_time_window.end_time = end_time;
+
+  time_change_manager(tab, new_time_window);
+
+}
+
+void
+on_MEntry3_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data)
+{
+  Tab *tab =(Tab *)user_data;
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  gint value = gtk_spin_button_get_value_as_int(spinbutton);
+
+  TimeWindow new_time_window = tab->time_window;
+  LttTime end_time = new_time_window.end_time;
+
+  end_time.tv_sec = value;
+
+  /* end nanoseconds */
+  if(end_time.tv_sec == time_span.start_time.tv_sec) {
+    if(end_time.tv_sec == time_span.end_time.tv_sec) {
+      if(end_time.tv_nsec > time_span.end_time.tv_nsec)
+        end_time.tv_nsec = time_span.end_time.tv_nsec;
+      if(end_time.tv_nsec < time_span.start_time.tv_nsec)
+        end_time.tv_nsec = time_span.start_time.tv_nsec+1;
+    } else {
+      if(end_time.tv_nsec < time_span.start_time.tv_nsec)
+        end_time.tv_nsec = time_span.start_time.tv_nsec+1;
+    }
+  }
+  else if(end_time.tv_sec == time_span.end_time.tv_sec) {
+    if(end_time.tv_nsec > time_span.end_time.tv_nsec)
+      end_time.tv_nsec = time_span.end_time.tv_nsec;
+  }
+
+  if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
+    /* Then, we must push front start time : keep the same time width
+     * if possible, else end traceset time */
+    new_time_window.start_time = LTT_TIME_MAX(
+                                  ltt_time_sub(end_time,
+                                               new_time_window.time_width),
+                                  time_span.start_time);
+  }
+
+  /* Fix the time width to fit start time and end time */
+  new_time_window.time_width = ltt_time_sub(end_time,
+                                            new_time_window.start_time);
+  new_time_window.time_width_double =
+              ltt_time_to_double(new_time_window.time_width);
+
+  new_time_window.end_time = end_time;
+  
+  time_change_manager(tab, new_time_window);
+
+}
+
+void
+on_MEntry4_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data)
+{
+  Tab *tab =(Tab *)user_data;
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  gint value = gtk_spin_button_get_value_as_int(spinbutton);
+
+  TimeWindow new_time_window = tab->time_window;
+  LttTime end_time = new_time_window.end_time;
+
+  end_time.tv_nsec = value;
+
+  if(ltt_time_compare(new_time_window.start_time, end_time) >= 0) {
+    /* Then, we must push front start time : keep the same time width
+     * if possible, else end traceset time */
+    new_time_window.start_time = LTT_TIME_MAX(
+                                ltt_time_sub(end_time,
+                                             new_time_window.time_width),
+                                time_span.start_time);
+  }
+
+  /* Fix the time width to fit start time and end time */
+  new_time_window.time_width = ltt_time_sub(end_time,
+                                            new_time_window.start_time);
+  new_time_window.time_width_double =
+              ltt_time_to_double(new_time_window.time_width);
+  new_time_window.end_time = end_time;
+
+  time_change_manager(tab, new_time_window);
+
+}
+
+
+void current_time_change_manager       (Tab *tab,
+                                        LttTime new_current_time)
+{
+  /* Only one source of time change */
+  if(tab->current_time_manager_lock == TRUE) return;
+
+  tab->current_time_manager_lock = TRUE;
+
+  LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+
+  /* current seconds */
+  gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
+                            (double)time_span.start_time.tv_sec,
+                            (double)time_span.end_time.tv_sec);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry5),
+                            (double)new_current_time.tv_sec);
+
+
+  /* start nanoseconds */
+  if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
+    /* can be both beginning and end at the same time. */
+    if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
+      /* If we are at the end, max nsec to end..  */
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
+                                (double)time_span.start_time.tv_nsec,
+                                (double)time_span.end_time.tv_nsec);
+    } else {
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
+                                (double)time_span.start_time.tv_nsec,
+                                (double)NANOSECONDS_PER_SECOND-1);
+    }
+  } else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
+      /* If we are at the end, max nsec to end..  */
+      gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
+                                0.0,
+                                (double)time_span.end_time.tv_nsec);
+  } else /* anywhere else */
+    gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry6),
+                              0.0,
+                              (double)NANOSECONDS_PER_SECOND-1);
+
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(tab->MEntry6),
+                            (double)new_current_time.tv_nsec);
+
+  set_current_time(tab, &new_current_time);
+
+  tab->current_time_manager_lock = FALSE;
+}
+
+void current_position_change_manager(Tab *tab,
+                                     LttvTracesetContextPosition *pos)
+{
+  LttvTracesetContext *tsc =
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+
+  g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0);
+  LttTime new_time = lttv_traceset_context_position_get_time(pos);
+  /* Put the context in a state coherent position */
+  lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, ltt_time_zero);
+  
+  current_time_change_manager(tab, new_time);
+  
+  set_current_position(tab, pos);
+}
+
+
+void
+on_MEntry5_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data)
+{
+  Tab *tab = (Tab*)user_data;
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  gint value = gtk_spin_button_get_value_as_int(spinbutton);
+  LttTime new_current_time = tab->current_time;
+  new_current_time.tv_sec = value;
+
+  /* current nanoseconds */
+  if(new_current_time.tv_sec == time_span.start_time.tv_sec) {
+    if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
+      if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
+        new_current_time.tv_nsec = time_span.end_time.tv_nsec;
+      if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
+        new_current_time.tv_nsec = time_span.start_time.tv_nsec;
+    } else {
+      if(new_current_time.tv_nsec < time_span.start_time.tv_nsec)
+        new_current_time.tv_nsec = time_span.start_time.tv_nsec;
+    }
+  }
+  else if(new_current_time.tv_sec == time_span.end_time.tv_sec) {
+    if(new_current_time.tv_nsec > time_span.end_time.tv_nsec)
+      new_current_time.tv_nsec = time_span.end_time.tv_nsec;
+  }
+
+  current_time_change_manager(tab, new_current_time);
+}
+
+void
+on_MEntry6_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data)
+{
+  Tab *tab = (Tab*)user_data;
+  gint value = gtk_spin_button_get_value_as_int(spinbutton);
+  LttTime new_current_time = tab->current_time;
+  new_current_time.tv_nsec = value;
+
+  current_time_change_manager(tab, new_current_time);
+}
+
+
+void scroll_value_changed_cb(GtkWidget *scrollbar,
+                             gpointer user_data)
+{
+  Tab *tab = (Tab *)user_data;
+  TimeWindow new_time_window;
+  LttTime time;
+  GtkAdjustment *adjust = gtk_range_get_adjustment(GTK_RANGE(scrollbar));
+  gdouble value = gtk_adjustment_get_value(adjust);
+ // gdouble upper, lower, ratio, page_size;
+  gdouble page_size;
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+
+  time = ltt_time_add(ltt_time_from_double(value),
+                      time_span.start_time);
+
+  new_time_window.start_time = time;
+  
+  page_size = adjust->page_size;
+
+  new_time_window.time_width = 
+    ltt_time_from_double(page_size);
+
+  new_time_window.time_width_double =
+              page_size;
+
+  new_time_window.end_time = ltt_time_add(new_time_window.start_time, 
+                                          new_time_window.time_width);
+
+
+  time_change_manager(tab, new_time_window);
+#if 0
+  //time_window = tab->time_window;
+
+  lower = adjust->lower;
+  upper = adjust->upper;
+  ratio = (value - lower) / (upper - lower);
+  g_info("lower %lu, upper %lu, value %lu, ratio %lu", lower, upper, value, ratio);
+  
+  //time = ltt_time_sub(time_span->end_time, time_span->start_time);
+  //time = ltt_time_mul(time, (float)ratio);
+  //time = ltt_time_add(time_span->start_time, time);
+  time = ltt_time_add(ltt_time_from_double(value),
+                      time_span.start_time);
+
+  time_window.start_time = time;
+  
+  page_size = adjust->page_size;
+
+  time_window.time_width = 
+    ltt_time_from_double(page_size);
+  //time = ltt_time_sub(time_span.end_time, time);
+  //if(ltt_time_compare(time,time_window.time_width) < 0){
+  //  time_window.time_width = time;
+  //}
+
+  /* call viewer hooks for new time window */
+  set_time_window(tab, &time_window);
+#endif //0
+}
+
+
+/* Display a dialogue showing all eventtypes and traces, let user to select the interested
+ * eventtypes, tracefiles and traces (filter)
+ */
+
+/* Select a trace which will be removed from traceset
+ */
+
+char * get_remove_trace(MainWindow *mw_data, 
+    char ** all_trace_name, int nb_trace)
+{
+  return get_selection(mw_data, all_trace_name, nb_trace, 
+                      "Select a trace", "Trace pathname");
+}
+
+
+/* Select a module which will be loaded
+ */
+
+char * get_load_module(MainWindow *mw_data, 
+    char ** load_module_name, int nb_module)
+{
+  return get_selection(mw_data, load_module_name, nb_module, 
+                      "Select a module to load", "Module name");
+}
+
+
+
+
+/* Select a module which will be unloaded
+ */
+
+char * get_unload_module(MainWindow *mw_data,
+    char ** loaded_module_name, int nb_module)
+{
+  return get_selection(mw_data, loaded_module_name, nb_module, 
+                      "Select a module to unload", "Module name");
+}
+
+
+/* Display a dialogue which shows all selectable items, let user to 
+ * select one of them
+ */
+
+char * get_selection(MainWindow *mw_data,
+    char ** loaded_module_name, int nb_module,
+         char *title, char * column_title)
+{
+  GtkWidget         * dialogue;
+  GtkWidget         * scroll_win;
+  GtkWidget         * tree;
+  GtkListStore      * store;
+  GtkTreeViewColumn * column;
+  GtkCellRenderer   * renderer;
+  GtkTreeSelection  * select;
+  GtkTreeIter         iter;
+  gint                id, i;
+  char              * unload_module_name = NULL;
+
+  dialogue = gtk_dialog_new_with_buttons(title,
+                                        NULL,
+                                        GTK_DIALOG_MODAL,
+                                        GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
+                                        GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
+                                        NULL); 
+  gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
+  gtk_window_set_transient_for(GTK_WINDOW(dialogue), 
+      GTK_WINDOW(mw_data->mwindow));
+
+  scroll_win = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show ( scroll_win);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win), 
+                                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+  store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
+  tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
+  gtk_widget_show ( tree);
+  g_object_unref (G_OBJECT (store));
+               
+  renderer = gtk_cell_renderer_text_new ();
+  column   = gtk_tree_view_column_new_with_attributes (column_title,
+                                                    renderer,
+                                                    "text", MODULE_COLUMN,
+                                                    NULL);
+  gtk_tree_view_column_set_alignment (column, 0.5);
+  gtk_tree_view_column_set_fixed_width (column, 150);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+  select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
+  gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
+
+  gtk_container_add (GTK_CONTAINER (scroll_win), tree);  
+
+  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
+
+  for(i=0;i<nb_module;i++){
+    gtk_list_store_append (store, &iter);
+    gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
+  }
+
+  id = gtk_dialog_run(GTK_DIALOG(dialogue));
+  GtkTreeModel **store_model = (GtkTreeModel**)&store;
+  switch(id){
+    case GTK_RESPONSE_ACCEPT:
+    case GTK_RESPONSE_OK:
+      if (gtk_tree_selection_get_selected (select, store_model, &iter)){
+         gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
+      }
+    case GTK_RESPONSE_REJECT:
+    case GTK_RESPONSE_CANCEL:
+    default:
+      gtk_widget_destroy(dialogue);
+      break;
+  }
+
+  return unload_module_name;
+}
+
+
+/* Insert all menu entry and tool buttons into this main window
+ * for modules.
+ *
+ */
+
+void add_all_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
+{
+  guint i;
+  GdkPixbuf *pixbuf;
+  lttvwindow_viewer_constructor constructor;
+  LttvMenus * global_menu, * instance_menu;
+  LttvToolbars * global_toolbar, * instance_toolbar;
+  LttvMenuClosure *menu_item;
+  LttvToolbarClosure *toolbar_item;
+  LttvAttributeValue value;
+  LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+  LttvIAttribute *attributes = mw->attributes;
+  GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
+
+  g_assert(lttv_iattribute_find_by_path(global_attributes,
+          "viewers/menu", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_menus_new();
+  global_menu = (LttvMenus*)*(value.v_pointer);
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+          "viewers/menu", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_menus_new();
+  instance_menu = (LttvMenus*)*(value.v_pointer);
+
+
+
+  g_assert(lttv_iattribute_find_by_path(global_attributes,
+          "viewers/toolbar", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_toolbars_new();
+  global_toolbar = (LttvToolbars*)*(value.v_pointer);
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+          "viewers/toolbar", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_toolbars_new();
+  instance_toolbar = (LttvToolbars*)*(value.v_pointer);
+
+  /* Add missing menu entries to window instance */
+  for(i=0;i<global_menu->len;i++) {
+    menu_item = &g_array_index(global_menu, LttvMenuClosure, i);
+
+    //add menu_item to window instance;
+    constructor = menu_item->con;
+    tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
+    new_widget =
+      gtk_menu_item_new_with_mnemonic (menu_item->menu_text);
+    gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
+        new_widget);
+    g_signal_connect ((gpointer) new_widget, "activate",
+        G_CALLBACK (insert_viewer_wrap),
+        constructor);  
+    gtk_widget_show (new_widget);
+    lttv_menus_add(instance_menu, menu_item->con, 
+        menu_item->menu_path,
+        menu_item->menu_text,
+        new_widget);
+
+  }
+
+  /* Add missing toolbar entries to window instance */
+  for(i=0;i<global_toolbar->len;i++) {
+    toolbar_item = &g_array_index(global_toolbar, LttvToolbarClosure, i);
+
+    //add toolbar_item to window instance;
+    constructor = toolbar_item->con;
+    tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
+    pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
+    pixmap = gtk_image_new_from_pixbuf(pixbuf);
+    new_widget =
+       gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
+          GTK_TOOLBAR_CHILD_BUTTON,
+          NULL,
+          "",
+          toolbar_item->tooltip, NULL,
+          pixmap, NULL, NULL);
+    gtk_label_set_use_underline(
+        GTK_LABEL (((GtkToolbarChild*) (
+                         g_list_last (GTK_TOOLBAR 
+                            (tool_menu_title_menu)->children)->data))->label),
+        TRUE);
+    gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
+    g_signal_connect ((gpointer) new_widget,
+        "clicked",
+        G_CALLBACK (insert_viewer_wrap),
+        constructor);       
+    gtk_widget_show (new_widget);
+    lttv_toolbars_add(instance_toolbar, toolbar_item->con, 
+                      toolbar_item->tooltip,
+                      toolbar_item->pixmap,
+                      new_widget);
+
+  }
+
+}
+
+
+/* Create a main window
+ */
+
+MainWindow *construct_main_window(MainWindow * parent)
+{
+  g_debug("construct_main_window()");
+  GtkWidget  * new_window; /* New generated main window */
+  MainWindow * new_m_window;/* New main window structure */
+  GtkNotebook * notebook;
+  LttvIAttribute *attributes =
+         LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
+  LttvAttributeValue value;
+  Tab *new_tab;
+         
+  new_m_window = g_new(MainWindow, 1);
+
+  // Add the object's information to the module's array 
+  g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
+
+  new_window  = create_MWindow();
+  gtk_widget_show (new_window);
+    
+  new_m_window->mwindow = new_window;
+  new_m_window->attributes = attributes;
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+           "viewers/menu", LTTV_POINTER, &value));
+  *(value.v_pointer) = lttv_menus_new();
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+           "viewers/toolbar", LTTV_POINTER, &value));
+  *(value.v_pointer) = lttv_toolbars_new();
+
+  add_all_menu_toolbar_constructors(new_m_window, NULL);
+  
+  g_object_set_data_full(G_OBJECT(new_window),
+                         "main_window_data",
+                         (gpointer)new_m_window,
+                         (GDestroyNotify)g_free);
+  //create a default tab
+  notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
+  if(notebook == NULL){
+    g_info("Notebook does not exist\n");
+    /* FIXME : destroy partially created widgets */
+    g_free(new_m_window);
+    return NULL;
+  }
+  //gtk_notebook_popup_enable (GTK_NOTEBOOK(notebook));
+  //for now there is no name field in LttvTraceset structure
+  //Use "Traceset" as the label for the default tab
+  if(parent) {
+    GtkWidget * parent_notebook = lookup_widget(parent->mwindow, "MNotebook");
+    GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent_notebook),
+                 gtk_notebook_get_current_page(GTK_NOTEBOOK(parent_notebook)));
+    Tab *parent_tab;
+
+    if(!page) {
+      parent_tab = NULL;
+    } else {
+      parent_tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+    }
+    new_tab = create_tab(new_m_window, parent_tab, notebook, "Traceset");
+  } else {
+    new_tab = create_tab(new_m_window, NULL, notebook, "Traceset");
+  }
+
+  /* Insert default viewers */
+  {
+    LttvAttributeType type;
+    LttvAttributeName name;
+    LttvAttributeValue value;
+    LttvAttribute *attribute;
+    
+    LttvIAttribute *attributes_global = 
+       LTTV_IATTRIBUTE(lttv_global_attributes());
+
+    g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(attributes_global),
+                                LTTV_VIEWER_CONSTRUCTORS)));
+
+    name = g_quark_from_string("guievents");
+    type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                       name, &value);
+    if(type == LTTV_POINTER) {
+      lttvwindow_viewer_constructor viewer_constructor = 
+                (lttvwindow_viewer_constructor)*value.v_pointer;
+      insert_viewer(new_window, viewer_constructor);
+    }
+
+    name = g_quark_from_string("guicontrolflow");
+    type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                       name, &value);
+    if(type == LTTV_POINTER) {
+      lttvwindow_viewer_constructor viewer_constructor = 
+                (lttvwindow_viewer_constructor)*value.v_pointer;
+      insert_viewer(new_window, viewer_constructor);
+    }
+
+    name = g_quark_from_string("guistatistics");
+    type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                       name, &value);
+    if(type == LTTV_POINTER) {
+      lttvwindow_viewer_constructor viewer_constructor = 
+                (lttvwindow_viewer_constructor)*value.v_pointer;
+      insert_viewer(new_window, viewer_constructor);
+    }
+  }
+
+  g_info("There are now : %d windows\n",g_slist_length(g_main_window_list));
+
+  return new_m_window;
+}
+
+
+/* Free the memory occupied by a tab structure
+ * destroy the tab
+ */
+
+void tab_destructor(Tab * tab)
+{
+  int i, nb, ref_count;
+  LttvTrace * trace;
+
+  gtk_object_destroy(GTK_OBJECT(tab->tooltips));
+  
+  if(tab->attributes)
+    g_object_unref(tab->attributes);
+
+  if(tab->interrupted_state)
+    g_object_unref(tab->interrupted_state);
+
+
+  if(tab->traceset_info->traceset_context != NULL){
+    //remove state update hooks
+    lttv_state_remove_event_hooks(
+         (LttvTracesetState*)tab->traceset_info->
+                              traceset_context);
+    lttv_context_fini(LTTV_TRACESET_CONTEXT(tab->traceset_info->
+                                           traceset_context));
+    g_object_unref(tab->traceset_info->traceset_context);
+  }
+  if(tab->traceset_info->traceset != NULL) {
+    nb = lttv_traceset_number(tab->traceset_info->traceset);
+    for(i = 0 ; i < nb ; i++) {
+      trace = lttv_traceset_get(tab->traceset_info->traceset, i);
+      ref_count = lttv_trace_get_ref_number(trace);
+      if(ref_count <= 1){
+             ltt_trace_close(lttv_trace(trace));
+      }
+    }
+  }
+  lttv_filter_destroy(tab->filter);
+  lttv_traceset_destroy(tab->traceset_info->traceset);
+  /* Remove the idle events requests processing function of the tab */
+  g_idle_remove_by_data(tab);
+
+  g_slist_free(tab->events_requests);
+  g_free(tab->traceset_info);
+  g_free(tab);
+}
+
+
+/* Create a tab and insert it into the current main window
+ */
+
+Tab* create_tab(MainWindow * mw, Tab *copy_tab, 
+                 GtkNotebook * notebook, char * label)
+{
+  GList * list;
+  Tab * tab;
+  
+  //create a new tab data structure
+  tab = g_new(Tab,1);
+
+  //construct and initialize the traceset_info
+  tab->traceset_info = g_new(TracesetInfo,1);
+
+  if(copy_tab) {
+    tab->traceset_info->traceset = 
+      lttv_traceset_copy(copy_tab->traceset_info->traceset);
+    
+    /* Copy the previous tab's filter */
+    /* We can clone the filter, as we copy the trace set also */
+    /* The filter must always be in sync with the trace set */
+    tab->filter = lttv_filter_clone(copy_tab->filter);
+  } else {
+    tab->traceset_info->traceset = lttv_traceset_new();
+    tab->filter = NULL;
+  }
+#ifdef DEBUG
+  lttv_attribute_write_xml(
+      lttv_traceset_attribute(tab->traceset_info->traceset),
+      stdout,
+      0, 4);
+  fflush(stdout);
+#endif //DEBUG
+
+  tab->time_manager_lock = FALSE;
+  tab->current_time_manager_lock = FALSE;
+
+  //FIXME copy not implemented in lower level
+  tab->traceset_info->traceset_context =
+    g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+  g_assert(tab->traceset_info->traceset_context != NULL);
+  lttv_context_init(
+           LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context),
+                                 tab->traceset_info->traceset);
+  //add state update hooks
+  lttv_state_add_event_hooks(
+       (LttvTracesetState*)tab->traceset_info->traceset_context);
+  
+  //determine the current_time and time_window of the tab
+#if 0
+  if(copy_tab != NULL){
+    tab->time_window      = copy_tab->time_window;
+    tab->current_time     = copy_tab->current_time;
+  }else{
+    tab->time_window.start_time = 
+           LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
+                             time_span.start_time;
+    if(DEFAULT_TIME_WIDTH_S <
+              LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
+                             time_span.end_time.tv_sec)
+      tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
+    else
+      tmp_time.tv_sec =
+              LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
+                             time_span.end_time.tv_sec;
+    tmp_time.tv_nsec = 0;
+    tab->time_window.time_width = tmp_time ;
+    tab->current_time.tv_sec = 
+       LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
+                             time_span.start_time.tv_sec;
+    tab->current_time.tv_nsec = 
+       LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->
+                             time_span.start_time.tv_nsec;
+  }
+#endif //0
+  tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
+  tab->interrupted_state = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  tab->vbox = gtk_vbox_new(FALSE, 2);
+  tab->viewer_container = gtk_vbox_new(TRUE, 2);
+  tab->scrollbar = gtk_hscrollbar_new(NULL);
+  //tab->multivpaned = gtk_multi_vpaned_new();
+  gtk_box_pack_start(GTK_BOX(tab->vbox),
+                     tab->viewer_container,
+                     TRUE, /* expand */
+                     TRUE, /* Give the extra space to the child */
+                     0);    /* No padding */
+  
+//  if(copy_tab) {
+//    tab->time_window = copy_tab->time_window;
+//    tab->current_time = copy_tab->current_time;
+//  }
+
+  /* Create the timebar */
+  {
+    tab->MTimebar = gtk_hbox_new(FALSE, 2);
+    gtk_widget_show(tab->MTimebar);
+    tab->tooltips = gtk_tooltips_new();
+
+    tab->MEventBox1a = gtk_event_box_new();
+    gtk_widget_show(tab->MEventBox1a);
+    gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1a, 
+        "Paste Start and End Times Here", "");
+    tab->MText1a = gtk_label_new("Time Frame ");
+    gtk_widget_show(tab->MText1a);
+    gtk_container_add(GTK_CONTAINER(tab->MEventBox1a), tab->MText1a);
+    tab->MEventBox1b = gtk_event_box_new();
+    gtk_widget_show(tab->MEventBox1b);
+    gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox1b, 
+        "Paste Start Time Here", "");
+    tab->MText1b = gtk_label_new("start: ");
+    gtk_widget_show(tab->MText1b);
+    gtk_container_add(GTK_CONTAINER(tab->MEventBox1b), tab->MText1b);
+    tab->MText2 = gtk_label_new("s");
+    gtk_widget_show(tab->MText2);
+    tab->MText3a = gtk_label_new("ns");
+    gtk_widget_show(tab->MText3a);
+    tab->MEventBox3b = gtk_event_box_new();
+    gtk_widget_show(tab->MEventBox3b);
+    gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox3b, 
+        "Paste End Time Here", "");
+    tab->MText3b = gtk_label_new("end:");
+    gtk_widget_show(tab->MText3b);
+    gtk_container_add(GTK_CONTAINER(tab->MEventBox3b), tab->MText3b);
+    tab->MText4 = gtk_label_new("s");
+    gtk_widget_show(tab->MText4);
+    tab->MText5a = gtk_label_new("ns");
+    gtk_widget_show(tab->MText5a);
+    tab->MEventBox5b = gtk_event_box_new();
+    gtk_widget_show(tab->MEventBox5b);
+    gtk_tooltips_set_tip(tab->tooltips, tab->MEventBox5b, 
+        "Paste Current Time Here", "");
+    tab->MText5b = gtk_label_new("Current Time:");
+    gtk_widget_show(tab->MText5b);
+    gtk_container_add(GTK_CONTAINER(tab->MEventBox5b), tab->MText5b);
+    tab->MText6 = gtk_label_new("s");
+    gtk_widget_show(tab->MText6);
+    tab->MText7 = gtk_label_new("ns");
+    gtk_widget_show(tab->MText7);
+
+    tab->MEntry1 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
+    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry1),0);
+    gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry1),TRUE);
+    gtk_widget_show(tab->MEntry1);
+    tab->MEntry2 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
+    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry2),0);
+    gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry2),TRUE);
+    gtk_widget_show(tab->MEntry2);
+    tab->MEntry3 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
+    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry3),0);
+    gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry3),TRUE);
+    gtk_widget_show(tab->MEntry3);
+    tab->MEntry4 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
+    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry4),0);
+    gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry4),TRUE);
+    gtk_widget_show(tab->MEntry4);
+    tab->MEntry5 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
+    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry5),0);
+    gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry5),TRUE);
+    gtk_widget_show(tab->MEntry5);
+    tab->MEntry6 = gtk_spin_button_new_with_range(0.0, 1.0, 1.0);
+    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(tab->MEntry6),0);
+    gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(tab->MEntry6),TRUE);
+    gtk_widget_show(tab->MEntry6);
+
+    
+    GtkWidget *temp_widget;
+    
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1a, FALSE,
+                         FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox1b, FALSE,
+                         FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry1, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText2, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry2, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText3a, FALSE, FALSE, 0);
+    temp_widget = gtk_vseparator_new();
+    gtk_widget_show(temp_widget);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEventBox3b, FALSE,
+                         FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry3, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText4, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MEntry4, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (tab->MTimebar), tab->MText5a, FALSE, FALSE, 0);
+    temp_widget = gtk_vseparator_new();
+    gtk_widget_show(temp_widget);
+    gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText7, FALSE, FALSE, 0);
+    gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry6, FALSE, FALSE, 0);
+    gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MText6, FALSE, FALSE, 0);
+    gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEntry5, FALSE, FALSE, 0);
+    gtk_box_pack_end (GTK_BOX (tab->MTimebar), tab->MEventBox5b, FALSE,
+                         FALSE, 0);
+    gtk_box_pack_end (GTK_BOX (tab->MTimebar), temp_widget, FALSE, FALSE, 0);
+    
+
+    //GtkWidget *test = gtk_button_new_with_label("drop");
+    //gtk_button_set_relief(GTK_BUTTON(test), GTK_RELIEF_NONE);
+    //gtk_widget_show(test);
+    //gtk_box_pack_end(GTK_BOX (tab->MTimebar), test, FALSE, FALSE, 0);
+    //gtk_widget_add_events(tab->MText1, GDK_ALL_EVENTS_MASK);//GDK_BUTTON_PRESS_MASK);
+    /*GtkWidget *event_box = gtk_event_box_new();
+    gtk_widget_show(event_box);
+    gtk_tooltips_set_tip(tooltips, event_box, 
+        "Paste Current Time Here", "");
+    gtk_box_pack_end(GTK_BOX (tab->MTimebar), event_box, FALSE, FALSE, 0);
+    GtkWidget *test = gtk_label_new("drop");
+    gtk_container_add(GTK_CONTAINER(event_box), test);
+    gtk_widget_show(test);
+    g_signal_connect (G_OBJECT(event_box),
+                      "button-press-event",
+                      G_CALLBACK (on_MText1_paste),
+                      (gpointer)tab);
+*/
+
+    g_signal_connect (G_OBJECT(tab->MEventBox1a),
+                      "button-press-event",
+                      G_CALLBACK (on_MEventBox1a_paste),
+                      (gpointer)tab);
+
+    g_signal_connect (G_OBJECT(tab->MEventBox1b),
+                      "button-press-event",
+                      G_CALLBACK (on_MEventBox1b_paste),
+                      (gpointer)tab);
+    g_signal_connect (G_OBJECT(tab->MEventBox3b),
+                      "button-press-event",
+                      G_CALLBACK (on_MEventBox3b_paste),
+                      (gpointer)tab);
+    g_signal_connect (G_OBJECT(tab->MEventBox5b),
+                      "button-press-event",
+                      G_CALLBACK (on_MEventBox5b_paste),
+                      (gpointer)tab);
+  }
+
+  gtk_box_pack_end(GTK_BOX(tab->vbox),
+                   tab->scrollbar,
+                   FALSE, /* Do not expand */
+                   FALSE, /* Fill has no effect here  (expand false) */
+                   0);    /* No padding */
+  
+  gtk_box_pack_end(GTK_BOX(tab->vbox),
+                   tab->MTimebar,
+                   FALSE, /* Do not expand */
+                   FALSE, /* Fill has no effect here  (expand false) */
+                   0);    /* No padding */
+
+  g_object_set_data(G_OBJECT(tab->viewer_container), "focused_viewer", NULL);
+
+
+  tab->mw   = mw;
+  
+  /*{
+    // Display a label with a X
+    GtkWidget *w_hbox = gtk_hbox_new(FALSE, 4);
+    GtkWidget *w_label = gtk_label_new (label);
+    GtkWidget *pixmap = create_pixmap(GTK_WIDGET(notebook), "close.png");
+    GtkWidget *w_button = gtk_button_new ();
+    gtk_container_add(GTK_CONTAINER(w_button), pixmap);
+    //GtkWidget *w_button = gtk_button_new_with_label("x");
+
+    gtk_button_set_relief(GTK_BUTTON(w_button), GTK_RELIEF_NONE);
+    
+    gtk_box_pack_start(GTK_BOX(w_hbox), w_label, TRUE, TRUE, 0);
+    gtk_box_pack_end(GTK_BOX(w_hbox), w_button, FALSE,
+                       FALSE, 0);
+
+    g_signal_connect_swapped (w_button, "clicked",
+                      G_CALLBACK (on_close_tab_X_clicked),
+                      tab->multi_vpaned);
+
+    gtk_widget_set_state(w_button, GTK_STATE_ACTIVE);
+
+    gtk_widget_show (w_label);
+    gtk_widget_show (pixmap);
+    gtk_widget_show (w_button);
+    gtk_widget_show (w_hbox);
+
+    tab->label = w_hbox;
+  }*/
+
+
+  tab->label = gtk_label_new (label);
+
+  gtk_widget_show(tab->label);
+  gtk_widget_show(tab->scrollbar);
+  gtk_widget_show(tab->viewer_container);
+  gtk_widget_show(tab->vbox);
+  //gtk_widget_show(tab->multivpaned);
+
+
+  /* Start with empty events requests list */
+  tab->events_requests = NULL;
+  tab->events_request_pending = FALSE;
+
+  g_object_set_data_full(
+           G_OBJECT(tab->vbox),
+           "Tab_Info",
+                tab,
+                (GDestroyNotify)tab_destructor);
+
+  g_signal_connect(G_OBJECT(tab->scrollbar), "value-changed",
+      G_CALLBACK(scroll_value_changed_cb), tab);
+
+  g_signal_connect ((gpointer) tab->MEntry1, "value-changed",
+                    G_CALLBACK (on_MEntry1_value_changed),
+                    tab);
+  g_signal_connect ((gpointer) tab->MEntry2, "value-changed",
+                    G_CALLBACK (on_MEntry2_value_changed),
+                    tab);
+  g_signal_connect ((gpointer) tab->MEntry3, "value-changed",
+                    G_CALLBACK (on_MEntry3_value_changed),
+                    tab);
+  g_signal_connect ((gpointer) tab->MEntry4, "value-changed",
+                    G_CALLBACK (on_MEntry4_value_changed),
+                    tab);
+  g_signal_connect ((gpointer) tab->MEntry5, "value-changed",
+                    G_CALLBACK (on_MEntry5_value_changed),
+                    tab);
+  g_signal_connect ((gpointer) tab->MEntry6, "value-changed",
+                    G_CALLBACK (on_MEntry6_value_changed),
+                    tab);
+
+  //g_signal_connect(G_OBJECT(tab->scrollbar), "changed",
+  //    G_CALLBACK(scroll_value_changed_cb), tab);
+
+
+ //insert tab into notebook
+  gtk_notebook_append_page(notebook,
+                           tab->vbox,
+                           tab->label);  
+  list = gtk_container_get_children(GTK_CONTAINER(notebook));
+  gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
+  // always show : not if(g_list_length(list)>1)
+  gtk_notebook_set_show_tabs(notebook, TRUE);
+  if(copy_tab) {
+    lttvwindow_report_time_window(tab, copy_tab->time_window);
+    lttvwindow_report_current_time(tab, copy_tab->current_time);
+  } else {
+    TimeWindow time_window;
+
+    time_window.start_time = ltt_time_zero;
+    time_window.end_time = ltt_time_add(time_window.start_time,
+        lttvwindow_default_time_width);
+    time_window.time_width = lttvwindow_default_time_width;
+    time_window.time_width_double = ltt_time_to_double(time_window.time_width);
+
+    lttvwindow_report_time_window(tab, time_window);
+    lttvwindow_report_current_time(tab, ltt_time_zero);
+  }
+  LttvTraceset *traceset = tab->traceset_info->traceset;
+  SetTraceset(tab, traceset);
+
+  return tab;
+}
+
+/*
+ * execute_events_requests
+ *
+ * Idle function that executes the pending requests for a tab.
+ *
+ * @return return value : TRUE : keep the idle function, FALSE : remove it.
+ */
+gboolean execute_events_requests(Tab *tab)
+{
+  return ( lttvwindow_process_pending_requests(tab) );
+}
+
+
+void create_main_window_with_trace(gchar *path)
+{
+  if(path == NULL) return;
+
+  /* Create window */
+  MainWindow *mw = construct_main_window(NULL);
+  GtkWidget *widget = mw->mwindow;
+
+  GtkWidget * notebook = lookup_widget(widget, "MNotebook");
+  GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                      gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+  Tab *tab;
+  
+  if(!page) {
+    tab = create_new_tab(widget, NULL);
+  } else {
+    tab = (Tab *)g_object_get_data(G_OBJECT(page), "Tab_Info");
+  }
+
+  /* Add trace */
+  gchar abs_path[PATH_MAX];
+  LttvTrace *trace_v;
+  LttTrace *trace;
+
+  get_absolute_pathname(path, abs_path);
+  trace_v = lttvwindowtraces_get_trace_by_name(abs_path);
+  if(trace_v == NULL) {
+    trace = ltt_trace_open(abs_path);
+    if(trace == NULL) {
+      g_warning("cannot open trace %s", abs_path);
+
+      GtkWidget *dialogue = 
+        gtk_message_dialog_new(
+          GTK_WINDOW(gtk_widget_get_toplevel(widget)),
+          GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+          GTK_MESSAGE_ERROR,
+          GTK_BUTTONS_OK,
+          "Cannot open trace : maybe you should enter in the directory"
+          "to select it ?");
+      gtk_dialog_run(GTK_DIALOG(dialogue));
+      gtk_widget_destroy(dialogue);
+    } else {
+      trace_v = lttv_trace_new(trace);
+      lttvwindowtraces_add_trace(trace_v);
+      lttvwindow_add_trace(tab, trace_v);
+    }
+  } else {
+    lttvwindow_add_trace(tab, trace_v);
+  }
+
+  LttvTraceset *traceset;
+
+  traceset = tab->traceset_info->traceset;
+  SetTraceset(tab, traceset);
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h
new file mode 100644 (file)
index 0000000..e517472
--- /dev/null
@@ -0,0 +1,315 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <lttvwindow/mainwindow.h>
+
+/* internal functions */
+
+void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone);
+void insert_menu_toolbar_item(MainWindow * mw, gpointer user_data);
+MainWindow *construct_main_window(MainWindow * parent);
+void main_window_free(MainWindow * mw);
+void main_window_destructor(MainWindow * mw);
+
+void create_main_window_with_trace(gchar *path);
+
+void insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data);
+gboolean execute_events_requests(Tab *tab);
+
+
+/* callback functions*/
+
+void
+on_empty_traceset_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_clone_traceset_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_tab_activate                        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_open_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_close_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_close_tab_X_clicked                 (GtkWidget       *widget,
+                                        gpointer         user_data);
+
+void
+on_close_tab_activate                  (GtkWidget       *widget,
+                                        gpointer         user_data);
+
+void
+on_add_trace_activate                  (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_remove_trace_activate               (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_save_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_save_as_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_quit_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_cut_activate                        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_copy_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_paste_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_delete_activate                     (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_zoom_in_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_zoom_out_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_zoom_extended_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_go_to_time_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_show_time_frame_activate            (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_move_viewer_up_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_move_viewer_down_activate           (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_remove_viewer_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_trace_filter_activate              (GtkMenuItem     *menuitem,
+                                      gpointer         user_data);
+
+void
+on_trace_facility_activate              (GtkMenuItem     *menuitem,
+                                      gpointer         user_data);
+
+void
+on_load_library_activate                (GtkMenuItem     *menuitem,
+                                         gpointer         user_data);
+
+void
+on_unload_library_activate                (GtkMenuItem     *menuitem,
+                                         gpointer         user_data);
+
+
+void
+on_load_module_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_unload_module_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_add_library_search_path_activate     (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+void
+on_remove_library_search_path_activate     (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_color_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_filter_activate                     (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_save_configuration_activate         (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_content_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_about_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_button_new_clicked                  (GtkButton       *button,
+                                        gpointer         user_data);
+void
+on_button_new_tab_clicked              (GtkButton       *button,
+                                        gpointer         user_data);
+void
+on_button_open_clicked                 (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_add_trace_clicked            (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_remove_trace_clicked         (GtkButton       *button,
+                                        gpointer         user_data);
+void
+on_button_redraw_clicked               (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_continue_processing_clicked  (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_stop_processing_clicked      (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_save_clicked                 (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_save_as_clicked              (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_zoom_in_clicked              (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_zoom_out_clicked             (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_zoom_extended_clicked        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_go_to_time_clicked           (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_show_time_frame_clicked      (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_move_up_clicked              (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_move_down_clicked            (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_button_delete_viewer_clicked        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_MWindow_destroy                     (GtkWidget       *widget,
+                                        gpointer         user_data);
+
+gboolean    
+on_MWindow_configure                   (GtkWidget         *widget,
+                                        GdkEventConfigure *event,
+                                        gpointer           user_data);
+
+gboolean    
+on_MWindow_expose                   (GtkWidget         *widget,
+                                        GdkEventExpose *event,
+                                        gpointer           user_data);
+gboolean    
+on_MWindow_after                   (GtkWidget         *widget,
+                                        GdkEvent *event,
+                                        gpointer           user_data);
+
+
+
+void
+on_insert_viewer_test_activate         (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+insertViewTest(GtkMenuItem *menuitem, gpointer user_data);
+
+void
+on_MNotebook_switch_page               (GtkNotebook     *notebook,
+                                        GtkNotebookPage *page,
+                                        guint            page_num,
+                                        gpointer         user_data);
+
+
+void
+on_MEntry1_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data);
+void
+on_MEntry2_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data);
+void
+on_MEntry3_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data);
+void
+on_MEntry4_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data);
+void
+on_MEntry5_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data);
+void
+on_MEntry6_value_changed               (GtkSpinButton *spinbutton,
+                                        gpointer user_data);
+
+
+void time_change_manager               (Tab *tab,
+                                        TimeWindow new_time_window);
+
+void current_time_change_manager       (Tab *tab,
+                                        LttTime new_current_time);
+
+gboolean execute_time_requests(MainWindow * mw);
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/computetrace.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/computetrace.c
new file mode 100644 (file)
index 0000000..29f5244
--- /dev/null
@@ -0,0 +1,94 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* This file does not even compile yet. It is a starting point to compute
+   some values in the background. This is why process_trace was split in
+   three. However, process_trace_middle as it is currently is would not work.
+   It needs to reinitialize its trace event positions each time since,
+   in between background calls to process middle, other foreground calls to 
+   process_middle can happen. */
+
+#include <lttvwindow/idleprocesstrace.h>
+
+/* The calling function has checked that the needed information has not
+   been or is not being computed yet, has prepared the trace, and now all
+   that is needed is to queue it for processing.
+
+   CHECK remove the work_queue global variable, have an automatic adjustment
+   of the number of events to process by iteration. */
+
+static gboolean inserted = false;
+
+static GList *work_queue = NULL;
+
+typedef struct _WorkPiece WorkPiece;
+
+struct _WorkPiece {
+  LttvTracesetContext *self;
+  LttTime end;
+  unsigned nb_events;
+  LttvHook f;
+  void *hook_data;
+  unsigned nb_done;
+}
+
+guint lttv_process_traceset_piece(gpointer data)
+{
+  GList *first = g_list_first(work_queue);
+  
+  guint nb_done, nb_asked;
+
+  if(first == NULL) {
+    inserted = false;
+    return false;
+  }
+
+  WorkPiece *work_piece = (WorkPiece *)first->data;
+  nb_asked = work_piece->nb_events - work_piece->nb_done;
+  nb_asked = min(nb_asked, 10000); 
+  nb_done = lttv_process_trace_middle(work_piece->self,work_piece->end,
+      nb_asked);
+  work_piece->nb_done += nb_done;
+  if(nb_done < nb_asked) {
+    lttv_process_trace_end(work_piece->self);
+    work_queue = g_list_delete(work_queue, first);
+  }
+}
+
+
+void lttv_process_traceset_when_idle(LttvTracesetContext *self, LttTime end,
+    unsigned nb_events, LttvHook f, void *hook_data)
+{
+  WorkPiece *work_piece = g_new(WorkPiece);
+  work_piece->self = self;
+  work_piece->end = end;
+  work_piece->nb_events = nb_events;
+  work_piece->f = f;
+  work_piece->hook_data = hook_data;
+  eork_piece->nb_done = 0;
+
+  lttv_process_traceset_begin(self);
+  work_queue = g_list_append(work_queue, work_piece);
+  if(!inserted) g_idle_add(lttv_process_traceset_piece, work_queue);
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.c
new file mode 100644 (file)
index 0000000..ec8b375
--- /dev/null
@@ -0,0 +1,580 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <lttvwindow/gtkmultivpaned.h>
+#include <lttvwindow/mainwindow.h>
+#include <lttvwindow/mainwindow-private.h>
+//#include "gtkintl.h"
+
+static void gtk_multi_vpaned_class_init (GtkMultiVPanedClass    *klass);
+static void gtk_multi_vpaned_init       (GtkMultiVPaned         *multi_vpaned);
+
+
+static void     gtk_multi_vpaned_size_request   (GtkWidget      *widget,
+                                          GtkRequisition *requisition);
+static void     gtk_multi_vpaned_size_allocate  (GtkWidget      *widget,
+                                          GtkAllocation  *allocation);
+
+void gtk_multi_vpaned_scroll_value_changed (GtkAdjustment *adjust, gpointer multi_vpaned);
+
+gboolean gtk_multi_vpaned_destroy(GtkObject       *object,
+                                  gpointer           user_data)
+{
+  GtkMultiVPaned * multi_vpaned = (GtkMultiVPaned * )object;
+  while(multi_vpaned->num_children){
+    gtk_multi_vpaned_widget_delete(multi_vpaned);
+  }    
+  return FALSE;
+}
+
+GType
+gtk_multi_vpaned_get_type (void)
+{
+  static GType multi_vpaned_type = 0;
+
+  if (!multi_vpaned_type)
+    {
+      static const GTypeInfo multi_vpaned_info =
+      {
+       sizeof (GtkMultiVPanedClass),
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_multi_vpaned_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkMultiVPaned),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_multi_vpaned_init,
+       NULL,           /* value_table */
+      };
+
+      multi_vpaned_type = g_type_register_static (GTK_TYPE_PANED, "GtkMultiVPaned", 
+                                        &multi_vpaned_info, 0);
+    }
+
+  return multi_vpaned_type;
+}
+
+static void
+gtk_multi_vpaned_class_init (GtkMultiVPanedClass *class)
+{
+  GtkWidgetClass *widget_class;
+  
+  widget_class = (GtkWidgetClass *) class;
+
+  widget_class->size_request = gtk_multi_vpaned_size_request;
+  widget_class->size_allocate = gtk_multi_vpaned_size_allocate;
+}
+
+static void
+gtk_multi_vpaned_init (GtkMultiVPaned * multi_vpaned)
+{
+  GtkWidget * button;
+
+  GTK_WIDGET_SET_FLAGS (multi_vpaned, GTK_NO_WINDOW);
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (multi_vpaned), FALSE);
+  
+  multi_vpaned->first_pane    = NULL;
+  multi_vpaned->last_pane     = NULL;
+  multi_vpaned->focused_pane  = NULL;
+  multi_vpaned->iter          = NULL;
+  multi_vpaned->num_children  = 0;
+
+  multi_vpaned->vbox         = NULL;
+  //  multi_vpaned->scrollWindow = NULL;
+  //  multi_vpaned->viewport     = NULL;
+  multi_vpaned->hscrollbar   = NULL;
+}
+
+
+GtkWidget* gtk_multi_vpaned_new ()
+{
+  GtkWidget * widget = GTK_WIDGET (g_object_new (gtk_multi_vpaned_get_type (), NULL));
+  g_signal_connect(G_OBJECT(widget), "destroy",
+                  G_CALLBACK(gtk_multi_vpaned_destroy),NULL);
+  
+  return widget;
+}
+
+GtkWidget * gtk_multi_vpaned_get_widget(GtkMultiVPaned * multi_vpaned)
+{
+  if(multi_vpaned->focused_pane == NULL)return NULL;
+  return (GtkWidget*)multi_vpaned->focused_pane->child2;
+}
+
+GtkWidget * gtk_multi_vpaned_get_first_widget(GtkMultiVPaned * multi_vpaned)
+{
+  if(multi_vpaned->first_pane == NULL)return NULL;
+  multi_vpaned->iter = multi_vpaned->first_pane;
+  return multi_vpaned->first_pane->child2;
+}
+
+GtkWidget * gtk_multi_vpaned_get_next_widget(GtkMultiVPaned * multi_vpaned)
+{
+  if(multi_vpaned->iter != multi_vpaned->last_pane){
+    multi_vpaned->iter = (GtkPaned *)multi_vpaned->iter->child1;
+    return multi_vpaned->iter->child2;
+  }else {
+    return NULL;
+  }
+}
+
+void gtk_multi_vpaned_set_data(GtkMultiVPaned * multi_vpaned,char * key, gpointer value)
+{
+  g_object_set_data(G_OBJECT(multi_vpaned->focused_pane), key, value);    
+}
+
+gpointer gtk_multi_vpaned_get_data(GtkMultiVPaned * multi_vpaned,char * key)
+{
+  if(multi_vpaned->focused_pane == NULL)return NULL;
+  return g_object_get_data(G_OBJECT(multi_vpaned->focused_pane), key);
+}
+
+void gtk_multi_vpaned_set_focus (GtkWidget * widget, GtkPaned* paned)
+{
+  GtkMultiVPaned * multi_vpaned = GTK_MULTI_VPANED(widget);
+  GtkPaned * pane;
+  if(!multi_vpaned->first_pane) return;
+  
+
+  pane = multi_vpaned->first_pane;
+  while(1){
+    if((GtkWidget*)pane == GTK_WIDGET(paned)){
+      multi_vpaned->focused_pane = pane;
+      break;
+    }
+    if(pane == multi_vpaned->last_pane){
+      multi_vpaned->focused_pane = NULL;
+      break;
+    }
+    pane = (GtkPaned*)pane->child1;
+  }
+}
+
+void gtk_multi_vpaned_set_adjust(GtkMultiVPaned * multi_vpaned, const TimeWindow *time_window, gboolean first_time)
+{
+  TimeInterval *time_span;
+  double len, start;
+  Tab *tab = (Tab *)g_object_get_data(G_OBJECT(multi_vpaned), "Tab_Info");
+  LttvTracesetContext *tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+
+  
+  if(first_time){
+    time_span = &tsc->time_span ;
+  
+    multi_vpaned->hadjust->lower = ltt_time_to_double(time_span->start_time) * 
+                             NANOSECONDS_PER_SECOND;
+    multi_vpaned->hadjust->value = multi_vpaned->hadjust->lower;
+    multi_vpaned->hadjust->upper = ltt_time_to_double(time_span->end_time) *
+                             NANOSECONDS_PER_SECOND;
+  }
+
+  /* Page increment of whole visible area */
+  if(multi_vpaned->hadjust == NULL){
+    g_warning("Insert a viewer first");
+    return;
+  }
+
+  start = ltt_time_to_double(time_window->start_time) * NANOSECONDS_PER_SECOND;
+  len = multi_vpaned->hadjust->upper - multi_vpaned->hadjust->lower;
+
+  multi_vpaned->hadjust->page_increment = ltt_time_to_double(
+                       time_window->time_width) * NANOSECONDS_PER_SECOND;
+
+  //if(multi_vpaned->hadjust->page_increment >= len )
+  //  multi_vpaned->hadjust->value = multi_vpaned->hadjust->lower;
+  //if(start + multi_vpaned->hadjust->page_increment >= multi_vpaned->hadjust->upper )
+  //  multi_vpaned->hadjust->value = start;
+  multi_vpaned->hadjust->value = start;
+
+  /* page_size to the whole visible area will take care that the
+     * scroll value + the shown area will never be more than what is
+     * in the trace. */
+  multi_vpaned->hadjust->page_size = multi_vpaned->hadjust->page_increment;
+  multi_vpaned->hadjust->step_increment = multi_vpaned->hadjust->page_increment / 10;
+
+  gtk_adjustment_changed (multi_vpaned->hadjust);
+
+}
+
+void gtk_multi_vpaned_widget_add(GtkMultiVPaned * multi_vpaned, GtkWidget * widget1)
+{
+  GtkPaned * tmpPane; 
+  GtkWidget * w;
+  Tab *tab = (Tab *)g_object_get_data(G_OBJECT(multi_vpaned), "Tab_Info");
+  
+  g_return_if_fail(GTK_IS_MULTI_VPANED(multi_vpaned));
+  g_object_ref(G_OBJECT(widget1));
+
+  if(!multi_vpaned->first_pane){
+    multi_vpaned->first_pane = (GtkPaned *)gtk_vpaned_new();
+    multi_vpaned->last_pane = multi_vpaned->first_pane;
+
+    multi_vpaned->hscrollbar = gtk_hscrollbar_new (NULL);
+    gtk_widget_show(multi_vpaned->hscrollbar);
+
+    multi_vpaned->hadjust = gtk_range_get_adjustment(GTK_RANGE(multi_vpaned->hscrollbar));
+    gtk_multi_vpaned_set_adjust(multi_vpaned, &tab->time_window, TRUE);
+
+    gtk_range_set_update_policy (GTK_RANGE(multi_vpaned->hscrollbar),
+                                                                                                                                GTK_UPDATE_CONTINUOUS);
+                                                                                                                                //changed by Mathieu Desnoyers, was :
+                                 // GTK_UPDATE_DISCONTINUOUS);
+    g_signal_connect(G_OBJECT(multi_vpaned->hadjust), "value-changed",
+                    G_CALLBACK(gtk_multi_vpaned_scroll_value_changed), multi_vpaned);
+    g_signal_connect(G_OBJECT(multi_vpaned->hadjust), "changed",
+                    G_CALLBACK(gtk_multi_vpaned_scroll_value_changed), multi_vpaned);
+
+
+    multi_vpaned->vbox = gtk_vbox_new(FALSE,0);
+    gtk_widget_show(multi_vpaned->vbox);
+    
+    //    multi_vpaned->viewport = gtk_viewport_new (NULL,NULL);
+    //    gtk_widget_show(multi_vpaned->viewport);
+    
+    //    gtk_container_add(GTK_CONTAINER(multi_vpaned->viewport), (GtkWidget*)multi_vpaned->vbox);
+    gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->hscrollbar,FALSE,FALSE,0);
+    gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->first_pane,TRUE,TRUE,0);
+    
+    //    multi_vpaned->scrollWindow = gtk_scrolled_window_new (NULL, NULL);
+    //    gtk_widget_show(multi_vpaned->scrollWindow);
+    //    gtk_container_add (GTK_CONTAINER (multi_vpaned->scrollWindow), (GtkWidget*)multi_vpaned->viewport);    
+    //    gtk_paned_pack1(GTK_PANED(multi_vpaned), (GtkWidget*)multi_vpaned->scrollWindow,FALSE, TRUE);
+
+    gtk_paned_pack1(GTK_PANED(multi_vpaned), (GtkWidget*)multi_vpaned->vbox,FALSE, TRUE);
+  }else{
+    tmpPane = multi_vpaned->last_pane;
+    multi_vpaned->last_pane = (GtkPaned *)gtk_vpaned_new();
+    gtk_paned_pack1 (tmpPane,(GtkWidget*)multi_vpaned->last_pane, FALSE,TRUE);
+  }
+  gtk_widget_show((GtkWidget *)multi_vpaned->last_pane);  
+
+  gtk_paned_pack2 (multi_vpaned->last_pane,widget1, TRUE, TRUE);      
+  multi_vpaned->focused_pane = multi_vpaned->last_pane;
+  multi_vpaned->num_children++;
+  
+}
+
+void gtk_multi_vpaned_widget_delete(GtkMultiVPaned * multi_vpaned)
+{
+  GtkPaned * tmp, *prev, *next;
+  GtkWidget *widget;
+
+  if(!multi_vpaned->focused_pane) return;
+  widget = GTK_WIDGET(multi_vpaned->focused_pane->child2); //widget in vpaned
+  g_object_unref(G_OBJECT(widget));
+
+  if(multi_vpaned->focused_pane == multi_vpaned->first_pane &&
+     multi_vpaned->focused_pane == multi_vpaned->last_pane){
+    //    gtk_container_remove(GTK_CONTAINER(multi_vpaned),(GtkWidget*)multi_vpaned->scrollWindow);
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned),(GtkWidget*)multi_vpaned->vbox);
+    multi_vpaned->first_pane = NULL;
+    multi_vpaned->last_pane = NULL;
+    multi_vpaned->focused_pane = NULL;
+  }else if(multi_vpaned->focused_pane == multi_vpaned->first_pane &&
+          multi_vpaned->focused_pane != multi_vpaned->last_pane){
+    next = (GtkPaned*)multi_vpaned->first_pane->child1;
+    g_object_ref(G_OBJECT(next));
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->first_pane),(GtkWidget*)next);
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->first_pane);
+    multi_vpaned->first_pane = next;
+    gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->first_pane,TRUE,TRUE,0);
+    multi_vpaned->focused_pane = multi_vpaned->first_pane;
+    g_object_unref(G_OBJECT(next));
+  }else if(multi_vpaned->focused_pane != multi_vpaned->first_pane &&
+          multi_vpaned->focused_pane == multi_vpaned->last_pane){
+    tmp = multi_vpaned->last_pane;
+    multi_vpaned->last_pane = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)multi_vpaned->last_pane);
+    multi_vpaned->focused_pane = multi_vpaned->last_pane;
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->last_pane),(GtkWidget*)tmp);
+  }else{
+    tmp = multi_vpaned->focused_pane;
+    prev = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)tmp);
+    next = (GtkPaned*)tmp->child1;
+    g_object_ref(G_OBJECT(next));
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->focused_pane),(GtkWidget*)next);
+    gtk_container_remove(GTK_CONTAINER(prev),(GtkWidget*)multi_vpaned->focused_pane);
+    gtk_paned_pack1(prev, (GtkWidget*)next, FALSE, TRUE);
+    multi_vpaned->focused_pane = next;
+    g_object_unref(G_OBJECT(next));
+  }
+
+  multi_vpaned->num_children--;
+}
+
+
+void gtk_multi_vpaned_widget_move_up(GtkMultiVPaned * multi_vpaned)
+{
+  GtkWidget* upWidget, *downWidget;
+  GtkPaned * prev,*next, *prevPrev;
+
+  if(multi_vpaned->last_pane == multi_vpaned->focused_pane) return;
+
+  // move VPane
+  prev = (GtkPaned*)multi_vpaned->focused_pane->child1;
+  g_object_ref(G_OBJECT(prev));
+  gtk_container_remove(GTK_CONTAINER(multi_vpaned->focused_pane),(GtkWidget*)prev);
+
+  if(prev == multi_vpaned->last_pane){
+    prevPrev = NULL;
+    multi_vpaned->last_pane = multi_vpaned->focused_pane;
+  }else{    
+    prevPrev = (GtkPaned*)prev->child1;
+    g_object_ref(G_OBJECT(prevPrev));
+    gtk_container_remove(GTK_CONTAINER(prev),(GtkWidget*)prevPrev);   
+  }
+
+  g_object_ref(G_OBJECT(multi_vpaned->focused_pane));
+  if(multi_vpaned->first_pane == multi_vpaned->focused_pane){
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->focused_pane);
+    gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)prev,TRUE,TRUE,0);
+    multi_vpaned->first_pane = prev;
+  }else{
+    next = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)multi_vpaned->focused_pane);
+    gtk_container_remove(GTK_CONTAINER(next),(GtkWidget*)multi_vpaned->focused_pane);
+    gtk_paned_pack1(GTK_PANED(next), (GtkWidget*)prev, FALSE,TRUE);
+  }
+  gtk_paned_pack1(GTK_PANED(prev),(GtkWidget*)multi_vpaned->focused_pane, FALSE,TRUE);
+  if(prevPrev)
+    gtk_paned_pack1(GTK_PANED(multi_vpaned->focused_pane),(GtkWidget*)prevPrev, FALSE,TRUE);
+
+  g_object_unref(G_OBJECT(prev));
+  if(prevPrev) g_object_unref(G_OBJECT(prevPrev));
+  g_object_unref(G_OBJECT(multi_vpaned->focused_pane));
+}
+
+
+void gtk_multi_vpaned_widget_move_down(GtkMultiVPaned * multi_vpaned)
+{
+  GtkWidget* upWidget, *downWidget;
+  GtkPaned * prev,*next, *nextNext;
+
+  if(multi_vpaned->first_pane == multi_vpaned->focused_pane) return;
+
+  //move VPane
+  next = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)multi_vpaned->focused_pane);
+  g_object_ref(G_OBJECT(next));
+
+  if(multi_vpaned->last_pane == multi_vpaned->focused_pane){
+    prev = NULL;
+    multi_vpaned->last_pane = next;
+  }else{
+    prev = (GtkPaned*)multi_vpaned->focused_pane->child1;
+    g_object_ref(G_OBJECT(prev));
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->focused_pane),(GtkWidget*)prev);    
+  }
+
+  g_object_ref(G_OBJECT(multi_vpaned->focused_pane));
+  gtk_container_remove(GTK_CONTAINER(next),(GtkWidget*)multi_vpaned->focused_pane);
+  
+  if(next == multi_vpaned->first_pane){
+    multi_vpaned->first_pane = multi_vpaned->focused_pane;
+    gtk_container_remove(GTK_CONTAINER(multi_vpaned->vbox),(GtkWidget*)next);       
+    gtk_box_pack_end(GTK_BOX(multi_vpaned->vbox),(GtkWidget*)multi_vpaned->focused_pane,TRUE,TRUE,0);
+  }else{    
+    nextNext = (GtkPaned*)gtk_widget_get_parent((GtkWidget*)next);
+    gtk_container_remove(GTK_CONTAINER(nextNext),(GtkWidget*)next);       
+    gtk_paned_pack1(nextNext, (GtkWidget*)multi_vpaned->focused_pane, FALSE, TRUE);
+  }
+  gtk_paned_pack1(multi_vpaned->focused_pane,(GtkWidget*)next, FALSE,TRUE);
+  if(prev)
+    gtk_paned_pack1(next,(GtkWidget*)prev, FALSE,TRUE);
+
+  if(prev)g_object_unref(G_OBJECT(prev));
+  g_object_unref(G_OBJECT(next));
+  g_object_unref(G_OBJECT(multi_vpaned->focused_pane));
+}
+
+void gtk_multi_vpaned_set_scroll_value(GtkMultiVPaned * multi_vpaned, double value)
+{
+  gtk_adjustment_set_value(multi_vpaned->hadjust, value);
+  //g_signal_stop_emission_by_name(G_OBJECT(multi_vpaned->hscrollbar), "value-changed");  
+}
+
+void gtk_multi_vpaned_scroll_value_changed(GtkAdjustment *adjust, gpointer multi_vpaned_arg)
+{
+  TimeWindow time_window;
+  TimeInterval *time_span;
+  LttTime time;
+  GtkMultiVPaned * multi_vpaned = (GtkMultiVPaned*)multi_vpaned_arg;
+  gdouble value = gtk_adjustment_get_value(adjust);
+  gdouble upper, lower, ratio;
+  Tab *tab = (Tab *)g_object_get_data(G_OBJECT(multi_vpaned), "Tab_Info");
+  LttvTracesetContext * tsc = 
+    LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+
+  time_window = tab->time_window;
+
+  time_span = &tsc->time_span ;
+  lower = multi_vpaned->hadjust->lower;
+  upper = multi_vpaned->hadjust->upper;
+  ratio = (value - lower) / (upper - lower);
+  
+  time = ltt_time_sub(time_span->end_time, time_span->start_time);
+  time = ltt_time_mul(time, (float)ratio);
+  time = ltt_time_add(time_span->start_time, time);
+
+  time_window.start_time = time;
+
+  time = ltt_time_sub(time_span->end_time, time);
+  if(ltt_time_compare(time,time_window.time_width) < 0){
+    time_window.time_width = time;
+  }
+  set_time_window(tab, &time_window);
+}
+
+
+static void
+gtk_multi_vpaned_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkPaned *paned = GTK_PANED (widget);
+  GtkRequisition child_requisition;
+
+  requisition->width = 0;
+  requisition->height = 0;
+
+  if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+    {
+      gtk_widget_size_request (paned->child1, &child_requisition);
+
+      requisition->height = child_requisition.height;
+      requisition->width = child_requisition.width;
+    }
+
+  if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+    {
+      gtk_widget_size_request (paned->child2, &child_requisition);
+
+      requisition->width = MAX (requisition->width, child_requisition.width);
+      requisition->height += child_requisition.height;
+    }
+
+  requisition->height += GTK_CONTAINER (paned)->border_width * 2;
+  requisition->width += GTK_CONTAINER (paned)->border_width * 2;
+  
+  if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1) &&
+      paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+    {
+      gint handle_size;
+
+      gtk_widget_style_get (widget, "handle_size", &handle_size, NULL);
+      requisition->height += handle_size;
+    }
+
+}
+
+static void
+gtk_multi_vpaned_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkPaned *paned = GTK_PANED (widget);
+  gint border_width = GTK_CONTAINER (paned)->border_width;
+
+  widget->allocation = *allocation;
+
+  if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1) &&
+      paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+    {
+      GtkRequisition child1_requisition;
+      GtkRequisition child2_requisition;
+      GtkAllocation child1_allocation;
+      GtkAllocation child2_allocation;
+      gint handle_size;
+      
+      gtk_widget_style_get (widget, "handle_size", &handle_size, NULL);
+
+      gtk_widget_get_child_requisition (paned->child1, &child1_requisition);
+      gtk_widget_get_child_requisition (paned->child2, &child2_requisition);
+    
+      gtk_paned_compute_position (paned,
+                                 MAX (1, widget->allocation.height
+                                      - handle_size
+                                      - 2 * border_width),
+                                 child1_requisition.height,
+                                 child2_requisition.height);
+
+      paned->handle_pos.x = widget->allocation.x + border_width;
+      paned->handle_pos.y = widget->allocation.y + paned->child1_size + border_width;
+      paned->handle_pos.width = MAX (1, (gint) widget->allocation.width - 2 * border_width);
+      paned->handle_pos.height = handle_size;
+      
+      if (GTK_WIDGET_REALIZED (widget))
+       {
+         if (GTK_WIDGET_MAPPED (widget))
+           gdk_window_show (paned->handle);
+         gdk_window_move_resize (paned->handle,
+                                 paned->handle_pos.x,
+                                 paned->handle_pos.y,
+                                 paned->handle_pos.width,
+                                 handle_size);
+       }
+
+      child1_allocation.width = child2_allocation.width = MAX (1, (gint) allocation->width - border_width * 2);
+      child1_allocation.height = MAX (1, paned->child1_size);
+      child1_allocation.x = child2_allocation.x = widget->allocation.x + border_width;
+      child1_allocation.y = widget->allocation.y + border_width;
+      
+      child2_allocation.y = child1_allocation.y + paned->child1_size + paned->handle_pos.height;
+      child2_allocation.height = MAX (1, widget->allocation.y + widget->allocation.height - child2_allocation.y - border_width);
+      
+      if (GTK_WIDGET_MAPPED (widget) &&
+         paned->child1->allocation.height < child1_allocation.height)
+       {
+         gtk_widget_size_allocate (paned->child2, &child2_allocation);
+         gtk_widget_size_allocate (paned->child1, &child1_allocation);
+       }
+      else
+       {
+         gtk_widget_size_allocate (paned->child1, &child1_allocation);
+         gtk_widget_size_allocate (paned->child2, &child2_allocation);
+       }
+    }
+  else
+    {
+      GtkAllocation child_allocation;
+
+      if (GTK_WIDGET_REALIZED (widget))      
+       gdk_window_hide (paned->handle);
+
+      if (paned->child1)
+       gtk_widget_set_child_visible (paned->child1, TRUE);
+      if (paned->child2)
+       gtk_widget_set_child_visible (paned->child2, TRUE);
+
+      child_allocation.x = widget->allocation.x + border_width;
+      child_allocation.y = widget->allocation.y + border_width;
+      child_allocation.width = MAX (1, allocation->width - 2 * border_width);
+      child_allocation.height = MAX (1, allocation->height - 2 * border_width);
+      
+      if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+       gtk_widget_size_allocate (paned->child1, &child_allocation);
+      else if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+       gtk_widget_size_allocate (paned->child2, &child_allocation);
+    }
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/gtkmultivpaned.h
new file mode 100644 (file)
index 0000000..9d6a49f
--- /dev/null
@@ -0,0 +1,90 @@
+
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_MULTI_VPANED_H__
+#define __GTK_MULTI_VPANED_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+#include <lttvwindow/mainwindow.h> // for TimeWindow
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TYPE_MULTI_VPANED            (gtk_multi_vpaned_get_type ())
+#define GTK_MULTI_VPANED(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MULTI_VPANED, GtkMultiVPaned))
+#define GTK_MULTI_VPANED_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MULTI_VPANED, GtkMultiVPanedClass))
+#define GTK_IS_MULTI_VPANED(obj   )      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MULTI_VPANED))
+#define GTK_IS_MULTI_VPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MULTI_VPANED))
+#define GTK_MULTI_VPANED_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MULTI_VPANED, GtkMultiVPanedClass))
+
+typedef struct _GtkMultiVPaned  GtkMultiVPaned;
+typedef struct _GtkMultiVPanedClass   GtkMultiVPanedClass;
+
+struct _GtkMultiVPaned
+{
+  GtkPaned container;
+
+  /*< public >*/
+  GtkPaned * first_pane;
+  GtkPaned * last_pane;
+  GtkPaned * focused_pane;
+  GtkPaned * iter;
+  guint num_children;
+
+  GtkWidget * vbox;
+  //  GtkWidget * scrollWindow;
+  //  GtkWidget * viewport;
+  GtkWidget * hscrollbar;  
+  GtkAdjustment *hadjust;
+};
+
+struct _GtkMultiVPanedClass
+{
+  GtkPanedClass parent_class;
+};
+
+
+GType     gtk_multi_vpaned_get_type (void) G_GNUC_CONST;
+GtkWidget* gtk_multi_vpaned_new (void);
+
+void gtk_multi_vpaned_set_focus (GtkWidget * widget, GtkPaned *Paned);     
+void gtk_multi_vpaned_widget_add(GtkMultiVPaned * multi_vpaned, GtkWidget * widget1);
+void gtk_multi_vpaned_widget_delete(GtkMultiVPaned * multi_vpaned);
+void gtk_multi_vpaned_widget_move_up(GtkMultiVPaned * multi_vpaned);
+void gtk_multi_vpaned_widget_move_down(GtkMultiVPaned * multi_vpaned);
+void gtk_multi_vpaned_set_adjust(GtkMultiVPaned * multi_vpaned, const TimeWindow * time_window, gboolean first_time);
+void gtk_multi_vpaned_set_data(GtkMultiVPaned * multi_vpaned, char * key, gpointer value);
+gpointer gtk_multi_vpaned_get_data(GtkMultiVPaned * multi_vpaned, char * key);
+GtkWidget * gtk_multi_vpaned_get_widget(GtkMultiVPaned * multi_vpaned);
+GtkWidget * gtk_multi_vpaned_get_first_widget(GtkMultiVPaned * multi_vpaned);
+GtkWidget * gtk_multi_vpaned_get_next_widget(GtkMultiVPaned * multi_vpaned);
+void gtk_multi_vpaned_set_scroll_value(GtkMultiVPaned * multi_vpaned, double value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MULTI_VPANED_H__ */
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c
new file mode 100644 (file)
index 0000000..1ca5cf0
--- /dev/null
@@ -0,0 +1,263 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Mathieu Desnoyers and XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*
+ * Initial main.c file generated by Glade. Edit as required.
+ * Glade will not overwrite this file.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include <lttv/lttv.h>
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+#include <lttv/option.h>
+#include <lttv/module.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/stats.h>
+#include <lttvwindow/menu.h>
+#include <lttvwindow/toolbar.h>
+#include <lttvwindow/lttvwindowtraces.h>
+
+#include "interface.h"
+#include "support.h"
+#include <lttvwindow/mainwindow.h>
+#include <lttvwindow/mainwindow-private.h>
+#include "callbacks.h"
+#include <ltt/trace.h>
+
+
+LttvTraceInfo LTTV_TRACES,
+       LTTV_COMPUTATION,
+       LTTV_VIEWER_CONSTRUCTORS,
+       LTTV_REQUESTS_QUEUE,
+       LTTV_REQUESTS_CURRENT,
+       LTTV_NOTIFY_QUEUE,
+       LTTV_NOTIFY_CURRENT,
+       LTTV_COMPUTATION_TRACESET,
+       LTTV_COMPUTATION_TRACESET_CONTEXT,
+       LTTV_COMPUTATION_SYNC_POSITION,
+       LTTV_BEFORE_CHUNK_TRACESET,
+       LTTV_BEFORE_CHUNK_TRACE,
+       LTTV_BEFORE_CHUNK_TRACEFILE,
+       LTTV_AFTER_CHUNK_TRACESET,
+       LTTV_AFTER_CHUNK_TRACE,
+       LTTV_AFTER_CHUNK_TRACEFILE,
+       LTTV_BEFORE_REQUEST,
+       LTTV_AFTER_REQUEST,
+       LTTV_EVENT_HOOK,
+       LTTV_EVENT_HOOK_BY_ID,
+       LTTV_HOOK_ADDER,
+       LTTV_HOOK_REMOVER,
+       LTTV_IN_PROGRESS,
+       LTTV_READY,
+       LTTV_LOCK;
+
+
+/** Array containing instanced objects. */
+GSList * g_main_window_list = NULL ;
+
+LttvHooks
+  *main_hooks;
+
+/* Initial trace from command line */
+//LttvTrace *g_init_trace = NULL;
+
+static char *a_trace;
+static char g_init_trace[PATH_MAX] = "";
+
+
+void lttv_trace_option(void *hook_data)
+{ 
+  LttTrace *trace;
+
+  get_absolute_pathname(a_trace, g_init_trace);
+}
+
+/*****************************************************************************
+ *                 Functions for module loading/unloading                    *
+ *****************************************************************************/
+/**
+ * plugin's init function
+ *
+ * This function initializes the GUI.
+ */
+
+static gboolean window_creation_hook(void *hook_data, void *call_data)
+{
+  g_debug("GUI window_creation_hook()");
+#ifdef ENABLE_NLS
+  bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  textdomain (GETTEXT_PACKAGE);
+#endif
+
+  gtk_set_locale ();
+  gtk_init (&lttv_argc, &lttv_argv);
+
+  add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
+  add_pixmap_directory ("pixmaps");
+  add_pixmap_directory ("../modules/gui/main/pixmaps");
+
+  /* First window, use command line trace */
+  if(strcmp(g_init_trace, "") != 0){
+    create_main_window_with_trace(g_init_trace);
+  } else {
+    construct_main_window(NULL);
+  }
+
+  gtk_main ();
+
+  return FALSE;
+}
+
+static void init() {
+
+  LttvAttributeValue value;
+  // Global attributes only used for interaction with main() here.
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+  
+  LTTV_TRACES = g_quark_from_string("traces");
+  LTTV_COMPUTATION = g_quark_from_string("computation");
+  LTTV_VIEWER_CONSTRUCTORS = g_quark_from_string("viewer_constructors");
+  LTTV_REQUESTS_QUEUE = g_quark_from_string("requests_queue");
+  LTTV_REQUESTS_CURRENT = g_quark_from_string("requests_current");
+  LTTV_NOTIFY_QUEUE = g_quark_from_string("notify_queue");
+  LTTV_NOTIFY_CURRENT = g_quark_from_string("notify_current");
+  LTTV_COMPUTATION_TRACESET = g_quark_from_string("computation_traceset");
+  LTTV_COMPUTATION_TRACESET_CONTEXT =
+                        g_quark_from_string("computation_traceset_context");
+  LTTV_COMPUTATION_SYNC_POSITION =
+                        g_quark_from_string("computation_sync_position");
+  LTTV_BEFORE_CHUNK_TRACESET = g_quark_from_string("before_chunk_traceset");
+  LTTV_BEFORE_CHUNK_TRACE = g_quark_from_string("before_chunk_trace");
+  LTTV_BEFORE_CHUNK_TRACEFILE = g_quark_from_string("before_chunk_tracefile");
+  LTTV_AFTER_CHUNK_TRACESET = g_quark_from_string("after_chunk_traceset");
+  LTTV_AFTER_CHUNK_TRACE = g_quark_from_string("after_chunk_trace");
+  LTTV_AFTER_CHUNK_TRACEFILE = g_quark_from_string("after_chunk_tracefile");
+  LTTV_BEFORE_REQUEST = g_quark_from_string("before_request");
+  LTTV_AFTER_REQUEST = g_quark_from_string("after_request");
+  LTTV_EVENT_HOOK = g_quark_from_string("event_hook");
+  LTTV_EVENT_HOOK_BY_ID = g_quark_from_string("event_hook_by_id");
+  LTTV_HOOK_ADDER = g_quark_from_string("hook_adder");
+  LTTV_HOOK_REMOVER = g_quark_from_string("hook_remover");
+  LTTV_IN_PROGRESS = g_quark_from_string("in_progress");
+  LTTV_READY = g_quark_from_string("ready");
+  LTTV_LOCK = g_quark_from_string("lock");
+
+  g_debug("GUI init()");
+
+  lttv_option_add("trace", 't', 
+      "add a trace to the trace set to analyse", 
+      "pathname of the directory containing the trace", 
+      LTTV_OPT_STRING, &a_trace, lttv_trace_option, NULL);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before",
+      LTTV_POINTER, &value));
+  g_assert((main_hooks = *(value.v_pointer)) != NULL);
+
+  lttv_hooks_add(main_hooks, window_creation_hook, NULL, LTTV_PRIO_DEFAULT);
+
+  {
+    /* Register state calculator */
+    LttvHooks *hook_adder = lttv_hooks_new();
+    lttv_hooks_add(hook_adder, lttv_state_save_hook_add_event_hooks, NULL,
+                   LTTV_PRIO_DEFAULT);
+    lttv_hooks_add(hook_adder, lttv_state_hook_add_event_hooks, NULL,
+                   LTTV_PRIO_DEFAULT);
+    LttvHooks *hook_remover = lttv_hooks_new();
+    lttv_hooks_add(hook_remover, lttv_state_save_hook_remove_event_hooks,
+                                    NULL, LTTV_PRIO_DEFAULT);
+    lttv_hooks_add(hook_remover, lttv_state_hook_remove_event_hooks,
+                                    NULL, LTTV_PRIO_DEFAULT);
+    /* Add state computation background hook adder to attributes */
+    lttvwindowtraces_register_computation_hooks(g_quark_from_string("state"),
+        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+        hook_adder, hook_remover);
+  }
+
+  {
+    /* Register statistics calculator */
+    LttvHooks *hook_adder = lttv_hooks_new();
+    lttv_hooks_add(hook_adder, lttv_stats_hook_add_event_hooks, NULL,
+                   LTTV_PRIO_DEFAULT);
+    lttv_hooks_add(hook_adder, lttv_state_hook_add_event_hooks, NULL,
+                   LTTV_PRIO_DEFAULT);
+    LttvHooks *hook_remover = lttv_hooks_new();
+    lttv_hooks_add(hook_remover, lttv_stats_hook_remove_event_hooks,
+                                    NULL, LTTV_PRIO_DEFAULT);
+    lttv_hooks_add(hook_remover, lttv_state_hook_remove_event_hooks,
+                                    NULL, LTTV_PRIO_DEFAULT);
+    LttvHooks *after_request = lttv_hooks_new();
+    lttv_hooks_add(after_request, lttv_stats_sum_traceset_hook, NULL,
+        LTTV_PRIO_DEFAULT);
+    /* Add state computation background hook adder to attributes */
+    lttvwindowtraces_register_computation_hooks(g_quark_from_string("stats"),
+        NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+        after_request, NULL, NULL,
+        hook_adder, hook_remover);
+  }
+}
+
+void
+main_window_destructor(MainWindow * mw)
+{
+  g_assert(GTK_IS_WIDGET(mw->mwindow));
+  gtk_widget_destroy(mw->mwindow);
+}
+
+static void destroy_walk(gpointer data, gpointer user_data)
+{
+  main_window_destructor((MainWindow*)data);
+}
+
+/**
+ * plugin's destroy function
+ *
+ * This function releases the memory reserved by the module and unregisters
+ * everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+
+  LttvAttributeValue value;  
+  LttvTrace *trace;
+  GSList *iter = NULL;
+  
+  lttv_option_remove("trace");
+
+  lttv_hooks_remove_data(main_hooks, window_creation_hook, NULL);
+
+  g_debug("GUI destroy()");
+
+  g_slist_foreach(g_main_window_list, destroy_walk, NULL);
+  
+  g_slist_free(g_main_window_list);
+  
+}
+
+
+LTTV_MODULE("lttvwindow", "Viewer main window", \
+    "Viewer with multiple windows, tabs and panes for graphical modules", \
+           init, destroy, "stats", "option")
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/interface.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/interface.c
new file mode 100644 (file)
index 0000000..55044a0
--- /dev/null
@@ -0,0 +1,937 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+#define GLADE_HOOKUP_OBJECT(component,widget,name) \
+  g_object_set_data_full (G_OBJECT (component), name, \
+    gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
+
+#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
+  g_object_set_data (G_OBJECT (component), name, widget)
+
+GtkWidget*
+create_MWindow (void)
+{
+  GtkWidget *MWindow;
+  GtkWidget *MVbox;
+  GtkWidget *MMenuBox;
+  GtkWidget *MenuMain;
+  GtkWidget *FileMenuTitle;
+  GtkWidget *FileMenuTitle_menu;
+  GtkWidget *FileMenuNewTitle;
+  GtkWidget *FileMenuNewTitle_menu;
+  //  GtkWidget *EmptyTraceset;
+  GtkWidget *CloneTraceset;
+  GtkWidget *FileMenuNewSep;
+  GtkWidget *Tab;
+  //  GtkWidget *OpenTraceset;
+  GtkWidget *Close;
+  GtkWidget *CloseTab;
+  GtkWidget *FileMenuSeparator1;
+  GtkWidget *AddTrace;
+  GtkWidget *RemoveTrace;
+  //  GtkWidget *Save;
+  //  GtkWidget *SaveAs;
+  GtkWidget *FileMenuSeparator2;
+  GtkWidget *Quit;
+  //  GtkWidget *EditMenuTitle;
+  //  GtkWidget *EditMenuTitle_menu;
+  //  GtkWidget *Cut;
+  //  GtkWidget *Copy;
+  //  GtkWidget *Paste;
+  //  GtkWidget *Delete;
+  GtkWidget *ViewMenuTitle;
+  GtkWidget *ViewMenuTitle_menu;
+  GtkWidget *ZoomIn;
+  GtkWidget *ZoomOut;
+  GtkWidget *ZoomExtended;
+  GtkWidget *ViewMenuSeparator;
+  //  GtkWidget *GoToTime;
+  //  GtkWidget *ShowTimeFrame;
+  GtkWidget *ToolMenuTitle;
+  GtkWidget *ToolMenuTitle_menu;
+  GtkWidget *MoveViewerUp;
+  GtkWidget *MoveViewerDown;
+  GtkWidget *RemoveViewer;
+  GtkWidget *ToolMenuSeparator;
+  GtkWidget *Filter;
+  //  GtkWidget *Facility;
+  GtkWidget *ToolMenuSeparator1;
+  //  GtkWidget *insert_viewer_test;
+  GtkWidget *PluginMenuTitle;
+  GtkWidget *PluginMenuTitle_menu;
+  GtkWidget *LoadLibrary;
+  GtkWidget *UnloadLibrary;
+  GtkWidget *LoadModule;
+  GtkWidget *UnloadModule;
+  GtkWidget *AddLibrarySearchPath;
+  GtkWidget *RemoveLibrarySearchPath;
+  //  GtkWidget *OptionMenuTitle;
+  //  GtkWidget *OptionMenuTitle_menu;
+  //  GtkWidget *Color;
+  //  GtkWidget *OptMenuSeparator;
+  //  GtkWidget *OpenFilter;
+  //  GtkWidget *SaveConfiguration;
+  GtkWidget *MenuHelp;
+  GtkWidget *HelpMenuTitle;
+  GtkWidget *HelpMenu;
+  GtkWidget *Content;
+  GtkWidget *HelpmenuSeparator;
+  GtkWidget *About;
+  GtkWidget *MToolbar1;
+  GtkWidget *tmp_toolbar_icon;
+  GtkWidget *tlbEmptyTraceset;
+  GtkWidget *tlbTab;
+  //  GtkWidget *tlbOpenTraceset;
+  GtkWidget *tlbAddTrace;
+  GtkWidget *tlbRemoveTrace;
+  GtkWidget *tlbRedraw;
+  GtkWidget *tlbContinueProcessing;
+  GtkWidget *tlbStopProcessing;
+  //  GtkWidget *tlbSave;
+  //  GtkWidget *tlbSaveAs;
+  GtkWidget *tlbZoomIn;
+  GtkWidget *tlbZoomOut;
+  GtkWidget *tlbZoomExtended;
+  //GtkWidget *tlbGoToTime;
+  //GtkWidget *tlbShowTimeFrame;
+  GtkWidget *tlbMoveViewerUp;
+  GtkWidget *tlbMoveViewerDown;
+  GtkWidget *tlbRemoveViewer;
+  GtkWidget *MToolbar2;
+  GtkWidget *MNotebook;
+  //  GtkWidget *empty_notebook_page;
+  //  GtkWidget *label1;
+  GtkWidget *MStatusbar;
+  GtkAccelGroup *accel_group;
+
+  accel_group = gtk_accel_group_new ();
+
+  MWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_size_request (MWindow, 100, 50);
+  gtk_window_set_title (GTK_WINDOW (MWindow), "Linux Trace Toolkit Viewer");
+  gtk_window_set_default_size (GTK_WINDOW (MWindow),
+      gdk_screen_width()*0.9, gdk_screen_height()*0.9);
+
+  MVbox = gtk_vbox_new (FALSE, 0);
+  gtk_widget_show (MVbox);
+  gtk_container_add (GTK_CONTAINER (MWindow), MVbox);
+
+  MMenuBox = gtk_hbox_new (FALSE, 0);
+  gtk_widget_show (MMenuBox);
+  gtk_box_pack_start (GTK_BOX (MVbox), MMenuBox, FALSE, FALSE, 0);
+
+  MenuMain = gtk_menu_bar_new ();
+  gtk_widget_show (MenuMain);
+  gtk_box_pack_start (GTK_BOX (MMenuBox), MenuMain, FALSE, FALSE, 0);
+
+  FileMenuTitle = gtk_menu_item_new_with_mnemonic ("_File");
+  gtk_widget_show (FileMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuMain), FileMenuTitle);
+
+  FileMenuTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (FileMenuTitle), FileMenuTitle_menu);
+
+  FileMenuNewTitle = gtk_menu_item_new_with_mnemonic ("New");
+  gtk_widget_show (FileMenuNewTitle);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), FileMenuNewTitle);
+
+  FileMenuNewTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (FileMenuNewTitle), FileMenuNewTitle_menu);
+
+  //  EmptyTraceset = gtk_menu_item_new_with_mnemonic ("Empty trace set");
+  //  gtk_widget_show (EmptyTraceset);
+  //  gtk_container_add (GTK_CONTAINER (FileMenuNewTitle_menu), EmptyTraceset);
+
+  //  CloneTraceset = gtk_menu_item_new_with_mnemonic ("Clone trace set");
+  CloneTraceset = gtk_menu_item_new_with_mnemonic ("New window");
+  gtk_widget_show (CloneTraceset);
+  gtk_container_add (GTK_CONTAINER (FileMenuNewTitle_menu), CloneTraceset);
+
+  FileMenuNewSep = gtk_menu_item_new ();
+  gtk_widget_show (FileMenuNewSep);
+  gtk_container_add (GTK_CONTAINER (FileMenuNewTitle_menu), FileMenuNewSep);
+  gtk_widget_set_sensitive (FileMenuNewSep, FALSE);
+
+  Tab = gtk_menu_item_new_with_mnemonic ("Tab");
+  gtk_widget_show (Tab);
+  gtk_container_add (GTK_CONTAINER (FileMenuNewTitle_menu), Tab);
+/*
+  OpenTraceset = gtk_menu_item_new_with_mnemonic ("Open");
+  gtk_widget_show (OpenTraceset);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), OpenTraceset);
+*/
+  Close = gtk_menu_item_new_with_mnemonic ("Close");
+  gtk_widget_show (Close);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), Close);
+
+  CloseTab = gtk_menu_item_new_with_mnemonic ("Close Tab");
+  gtk_widget_show (CloseTab);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), CloseTab);
+
+  FileMenuSeparator1 = gtk_menu_item_new ();
+  gtk_widget_show (FileMenuSeparator1);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), FileMenuSeparator1);
+  gtk_widget_set_sensitive (FileMenuSeparator1, FALSE);
+
+  AddTrace = gtk_menu_item_new_with_mnemonic ("Add Trace");
+  gtk_widget_show (AddTrace);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), AddTrace);
+
+  RemoveTrace = gtk_menu_item_new_with_mnemonic ("Remove Trace");
+  gtk_widget_show (RemoveTrace);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), RemoveTrace);
+/*
+  Save = gtk_menu_item_new_with_mnemonic ("Save");
+  gtk_widget_show (Save);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), Save);
+
+  SaveAs = gtk_menu_item_new_with_mnemonic ("Save As");
+  gtk_widget_show (SaveAs);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), SaveAs);
+*/
+  FileMenuSeparator2 = gtk_menu_item_new ();
+  gtk_widget_show (FileMenuSeparator2);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), FileMenuSeparator2);
+  gtk_widget_set_sensitive (FileMenuSeparator2, FALSE);
+
+  Quit = gtk_menu_item_new_with_mnemonic ("Quit");
+  gtk_widget_show (Quit);
+  gtk_container_add (GTK_CONTAINER (FileMenuTitle_menu), Quit);
+/*
+  EditMenuTitle = gtk_menu_item_new_with_mnemonic ("_Edit");
+  gtk_widget_show (EditMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuMain), EditMenuTitle);
+
+  EditMenuTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (EditMenuTitle), EditMenuTitle_menu);
+
+  Cut = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group);
+  gtk_widget_show (Cut);
+  gtk_container_add (GTK_CONTAINER (EditMenuTitle_menu), Cut);
+
+  Copy = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group);
+  gtk_widget_show (Copy);
+  gtk_container_add (GTK_CONTAINER (EditMenuTitle_menu), Copy);
+
+  Paste = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group);
+  gtk_widget_show (Paste);
+  gtk_container_add (GTK_CONTAINER (EditMenuTitle_menu), Paste);
+
+  Delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
+  gtk_widget_show (Delete);
+  gtk_container_add (GTK_CONTAINER (EditMenuTitle_menu), Delete);
+*/
+  ViewMenuTitle = gtk_menu_item_new_with_mnemonic ("_View");
+  gtk_widget_show (ViewMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuMain), ViewMenuTitle);
+
+  ViewMenuTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (ViewMenuTitle), ViewMenuTitle_menu);
+
+  ZoomIn = gtk_menu_item_new_with_mnemonic ("Zoom in");
+  gtk_widget_show (ZoomIn);
+  gtk_container_add (GTK_CONTAINER (ViewMenuTitle_menu), ZoomIn);
+
+  ZoomOut = gtk_menu_item_new_with_mnemonic ("Zoom out");
+  gtk_widget_show (ZoomOut);
+  gtk_container_add (GTK_CONTAINER (ViewMenuTitle_menu), ZoomOut);
+
+  ZoomExtended = gtk_menu_item_new_with_mnemonic ("Zoom extended");
+  gtk_widget_show (ZoomExtended);
+  gtk_container_add (GTK_CONTAINER (ViewMenuTitle_menu), ZoomExtended);
+
+  ViewMenuSeparator = gtk_menu_item_new ();
+  gtk_widget_show (ViewMenuSeparator);
+  gtk_container_add (GTK_CONTAINER (ViewMenuTitle_menu), ViewMenuSeparator);
+  gtk_widget_set_sensitive (ViewMenuSeparator, FALSE);
+/*
+  GoToTime = gtk_menu_item_new_with_mnemonic ("Go to time");
+  gtk_widget_show (GoToTime);
+  gtk_container_add (GTK_CONTAINER (ViewMenuTitle_menu), GoToTime);
+
+  ShowTimeFrame = gtk_menu_item_new_with_mnemonic ("Show time frame");
+  gtk_widget_show (ShowTimeFrame);
+  gtk_container_add (GTK_CONTAINER (ViewMenuTitle_menu), ShowTimeFrame);
+*/
+  ToolMenuTitle = gtk_menu_item_new_with_mnemonic ("Tools");
+  gtk_widget_show (ToolMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuMain), ToolMenuTitle);
+
+  ToolMenuTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (ToolMenuTitle), ToolMenuTitle_menu);
+
+  MoveViewerUp = gtk_menu_item_new_with_mnemonic ("Move viewer up");
+  gtk_widget_show (MoveViewerUp);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), MoveViewerUp);
+
+  MoveViewerDown = gtk_menu_item_new_with_mnemonic ("Move viewer down");
+  gtk_widget_show (MoveViewerDown);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), MoveViewerDown);
+
+  RemoveViewer = gtk_menu_item_new_with_mnemonic ("Remove viewer");
+  gtk_widget_show (RemoveViewer);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), RemoveViewer);
+
+  ToolMenuSeparator = gtk_menu_item_new ();
+  gtk_widget_show (ToolMenuSeparator);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), ToolMenuSeparator);
+  gtk_widget_set_sensitive (ToolMenuSeparator, FALSE);
+
+  Filter = gtk_menu_item_new_with_mnemonic ("Trace Filter Selector");
+  gtk_widget_show (Filter);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), Filter);
+
+  //  Facility = gtk_menu_item_new_with_mnemonic ("Facility Selector");
+  //  gtk_widget_show (Facility);
+  //  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), Facility);
+
+  ToolMenuSeparator1 = gtk_menu_item_new ();
+  gtk_widget_show (ToolMenuSeparator1);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), ToolMenuSeparator1);
+  gtk_widget_set_sensitive (ToolMenuSeparator1, FALSE);
+
+  //  insert_viewer_test = gtk_menu_item_new_with_mnemonic ("Insert viewer test");
+  //  gtk_widget_show (insert_viewer_test);
+  //  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), insert_viewer_test);
+
+  PluginMenuTitle = gtk_menu_item_new_with_mnemonic ("Plugins");
+  gtk_widget_show (PluginMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuMain), PluginMenuTitle);
+
+  PluginMenuTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (PluginMenuTitle), PluginMenuTitle_menu);
+
+  LoadLibrary = gtk_menu_item_new_with_mnemonic ("Load library");
+  gtk_widget_show (LoadLibrary);
+  gtk_container_add (GTK_CONTAINER (PluginMenuTitle_menu), LoadLibrary);
+  
+  UnloadLibrary = gtk_menu_item_new_with_mnemonic ("Unload library");
+  gtk_widget_show (UnloadLibrary);
+  gtk_container_add (GTK_CONTAINER (PluginMenuTitle_menu), UnloadLibrary);
+
+  LoadModule = gtk_menu_item_new_with_mnemonic ("Load module");
+  gtk_widget_show (LoadModule);
+  gtk_container_add (GTK_CONTAINER (PluginMenuTitle_menu), LoadModule);
+
+  UnloadModule = gtk_menu_item_new_with_mnemonic ("Unload module");
+  gtk_widget_show (UnloadModule);
+  gtk_container_add (GTK_CONTAINER (PluginMenuTitle_menu), UnloadModule);
+
+  AddLibrarySearchPath = gtk_menu_item_new_with_mnemonic ("Add library search path");
+  gtk_widget_show (AddLibrarySearchPath);
+  gtk_container_add (GTK_CONTAINER (PluginMenuTitle_menu), AddLibrarySearchPath);
+  
+  RemoveLibrarySearchPath = gtk_menu_item_new_with_mnemonic ("Remove library search path");
+  gtk_widget_show (RemoveLibrarySearchPath);
+  gtk_container_add (GTK_CONTAINER (PluginMenuTitle_menu), RemoveLibrarySearchPath);
+/*
+  OptionMenuTitle = gtk_menu_item_new_with_mnemonic ("Options");
+  gtk_widget_show (OptionMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuMain), OptionMenuTitle);
+
+  OptionMenuTitle_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (OptionMenuTitle), OptionMenuTitle_menu);
+
+  Color = gtk_menu_item_new_with_mnemonic ("Color");
+  gtk_widget_show (Color);
+  gtk_container_add (GTK_CONTAINER (OptionMenuTitle_menu), Color);
+
+  OptMenuSeparator = gtk_menu_item_new ();
+  gtk_widget_show (OptMenuSeparator);
+  gtk_container_add (GTK_CONTAINER (OptionMenuTitle_menu), OptMenuSeparator);
+  gtk_widget_set_sensitive (OptMenuSeparator, FALSE);
+
+  OpenFilter = gtk_menu_item_new_with_mnemonic ("Filter");
+  gtk_widget_show (OpenFilter);
+  gtk_container_add (GTK_CONTAINER (OptionMenuTitle_menu), OpenFilter);
+
+  SaveConfiguration = gtk_menu_item_new_with_mnemonic ("Save configuration");
+  gtk_widget_show (SaveConfiguration);
+  gtk_container_add (GTK_CONTAINER (OptionMenuTitle_menu), SaveConfiguration);
+*/
+  MenuHelp = gtk_menu_bar_new ();
+  gtk_widget_show (MenuHelp);
+  gtk_box_pack_end (GTK_BOX (MMenuBox), MenuHelp, FALSE, FALSE, 0);
+
+  HelpMenuTitle = gtk_menu_item_new_with_mnemonic ("_Help");
+  gtk_widget_show (HelpMenuTitle);
+  gtk_container_add (GTK_CONTAINER (MenuHelp), HelpMenuTitle);
+
+  HelpMenu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (HelpMenuTitle), HelpMenu);
+
+  Content = gtk_menu_item_new_with_mnemonic ("Content");
+  gtk_widget_show (Content);
+  gtk_container_add (GTK_CONTAINER (HelpMenu), Content);
+
+  HelpmenuSeparator = gtk_menu_item_new ();
+  gtk_widget_show (HelpmenuSeparator);
+  gtk_container_add (GTK_CONTAINER (HelpMenu), HelpmenuSeparator);
+  gtk_widget_set_sensitive (HelpmenuSeparator, FALSE);
+
+  About = gtk_menu_item_new_with_mnemonic ("About...");
+  gtk_widget_show (About);
+  gtk_container_add (GTK_CONTAINER (HelpMenu), About);
+
+  MToolbar1 = gtk_toolbar_new ();
+  gtk_widget_show (MToolbar1);
+  gtk_box_pack_start (GTK_BOX (MVbox), MToolbar1, FALSE, FALSE, 0);
+  gtk_toolbar_set_style (GTK_TOOLBAR (MToolbar1), GTK_TOOLBAR_ICONS);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "filenew.png");
+  tlbEmptyTraceset = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "New window", NULL,
+                               //"New window with empty trace set", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbEmptyTraceset);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbEmptyTraceset), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "filenew.png");
+  tlbTab = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "New tab", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbTab);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbTab), 1);
+
+/*
+  tmp_toolbar_icon = create_pixmap (MWindow, "fileopen.png");
+  tlbOpenTraceset = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "open a trace set", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbOpenTraceset);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbOpenTraceset), 1);
+*/
+  tmp_toolbar_icon = create_pixmap (MWindow, "edit_add_22.png");
+  tlbAddTrace = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Add a trace ", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbAddTrace);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbAddTrace), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "edit_remove_22.png");
+  tlbRemoveTrace = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Remove a trace", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbRemoveTrace);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbRemoveTrace), 1);
+/*
+  tmp_toolbar_icon = create_pixmap (MWindow, "filesave.png");
+  tlbSave = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "save the current trace set", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbSave);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbSave), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "filesaveas.png");
+  tlbSaveAs = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "save as ", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbSaveAs);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbSaveAs), 1);
+*/
+  gtk_toolbar_append_space (GTK_TOOLBAR (MToolbar1));
+
+  /* Manually added by Mathieu Desnoyers */
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "stock_refresh_24.png");
+  tlbRedraw = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Redraw", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbRedraw);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbRedraw), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "stock_redo_24.png");
+  tlbContinueProcessing = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Continue Processing", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbContinueProcessing);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbContinueProcessing), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "stock_stop_24.png");
+  tlbStopProcessing = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Stop Processing", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbStopProcessing);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbStopProcessing), 1);
+
+
+  gtk_toolbar_append_space (GTK_TOOLBAR (MToolbar1));
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "stock_zoom_in_24.png");
+  tlbZoomIn = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Zoom in", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbZoomIn);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbZoomIn), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "stock_zoom_out_24.png");
+  tlbZoomOut = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Zoom out", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbZoomOut);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbZoomOut), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "stock_zoom_fit_24.png");
+  tlbZoomExtended = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Zoom extended", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbZoomExtended);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbZoomExtended), 1);
+
+  /*
+  tmp_toolbar_icon = create_pixmap (MWindow, "gtk-jump-to.png");
+  tlbGoToTime = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Go to time", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbGoToTime);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbGoToTime), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "mini-display.xpm");
+  tlbShowTimeFrame = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Show time frame", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbShowTimeFrame);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbShowTimeFrame), 1);
+  */
+  gtk_toolbar_append_space (GTK_TOOLBAR (MToolbar1));
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "1uparrow.png");
+  tlbMoveViewerUp = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Move up current viewer", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbMoveViewerUp);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbMoveViewerUp), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "1downarrow.png");
+  tlbMoveViewerDown = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Move down current viewer", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbMoveViewerDown);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbMoveViewerDown), 1);
+
+  tmp_toolbar_icon = create_pixmap (MWindow, "remove.png");
+  tlbRemoveViewer = gtk_toolbar_append_element (GTK_TOOLBAR (MToolbar1),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                "",
+                                "Delete current viewer", NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (MToolbar1)->children)->data))->label), TRUE);
+  gtk_widget_show (tlbRemoveViewer);
+  gtk_container_set_border_width (GTK_CONTAINER (tlbRemoveViewer), 1);
+
+  gtk_toolbar_append_space (GTK_TOOLBAR (MToolbar1));
+
+  //  MToolbar2 = gtk_toolbar_new ();
+  //  gtk_widget_show (MToolbar2);
+  //  gtk_box_pack_start (GTK_BOX (MVbox), MToolbar2, FALSE, FALSE, 0);
+  //  gtk_toolbar_set_style (GTK_TOOLBAR (MToolbar2), GTK_TOOLBAR_ICONS);
+
+  MNotebook = gtk_notebook_new ();
+  gtk_widget_show (MNotebook);
+  gtk_notebook_set_show_tabs((GtkNotebook*)MNotebook, FALSE);
+  gtk_box_pack_start (GTK_BOX (MVbox), MNotebook, TRUE, TRUE, 0);
+
+/*
+  empty_notebook_page = gtk_vbox_new (FALSE, 0);
+  gtk_widget_show (empty_notebook_page);
+  gtk_container_add (GTK_CONTAINER (MNotebook), empty_notebook_page);
+
+  label1 = gtk_label_new ("");
+  gtk_widget_show (label1);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (MNotebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (MNotebook), 0), label1);
+  gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);
+*/
+  MStatusbar = gtk_statusbar_new ();
+  gtk_widget_show (MStatusbar);
+  gtk_box_pack_start (GTK_BOX (MVbox), MStatusbar, FALSE, FALSE, 0);
+
+  g_signal_connect ((gpointer) MWindow, "destroy",
+                    G_CALLBACK (on_MWindow_destroy),
+                    NULL);
+  g_signal_connect ((gpointer) MWindow, "configure-event",
+                    G_CALLBACK (on_MWindow_configure),
+                    NULL);
+                  
+  //  g_signal_connect ((gpointer) EmptyTraceset, "activate",
+  //                    G_CALLBACK (on_empty_traceset_activate),
+  //                    NULL);
+  g_signal_connect ((gpointer) CloneTraceset, "activate",
+                    G_CALLBACK (on_clone_traceset_activate),
+                    NULL);
+  g_signal_connect ((gpointer) Tab, "activate",
+                    G_CALLBACK (on_tab_activate),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) OpenTraceset, "activate",
+                    G_CALLBACK (on_open_activate),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) Close, "activate",
+                    G_CALLBACK (on_close_activate),
+                    NULL);
+  g_signal_connect ((gpointer) CloseTab, "activate",
+                    G_CALLBACK (on_close_tab_activate),
+                    NULL);
+  g_signal_connect ((gpointer) AddTrace, "activate",
+                    G_CALLBACK (on_add_trace_activate),
+                    NULL);
+  g_signal_connect ((gpointer) RemoveTrace, "activate",
+                    G_CALLBACK (on_remove_trace_activate),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) Save, "activate",
+                    G_CALLBACK (on_save_activate),
+                    NULL);
+  g_signal_connect ((gpointer) SaveAs, "activate",
+                    G_CALLBACK (on_save_as_activate),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) Quit, "activate",
+                    G_CALLBACK (on_quit_activate),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) Cut, "activate",
+                    G_CALLBACK (on_cut_activate),
+                    NULL);
+  g_signal_connect ((gpointer) Copy, "activate",
+                    G_CALLBACK (on_copy_activate),
+                    NULL);
+  g_signal_connect ((gpointer) Paste, "activate",
+                    G_CALLBACK (on_paste_activate),
+                    NULL);
+  g_signal_connect ((gpointer) Delete, "activate",
+                    G_CALLBACK (on_delete_activate),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) ZoomIn, "activate",
+                    G_CALLBACK (on_zoom_in_activate),
+                    NULL);
+  g_signal_connect ((gpointer) ZoomOut, "activate",
+                    G_CALLBACK (on_zoom_out_activate),
+                    NULL);
+  g_signal_connect ((gpointer) ZoomExtended, "activate",
+                    G_CALLBACK (on_zoom_extended_activate),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) GoToTime, "activate",
+                   G_CALLBACK (on_go_to_time_activate),
+                   NULL);
+  g_signal_connect ((gpointer) ShowTimeFrame, "activate",
+                    G_CALLBACK (on_show_time_frame_activate),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) MoveViewerUp, "activate",
+                    G_CALLBACK (on_move_viewer_up_activate),
+                    NULL);
+  g_signal_connect ((gpointer) MoveViewerDown, "activate",
+                    G_CALLBACK (on_move_viewer_down_activate),
+                    NULL);
+  g_signal_connect ((gpointer) RemoveViewer, "activate",
+                    G_CALLBACK (on_remove_viewer_activate),
+                    NULL);
+  //g_signal_connect ((gpointer) Filter, "activate",
+  //                  G_CALLBACK (on_trace_filter_activate),
+  //                  NULL);
+  //  g_signal_connect ((gpointer) Facility, "activate",
+  //                    G_CALLBACK (on_trace_facility_activate),
+  //                    NULL);
+  //  g_signal_connect ((gpointer) insert_viewer_test, "activate",
+  //                    G_CALLBACK (on_insert_viewer_test_activate),
+  //                    NULL);
+  g_signal_connect ((gpointer) LoadLibrary, "activate",
+                    G_CALLBACK (on_load_library_activate),
+                    NULL);
+  g_signal_connect ((gpointer) UnloadLibrary, "activate",
+                    G_CALLBACK (on_unload_library_activate),
+                    NULL);
+  g_signal_connect ((gpointer) LoadModule, "activate",
+                    G_CALLBACK (on_load_module_activate),
+                    NULL);
+  g_signal_connect ((gpointer) UnloadModule, "activate",
+                    G_CALLBACK (on_unload_module_activate),
+                    NULL);
+  g_signal_connect ((gpointer) AddLibrarySearchPath, "activate",
+                    G_CALLBACK (on_add_library_search_path_activate),
+                    NULL);
+  g_signal_connect ((gpointer) RemoveLibrarySearchPath, "activate",
+                    G_CALLBACK (on_remove_library_search_path_activate),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) Color, "activate",
+                    G_CALLBACK (on_color_activate),
+                    NULL);
+  g_signal_connect ((gpointer) OpenFilter, "activate",
+                    G_CALLBACK (on_filter_activate),
+                    NULL);
+  g_signal_connect ((gpointer) SaveConfiguration, "activate",
+                    G_CALLBACK (on_save_configuration_activate),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) Content, "activate",
+                    G_CALLBACK (on_content_activate),
+                    NULL);
+  g_signal_connect ((gpointer) About, "activate",
+                    G_CALLBACK (on_about_activate),
+                    NULL);
+  g_signal_connect ((gpointer) tlbEmptyTraceset, "clicked",
+                    G_CALLBACK (on_button_new_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbTab, "clicked",
+                    G_CALLBACK (on_button_new_tab_clicked),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) tlbOpenTraceset, "clicked",
+                    G_CALLBACK (on_button_open_clicked),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) tlbAddTrace, "clicked",
+                    G_CALLBACK (on_button_add_trace_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbRemoveTrace, "clicked",
+                    G_CALLBACK (on_button_remove_trace_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbRedraw, "clicked",
+                    G_CALLBACK (on_button_redraw_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbContinueProcessing, "clicked",
+                    G_CALLBACK (on_button_continue_processing_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbStopProcessing, "clicked",
+                    G_CALLBACK (on_button_stop_processing_clicked),
+                    NULL);
+/*
+  g_signal_connect ((gpointer) tlbSave, "clicked",
+                    G_CALLBACK (on_button_save_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbSaveAs, "clicked",
+                    G_CALLBACK (on_button_save_as_clicked),
+                    NULL);
+*/
+  g_signal_connect ((gpointer) tlbZoomIn, "clicked",
+                    G_CALLBACK (on_button_zoom_in_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbZoomOut, "clicked",
+                    G_CALLBACK (on_button_zoom_out_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbZoomExtended, "clicked",
+                    G_CALLBACK (on_button_zoom_extended_clicked),
+                    NULL);
+  /*
+  g_signal_connect ((gpointer) tlbGoToTime, "clicked",
+                    G_CALLBACK (on_button_go_to_time_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbShowTimeFrame, "clicked",
+                    G_CALLBACK (on_button_show_time_frame_clicked),
+                    NULL);
+                    */
+  g_signal_connect ((gpointer) tlbMoveViewerUp, "clicked",
+                    G_CALLBACK (on_button_move_up_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbMoveViewerDown, "clicked",
+                    G_CALLBACK (on_button_move_down_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) tlbRemoveViewer, "clicked",
+                    G_CALLBACK (on_button_delete_viewer_clicked),
+                    NULL);
+  g_signal_connect ((gpointer) MNotebook, "switch_page",
+                    G_CALLBACK (on_MNotebook_switch_page),
+                    NULL);
+
+  /* Store pointers to all widgets, for use by lookup_widget(). */
+  GLADE_HOOKUP_OBJECT_NO_REF (MWindow, MWindow, "MWindow");
+  GLADE_HOOKUP_OBJECT (MWindow, MVbox, "MVbox");
+  GLADE_HOOKUP_OBJECT (MWindow, MMenuBox, "MMenuBox");
+  GLADE_HOOKUP_OBJECT (MWindow, MenuMain, "MenuMain");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuTitle, "FileMenuTitle");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuTitle_menu, "FileMenuTitle_menu");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuNewTitle, "FileMenuNewTitle");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuNewTitle_menu, "FileMenuNewTitle_menu");
+  //  GLADE_HOOKUP_OBJECT (MWindow, EmptyTraceset, "EmptyTraceset");
+  GLADE_HOOKUP_OBJECT (MWindow, CloneTraceset, "CloneTraceset");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuNewSep, "FileMenuNewSep");
+  GLADE_HOOKUP_OBJECT (MWindow, Tab, "Tab");
+  //  GLADE_HOOKUP_OBJECT (MWindow, OpenTraceset, "OpenTraceset");
+  GLADE_HOOKUP_OBJECT (MWindow, Close, "Close");
+  GLADE_HOOKUP_OBJECT (MWindow, CloseTab, "CloseTab");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuSeparator1, "FileMenuSeparator1");
+  GLADE_HOOKUP_OBJECT (MWindow, AddTrace, "AddTrace");
+  GLADE_HOOKUP_OBJECT (MWindow, RemoveTrace, "RemoveTrace");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Save, "Save");
+  //  GLADE_HOOKUP_OBJECT (MWindow, SaveAs, "SaveAs");
+  GLADE_HOOKUP_OBJECT (MWindow, FileMenuSeparator2, "FileMenuSeparator2");
+  GLADE_HOOKUP_OBJECT (MWindow, Quit, "Quit");
+  //  GLADE_HOOKUP_OBJECT (MWindow, EditMenuTitle, "EditMenuTitle");
+  //  GLADE_HOOKUP_OBJECT (MWindow, EditMenuTitle_menu, "EditMenuTitle_menu");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Cut, "Cut");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Copy, "Copy");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Paste, "Paste");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Delete, "Delete");
+  GLADE_HOOKUP_OBJECT (MWindow, ViewMenuTitle, "ViewMenuTitle");
+  GLADE_HOOKUP_OBJECT (MWindow, ViewMenuTitle_menu, "ViewMenuTitle_menu");
+  GLADE_HOOKUP_OBJECT (MWindow, ZoomIn, "ZoomIn");
+  GLADE_HOOKUP_OBJECT (MWindow, ZoomOut, "ZoomOut");
+  GLADE_HOOKUP_OBJECT (MWindow, ZoomExtended, "ZoomExtended");
+  GLADE_HOOKUP_OBJECT (MWindow, ViewMenuSeparator, "ViewMenuSeparator");
+  //  GLADE_HOOKUP_OBJECT (MWindow, GoToTime, "GoToTime");
+  //  GLADE_HOOKUP_OBJECT (MWindow, ShowTimeFrame, "ShowTimeFrame");
+  GLADE_HOOKUP_OBJECT (MWindow, ToolMenuTitle, "ToolMenuTitle");
+  GLADE_HOOKUP_OBJECT (MWindow, ToolMenuTitle_menu, "ToolMenuTitle_menu");
+  GLADE_HOOKUP_OBJECT (MWindow, MoveViewerUp, "MoveViewerUp");
+  GLADE_HOOKUP_OBJECT (MWindow, MoveViewerDown, "MoveViewerDown");
+  GLADE_HOOKUP_OBJECT (MWindow, RemoveViewer, "RemoveViewer");
+  GLADE_HOOKUP_OBJECT (MWindow, ToolMenuSeparator, "ToolMenuSeparator");
+  GLADE_HOOKUP_OBJECT (MWindow, Filter, "Filter");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Facility, "Facility");
+  GLADE_HOOKUP_OBJECT (MWindow, ToolMenuSeparator1, "ToolMenuSeparator1");
+  //  GLADE_HOOKUP_OBJECT (MWindow, insert_viewer_test, "insert_viewer_test");
+  GLADE_HOOKUP_OBJECT (MWindow, PluginMenuTitle, "PluginMenuTitle");
+  GLADE_HOOKUP_OBJECT (MWindow, PluginMenuTitle_menu, "PluginMenuTitle_menu");
+  GLADE_HOOKUP_OBJECT (MWindow, LoadLibrary, "LoadLibrary");
+  GLADE_HOOKUP_OBJECT (MWindow, UnloadLibrary, "UnloadLibrary");
+  GLADE_HOOKUP_OBJECT (MWindow, LoadModule, "LoadModule");
+  GLADE_HOOKUP_OBJECT (MWindow, UnloadModule, "UnloadModule");
+  GLADE_HOOKUP_OBJECT (MWindow, AddLibrarySearchPath, "AddLibrarySearchPath");
+  GLADE_HOOKUP_OBJECT (MWindow, RemoveLibrarySearchPath, "RemoveLibrarySearchPath");
+  //  GLADE_HOOKUP_OBJECT (MWindow, OptionMenuTitle, "OptionMenuTitle");
+  //  GLADE_HOOKUP_OBJECT (MWindow, OptionMenuTitle_menu, "OptionMenuTitle_menu");
+  //  GLADE_HOOKUP_OBJECT (MWindow, Color, "Color");
+  //  GLADE_HOOKUP_OBJECT (MWindow, OptMenuSeparator, "OptMenuSeparator");
+  //  GLADE_HOOKUP_OBJECT (MWindow, OpenFilter, "OpenFilter");
+  //  GLADE_HOOKUP_OBJECT (MWindow, SaveConfiguration, "SaveConfiguration");
+  GLADE_HOOKUP_OBJECT (MWindow, MenuHelp, "MenuHelp");
+  GLADE_HOOKUP_OBJECT (MWindow, HelpMenuTitle, "HelpMenuTitle");
+  GLADE_HOOKUP_OBJECT (MWindow, HelpMenu, "HelpMenu");
+  GLADE_HOOKUP_OBJECT (MWindow, Content, "Content");
+  GLADE_HOOKUP_OBJECT (MWindow, HelpmenuSeparator, "HelpmenuSeparator");
+  GLADE_HOOKUP_OBJECT (MWindow, About, "About");
+  GLADE_HOOKUP_OBJECT (MWindow, MToolbar1, "MToolbar1");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbEmptyTraceset, "tlbEmptyTraceset");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbTab, "tlbTab");
+  //  GLADE_HOOKUP_OBJECT (MWindow, tlbOpenTraceset, "tlbOpenTraceset");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbAddTrace, "tlbAddTrace");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbRemoveTrace, "tlbRemoveTrace");
+  //  GLADE_HOOKUP_OBJECT (MWindow, tlbSave, "tlbSave");
+  //  GLADE_HOOKUP_OBJECT (MWindow, tlbSaveAs, "tlbSaveAs");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbZoomIn, "tlbZoomIn");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbZoomOut, "tlbZoomOut");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbZoomExtended, "tlbZoomExtended");
+  //  GLADE_HOOKUP_OBJECT (MWindow, tlbGoToTime, "tlbGoToTime");
+  // GLADE_HOOKUP_OBJECT (MWindow, tlbShowTimeFrame, "tlbShowTimeFrame");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbMoveViewerUp, "tlbMoveViewerUp");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbMoveViewerDown, "tlbMoveViewerDown");
+  GLADE_HOOKUP_OBJECT (MWindow, tlbRemoveViewer, "tlbRemoveViewer");
+  //  GLADE_HOOKUP_OBJECT (MWindow, MToolbar2, "MToolbar2");
+  GLADE_HOOKUP_OBJECT (MWindow, MNotebook, "MNotebook");
+  //  GLADE_HOOKUP_OBJECT (MWindow, label1, "label1");
+  GLADE_HOOKUP_OBJECT (MWindow, MStatusbar, "MStatusbar");
+
+  gtk_window_add_accel_group (GTK_WINDOW (MWindow), accel_group);
+
+  return MWindow;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/interface.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/interface.h
new file mode 100644 (file)
index 0000000..05d8846
--- /dev/null
@@ -0,0 +1,23 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+GtkWidget* create_MWindow (void);
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c
new file mode 100644 (file)
index 0000000..a379df5
--- /dev/null
@@ -0,0 +1,1154 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*! \file lttvwindow.c
+ * \brief API used by the graphical viewers to interact with their tab.
+ * 
+ * Main window (gui module) is the place to contain and display viewers. 
+ * Viewers (lttv plugins) interact with tab and main window through this API
+ * and events sent by gtk.
+ * This header file should be included in each graphic module.
+ * This library is used by graphical modules to interact with their tab and
+ * main window.
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ltt/ltt.h>
+#include <lttv/lttv.h>
+#include <lttv/state.h>
+#include <lttv/stats.h>
+#include <lttv/tracecontext.h>
+#include <lttvwindow/mainwindow.h>   
+#include <lttvwindow/mainwindow-private.h>   
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/toolbar.h>
+#include <lttvwindow/menu.h>
+#include <lttvwindow/callbacks.h> // for execute_events_requests
+#include <lttvwindow/support.h>
+
+/**
+ * Internal function parts
+ */
+
+extern GSList * g_main_window_list;
+
+/* set_time_window 
+ *
+ * It updates the time window of the tab, then calls the updatetimewindow
+ * hooks of each viewer.
+ *
+ * This is called whenever the scrollbar value changes.
+ */
+
+void set_time_window(Tab *tab, const TimeWindow *time_window)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+
+  TimeWindowNotifyData time_window_notify_data;
+  TimeWindow old_time_window = tab->time_window;
+  time_window_notify_data.old_time_window = &old_time_window;
+  tab->time_window = *time_window;
+  time_window_notify_data.new_time_window = 
+                          &(tab->time_window);
+
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatetimewindow", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp != NULL) lttv_hooks_call(tmp, &time_window_notify_data);
+
+  //gtk_multi_vpaned_set_adjust(tab->multi_vpaned, new_time_window, FALSE);
+
+}
+
+/* set_current_time
+ *
+ * It updates the current time of the tab, then calls the updatetimewindow
+ * hooks of each viewer.
+ *
+ * This is called whenever the current time value changes.
+ */
+
+void set_current_time(Tab *tab, const LttTime *current_time)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+
+  tab->current_time = *current_time;
+
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatecurrenttime", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp != NULL) lttv_hooks_call(tmp, &tab->current_time);
+}
+
+/* set_current_position
+ *
+ * It updates the current time of the tab, then calls the updatetimewindow
+ * hooks of each viewer.
+ *
+ * This is called whenever the current time value changes.
+ */
+
+void set_current_position(Tab *tab, const LttvTracesetContextPosition *pos)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+
+  tab->current_time = lttv_traceset_context_position_get_time(pos);
+
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatecurrentposition", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp != NULL) lttv_hooks_call(tmp, pos);
+}
+
+void add_toolbar_constructor(MainWindow *mw, LttvToolbarClosure *toolbar_c)
+{
+  LttvIAttribute *attributes = mw->attributes;
+  LttvAttributeValue value;
+  LttvToolbars * instance_toolbar;
+  lttvwindow_viewer_constructor constructor;
+  GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
+  GdkPixbuf *pixbuf;
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+          "viewers/toolbar", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_toolbars_new();
+  instance_toolbar = (LttvToolbars*)*(value.v_pointer);
+
+  constructor = toolbar_c->con;
+  tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
+  pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_c->pixmap);
+  pixmap = gtk_image_new_from_pixbuf(pixbuf);
+  new_widget =
+     gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
+        GTK_TOOLBAR_CHILD_BUTTON,
+        NULL,
+        "",
+        toolbar_c->tooltip, NULL,
+        pixmap, NULL, NULL);
+  gtk_label_set_use_underline(
+      GTK_LABEL (((GtkToolbarChild*) (
+                       g_list_last (GTK_TOOLBAR 
+                          (tool_menu_title_menu)->children)->data))->label),
+      TRUE);
+  gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
+  g_signal_connect ((gpointer) new_widget,
+      "clicked",
+      G_CALLBACK (insert_viewer_wrap),
+      constructor);       
+  gtk_widget_show (new_widget);
+
+  lttv_toolbars_add(instance_toolbar, toolbar_c->con, 
+                    toolbar_c->tooltip,
+                    toolbar_c->pixmap,
+                    new_widget);
+
+}
+
+void add_menu_constructor(MainWindow *mw, LttvMenuClosure *menu_c)
+{
+  LttvIAttribute *attributes = mw->attributes;
+  LttvAttributeValue value;
+  LttvToolbars * instance_menu;
+  lttvwindow_viewer_constructor constructor;
+  GtkWidget * tool_menu_title_menu, *new_widget;
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+          "viewers/menu", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_menus_new();
+  instance_menu = (LttvMenus*)*(value.v_pointer);
+
+
+  constructor = menu_c->con;
+  tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
+  new_widget =
+          gtk_menu_item_new_with_mnemonic (menu_c->menu_text);
+  gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
+          new_widget);
+  g_signal_connect ((gpointer) new_widget, "activate",
+                      G_CALLBACK (insert_viewer_wrap),
+                      constructor);
+  gtk_widget_show (new_widget);
+  lttv_menus_add(instance_menu, menu_c->con, 
+                    menu_c->menu_path,
+                    menu_c->menu_text,
+                    new_widget);
+}
+
+void remove_toolbar_constructor(MainWindow *mw, lttvwindow_viewer_constructor viewer_constructor)
+{
+  LttvIAttribute *attributes = mw->attributes;
+  LttvAttributeValue value;
+  LttvToolbars * instance_toolbar;
+  lttvwindow_viewer_constructor constructor;
+  GtkWidget * tool_menu_title_menu, *widget;
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+          "viewers/toolbar", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_toolbars_new();
+  instance_toolbar = (LttvToolbars*)*(value.v_pointer);
+
+  tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
+  widget = lttv_menus_remove(instance_toolbar, viewer_constructor);
+  gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), 
+                        widget);
+}
+
+
+void remove_menu_constructor(MainWindow *mw, lttvwindow_viewer_constructor viewer_constructor)
+{
+  LttvIAttribute *attributes = mw->attributes;
+  LttvAttributeValue value;
+  LttvMenus * instance_menu;
+  lttvwindow_viewer_constructor constructor;
+  GtkWidget * tool_menu_title_menu, *widget;
+  LttvMenuClosure *menu_item_i;
+
+  g_assert(lttv_iattribute_find_by_path(attributes,
+          "viewers/menu", LTTV_POINTER, &value));
+  if(*(value.v_pointer) == NULL)
+    *(value.v_pointer) = lttv_menus_new();
+  instance_menu = (LttvMenus*)*(value.v_pointer);
+
+  widget = lttv_menus_remove(instance_menu, viewer_constructor);
+  tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
+  gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), widget);
+}
+
+
+/**
+ * API parts
+ */
+
+
+/**
+ * Function to register a view constructor so that main window can generate
+ * a menu item and a toolbar item for the viewer in order to generate a new
+ * instance easily. A menu entry and toolbar item will be added to each main
+ * window.
+ * 
+ * It should be called by init function of the module.
+ * 
+ * @param name name of the viewer
+ * @param menu_path path of the menu item.
+ * @param menu_text text of the menu item.
+ * @param pixmap Image shown on the toolbar item.
+ * @param tooltip tooltip of the toolbar item.
+ * @param view_constructor constructor of the viewer. 
+ */
+
+void lttvwindow_register_constructor
+                            (char *  name,
+                             char *  menu_path, 
+                             char *  menu_text,
+                             char ** pixmap,
+                             char *  tooltip,
+                             lttvwindow_viewer_constructor view_constructor)
+{
+  LttvIAttribute *attributes_global = LTTV_IATTRIBUTE(lttv_global_attributes());
+  LttvToolbars * toolbar;
+  LttvMenus * menu;
+  LttvToolbarClosure toolbar_c;
+  LttvMenuClosure menu_c;
+  LttvAttributeValue value;
+
+  if(view_constructor == NULL) return;
+  
+  if(pixmap != NULL) {
+    g_assert(lttv_iattribute_find_by_path(attributes_global,
+       "viewers/toolbar", LTTV_POINTER, &value));
+    toolbar = (LttvToolbars*)*(value.v_pointer);
+
+    if(toolbar == NULL) {
+      toolbar = lttv_toolbars_new();
+      *(value.v_pointer) = toolbar;
+    }
+    toolbar_c = lttv_toolbars_add(toolbar, view_constructor, tooltip, pixmap,
+                                  NULL);
+
+    g_slist_foreach(g_main_window_list,
+                    (gpointer)add_toolbar_constructor,
+                    &toolbar_c);
+  }
+
+  if(menu_path != NULL) {
+    g_assert(lttv_iattribute_find_by_path(attributes_global,
+       "viewers/menu", LTTV_POINTER, &value));
+    menu = (LttvMenus*)*(value.v_pointer);
+    
+    if(menu == NULL) {
+      menu = lttv_menus_new();
+      *(value.v_pointer) = menu;
+    }
+    menu_c = lttv_menus_add(menu, view_constructor, menu_path, menu_text,NULL);
+
+    g_slist_foreach(g_main_window_list,
+                    (gpointer)add_menu_constructor,
+                    &menu_c);
+  }
+  {
+    LttvAttribute *attribute;
+    g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(attributes_global),
+                                LTTV_VIEWER_CONSTRUCTORS)));
+  
+    g_assert(lttv_iattribute_find_by_path(LTTV_IATTRIBUTE(attribute),
+                            name, LTTV_POINTER, &value));
+
+    *(value.v_pointer) = view_constructor;
+
+  }
+}
+
+
+/**
+ * Function to unregister the viewer's constructor, release the space 
+ * occupied by menu_path, menu_text, pixmap, tooltip and constructor of the
+ * viewer.
+ * 
+ * It will be called when a module is unloaded.
+ * 
+ * @param view_constructor constructor of the viewer.
+ */
+
+
+void lttvwindow_unregister_constructor
+                  (lttvwindow_viewer_constructor view_constructor)
+{
+  LttvIAttribute *attributes_global = LTTV_IATTRIBUTE(lttv_global_attributes());
+  LttvToolbars * toolbar;
+  LttvMenus * menu;
+  LttvAttributeValue value;
+
+  g_assert(lttv_iattribute_find_by_path(attributes_global,
+     "viewers/toolbar", LTTV_POINTER, &value));
+  toolbar = (LttvToolbars*)*(value.v_pointer);
+  
+  if(toolbar != NULL) {
+    g_slist_foreach(g_main_window_list,
+                    (gpointer)remove_toolbar_constructor,
+                    view_constructor);
+    lttv_toolbars_remove(toolbar, view_constructor);
+  }
+
+  g_assert(lttv_iattribute_find_by_path(attributes_global,
+     "viewers/menu", LTTV_POINTER, &value));
+  menu = (LttvMenus*)*(value.v_pointer);
+  
+  if(menu != NULL) {
+    g_slist_foreach(g_main_window_list,
+                    (gpointer)remove_menu_constructor,
+                    view_constructor);
+    lttv_menus_remove(menu, view_constructor);
+  }
+
+  {
+    LttvAttribute *attribute;
+    g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(attributes_global),
+                                LTTV_VIEWER_CONSTRUCTORS)));
+  
+    guint num = lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute));
+    guint i;
+    LttvAttributeName name;
+    LttvAttributeValue value;
+    LttvAttributeType type;
+    
+    for(i=0;i<num;i++) {
+      type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), i, &name, &value);
+      g_assert(type == LTTV_POINTER);
+      if(*(value.v_pointer) == view_constructor) {
+        lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute), i);
+        break;
+      }
+    }
+  }
+}
+
+
+/**
+ * Function to register a hook function for a viewer to set/update its
+ * time interval.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+void lttvwindow_register_time_window_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatetimewindow", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook,hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update the time interval of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_time_window_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatetimewindow", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
+ * Function to register a hook function for a viewer to set/update its 
+ * traceset.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_traceset_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatetraceset", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update the traceset of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_traceset_notify(Tab *tab,
+              LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatetraceset", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
+ * Function to register a hook function for a viewer be completely redrawn.
+ * 
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_redraw_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/redraw", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a hook function for a viewer be completely redrawn.
+ *
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_redraw_notify(Tab *tab,
+              LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/redraw", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
+ * Function to register a hook function for a viewer to re-do the events
+ * requests for the needed interval.
+ *
+ * This action is typically done after a "stop".
+ *
+ * The typical hook will remove all current requests for the viewer
+ * and make requests for missing information.
+ * 
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_continue_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/continue", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a hook function for a viewer to re-do the events
+ * requests for the needed interval.
+ *
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_continue_notify(Tab *tab,
+              LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/continue", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+
+/**
+ * Function to register a hook function for a viewer to set/update its 
+ * filter.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_filter_notify(Tab *tab,
+      LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatefilter", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update the filter of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_filter_notify(Tab *tab,
+                                         LttvHook hook,
+                                         gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatefilter", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
+ * function to register a hook function for a viewer to set/update its 
+ * current time.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_current_time_notify(Tab *tab,
+            LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatecurrenttime", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * function to unregister a viewer's hook function which is used to 
+ * set/update the current time of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_current_time_notify(Tab *tab,
+            LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatecurrenttime", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
+ * function to register a hook function for a viewer to set/update its 
+ * current position.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_current_position_notify(Tab *tab,
+            LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatecurrentposition", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * function to unregister a viewer's hook function which is used to 
+ * set/update the current position of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_current_position_notify(Tab *tab,
+            LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatecurrentposition", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+
+/**
+ * Function to register a hook function for a viewer to show 
+ * the content of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_show_notify(Tab *tab,
+          LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/showviewer", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * show the content of the viewer..
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_show_notify(Tab *tab,
+              LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/showviewer", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
+ * Function to register a hook function for a viewer to set/update the 
+ * dividor of the hpane.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_dividor(Tab *tab,
+                    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/hpanedividor", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL){    
+    tmp = lttv_hooks_new();
+    *(value.v_pointer) = tmp;
+  }
+  lttv_hooks_add(tmp, hook, hook_data, LTTV_PRIO_DEFAULT);
+}
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update hpane's dividor of the viewer.
+ * It will be called by the destructor of the viewer.
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_dividor(Tab *tab,
+                    LttvHook hook, gpointer hook_data)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/hpanedividor", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+
+/**
+ * Function to set the time interval of the current tab.
+ * It will be called by a viewer's signal handle associated with 
+ * the move_slider signal
+ * @param tab viewer's tab 
+ * @param time_interval a pointer where time interval is stored.
+ */
+
+void lttvwindow_report_time_window(Tab *tab,
+                                   TimeWindow time_window)
+{
+  //set_time_window(tab, time_window);
+  //set_time_window_adjustment(tab, time_window);
+
+  time_change_manager(tab, time_window);
+
+  
+#if 0    
+  /* Set scrollbar */
+  LttvTracesetContext *tsc =
+        LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+  TimeInterval time_span = tsc->time_span;
+  GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
+  g_object_set(G_OBJECT(adjustment),
+               "lower",
+               0.0, /* lower */
+               "upper",
+               ltt_time_to_double(
+                 ltt_time_sub(time_span.end_time, time_span.start_time)) 
+                 , /* upper */
+               "step_increment",
+               ltt_time_to_double(time_window->time_width)
+                             / SCROLL_STEP_PER_PAGE
+                            , /* step increment */
+               "page_increment",
+               ltt_time_to_double(time_window->time_width) 
+                 , /* page increment */
+               "page_size",
+               ltt_time_to_double(time_window->time_width) 
+                 , /* page size */
+               NULL);
+  gtk_adjustment_changed(adjustment);
+
+  //g_object_set(G_OBJECT(adjustment),
+  //             "value",
+  //             ltt_time_to_double(time_window->start_time) 
+  //               , /* value */
+  //               NULL);
+  /* Note : the set value will call set_time_window if scrollbar value changed
+   */
+  gtk_adjustment_set_value(adjustment,
+                           ltt_time_to_double(
+                             ltt_time_sub(time_window->start_time,
+                                          time_span.start_time))
+                           );
+#endif //0
+}
+
+
+/**
+ * Function to set the current time of the current tab.
+ * It will be called by a viewer's signal handle associated with 
+ * the button-release-event signal
+ * @param tab viewer's tab 
+ * @param time a pointer where time is stored.
+ */
+
+void lttvwindow_report_current_time(Tab *tab,
+                                    LttTime time)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  
+  current_time_change_manager(tab, time);
+}
+
+/**
+ * Function to set the current event of the current tab.
+ * It will be called by a viewer's signal handle associated with 
+ * the button-release-event signal
+ * @param tab viewer's tab 
+ * @param time a pointer where time is stored.
+ */
+
+void lttvwindow_report_current_position(Tab *tab,
+                                        LttvTracesetContextPosition *pos)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  
+  current_position_change_manager(tab, pos);
+}
+
+
+/**
+ * Function to set the position of the hpane's dividor (viewer).
+ * It will be called by a viewer's signal handle associated with 
+ * the motion_notify_event event/signal
+ * @param tab viewer's tab 
+ * @param position position of the hpane's dividor.
+ */
+
+void lttvwindow_report_dividor(Tab *tab, gint position)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/hpanedividor", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_call(tmp, &position);
+}
+
+/**
+ * Function to request data in a specific time interval to the main window. The
+ * event request servicing is differed until the glib idle functions are
+ * called.
+ *
+ * The viewer has to provide hooks that should be associated with the event
+ * request.
+ *
+ * Either start time or start position must be defined in a EventRequest
+ * structure for it to be valid.
+ *
+ * end_time, end_position and num_events can all be defined. The first one
+ * to occur will be used as end criterion.
+ * 
+ * @param tab viewer's tab 
+ * @param events_requested the structure of request from.
+ */
+
+void lttvwindow_events_request(Tab *tab,
+                               EventsRequest  *events_request)
+{
+  tab->events_requests = g_slist_append(tab->events_requests, events_request);
+  
+  if(!tab->events_request_pending)
+  {
+    /* Redraw has +20 priority. We want to let the redraw be done while we do
+     * our job. Mathieu : test with high prio higher than events for better
+     * scrolling. */
+    //g_idle_add_full((G_PRIORITY_HIGH_IDLE + 21),
+    g_idle_add_full((G_PRIORITY_DEFAULT + 2),
+                    (GSourceFunc)execute_events_requests,
+                    tab,
+                    NULL);
+    tab->events_request_pending = TRUE;
+  }
+}
+
+
+/**
+ * Function to remove data requests related to a viewer.
+ *
+ * The existing requests's viewer gpointer is compared to the pointer
+ * given in argument to establish which data request should be removed.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param viewer a pointer to the viewer data structure
+ */
+
+gint find_viewer (const EventsRequest *a, gconstpointer b)
+{
+  return (a->owner != b);
+}
+
+
+void lttvwindow_events_request_remove_all(Tab       *tab,
+                                          gconstpointer   viewer)
+{
+  GSList *element = tab->events_requests;
+  
+  while((element = 
+            g_slist_find_custom(element, viewer,
+                                (GCompareFunc)find_viewer))
+              != NULL) {
+    EventsRequest *events_request = (EventsRequest *)element->data;
+    // Modified so a viewer being destroyed won't have its after_request
+    // called. Not so important anyway. Note that a viewer that call this
+    // remove_all function will not get its after_request called.
+    //if(events_request->servicing == TRUE) {
+    //  lttv_hooks_call(events_request->after_request, NULL);
+    //}
+    events_request_free(events_request);
+    //g_free(events_request);
+    tab->events_requests = g_slist_remove_link(tab->events_requests, element);
+    element = g_slist_next(element);
+    if(element == NULL) break;   /* end of list */
+  }
+  if(g_slist_length(tab->events_requests) == 0) {
+    tab->events_request_pending = FALSE;
+    g_idle_remove_by_data(tab);
+  }
+
+}
+
+
+/**
+ * Function to see if there are events request pending.
+ *
+ * It tells if events requests are pending. Useful for checks in some events,
+ * i.e. detailed event list scrolling.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param viewer a pointer to the viewer data structure
+ * @return : TRUE is events requests are pending, else FALSE.
+ */
+
+gboolean lttvwindow_events_request_pending(Tab            *tab)
+{
+  GSList *element = tab->events_requests;
+
+  if(element == NULL) return FALSE;
+  else return TRUE;
+}
+
+
+
+
+/**
+ * Function to get the current time interval shown on the current tab.
+ * It will be called by a viewer's hook function to update the 
+ * shown time interval of the viewer and also be called by the constructor
+ * of the viewer.
+ * @param tab viewer's tab 
+ * @return time window.
+ */
+
+TimeWindow lttvwindow_get_time_window(Tab *tab)
+{
+  return tab->time_window;
+}
+
+
+/**
+ * Function to get the current time/event of the current tab.
+ * It will be called by a viewer's hook function to update the 
+ * current time/event of the viewer.
+ * @param tab viewer's tab 
+ * @return time
+ */
+
+LttTime lttvwindow_get_current_time(Tab *tab)
+{
+  return tab->current_time;
+}
+
+
+/**
+ * Function to get the filter of the current tab.
+ * @param filter, a pointer to a filter.
+ *
+ * returns the current filter
+ */
+LttvFilter *lttvwindow_get_filter(Tab *tab)
+{
+  return tab->filter;
+}
+
+/**
+ * Function to set the filter of the current tab.
+ * It should be called by the filter GUI to tell the
+ * main window to update the filter tab's lttv_filter.
+ *
+ * This function does change the current filter, removing the
+ * old one when necessary, and call the updatefilter hooks
+ * of the registered viewers.
+ *
+ * @param main_win, the main window the viewer belongs to.
+ * @param filter, a pointer to a filter.
+ */
+
+void lttvwindow_report_filter(Tab *tab, LttvFilter *filter)
+{
+  LttvAttributeValue value;
+  LttvHooks * tmp;
+
+  lttv_filter_destroy(tab->filter);
+  tab->filter = filter;
+  
+  g_assert(lttv_iattribute_find_by_path(tab->attributes,
+           "hooks/updatefilter", LTTV_POINTER, &value));
+  tmp = (LttvHooks*)*(value.v_pointer);
+  if(tmp == NULL) return;
+  lttv_hooks_call(tmp, filter);
+}
+
+
+
+/**
+ * Function to get the stats of the traceset 
+ * @param tab viewer's tab 
+ */
+
+LttvTracesetStats* lttvwindow_get_traceset_stats(Tab *tab)
+{
+  return tab->traceset_info->traceset_context;
+}
+
+
+LttvTracesetContext* lttvwindow_get_traceset_context(Tab *tab)
+{
+  return (LttvTracesetContext*)tab->traceset_info->traceset_context;
+}
+
+
+void events_request_free(EventsRequest *events_request)
+{
+  if(events_request == NULL) return;
+
+  if(events_request->start_position != NULL)
+       lttv_traceset_context_position_destroy(events_request->start_position);
+  if(events_request->end_position != NULL)
+       lttv_traceset_context_position_destroy(events_request->end_position);
+  if(events_request->hooks != NULL) {
+    guint i;
+    GArray *hooks = events_request->hooks;
+    for(i=0;i<hooks->len;i++) {
+      lttv_trace_hook_destroy(&g_array_index(hooks, LttvTraceHook, i));
+    }
+    g_array_free(events_request->hooks, TRUE);
+  }
+  if(events_request->before_chunk_traceset != NULL)
+       lttv_hooks_destroy(events_request->before_chunk_traceset);
+  if(events_request->before_chunk_trace != NULL)
+       lttv_hooks_destroy(events_request->before_chunk_trace);
+  if(events_request->before_chunk_tracefile != NULL)
+       lttv_hooks_destroy(events_request->before_chunk_tracefile);
+  if(events_request->event != NULL)
+       lttv_hooks_destroy(events_request->event);
+  if(events_request->event_by_id != NULL)
+       lttv_hooks_by_id_destroy(events_request->event_by_id);
+  if(events_request->after_chunk_tracefile != NULL)
+       lttv_hooks_destroy(events_request->after_chunk_tracefile);
+  if(events_request->after_chunk_trace != NULL)
+       lttv_hooks_destroy(events_request->after_chunk_trace);
+  if(events_request->after_chunk_traceset != NULL)
+       lttv_hooks_destroy(events_request->after_chunk_traceset);
+  if(events_request->before_request != NULL)
+       lttv_hooks_destroy(events_request->before_request);
+  if(events_request->after_request != NULL)
+       lttv_hooks_destroy(events_request->after_request);
+
+  g_free(events_request);
+}
+
+
+
+GtkWidget *main_window_get_widget(Tab *tab)
+{
+  return tab->mw->mwindow;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h
new file mode 100644 (file)
index 0000000..a3867f0
--- /dev/null
@@ -0,0 +1,827 @@
+/* This file is part of the Linux Trace Toolkit Graphic User Interface
+ * Copyright (C) 2003-2004 Xiangxiu Yang, Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*
+This file is what every viewer plugin writer should refer to.
+
+
+Module Related API
+
+A viewer plugin is, before anything, a plugin. As a dynamically loadable
+module, it thus has an init and a destroy function called whenever it is
+loaded/initialized and unloaded/destroyed. A graphical module depends on
+lttvwindow for construction of its viewer instances. In order to achieve
+this, it must register its constructor function to the main window along
+with button description or text menu entry description. A module keeps
+a list of every viewer that currently sits in memory so it can destroy
+them before the module gets unloaded/destroyed.
+
+The contructor registration to the main windows adds button and menu
+entry to each main window, thus allowing instanciation of viewers.
+
+
+Main Window
+
+The main window is a container that offers menus, buttons and a
+notebook. Some of those menus and buttons are part of the core of the
+main window, others are dynamically added and removed when modules are
+loaded/unloaded.
+
+The notebook contains as much tabs as wanted. Each tab is linked with
+a set of traces (traceset). Each trace contains many tracefiles (one
+per cpu).  A trace corresponds to a kernel being traced. A traceset
+corresponds to many traces read together. The time span of a traceset
+goes from the earliest start of all the traces to the latest end of all
+the traces.
+
+Inside each tab are added the viewers. When they interact with the main
+window through the lttvwindow API, they affect the other viewers located
+in the same tab as they are.
+
+The insertion of many viewers in a tab permits a quick look at all the
+information wanted in a glance. The main window does merge the read
+requests from all the viewers in the same tab in a way that every viewer
+will get exactly the events it asked for, while the event reading loop
+and state update are shared. It improves performance of events delivery
+to the viewers.
+
+
+
+Viewer Instance Related API
+
+The lifetime of a viewer is as follows. The viewer constructor function
+is called each time an instance view is created (one subwindow of this
+viewer type is created by the user either by clicking on the menu item
+or the button corresponding to the viewer). Thereafter, the viewer gets
+hooks called for different purposes by the window containing it. These
+hooks are detailed below. It also has to deal with GTK Events. Finally,
+it can be destructed by having its top level widget unreferenced by the
+main window or by any GTK Event causing a "destroy-event" signal on the
+its top widget. Another possible way for it do be destroyed is if the
+module gets unloaded. The module unload function will have to emit a
+"destroy" signal on each top level widget of all instances of its viewers.
+
+
+Notices from Main Window
+
+time_window : This is the time interval visible on the viewer's tab. Every
+              viewer that cares about being synchronised by respect to the
+              time with other viewers should register to this notification.
+              They should redraw all or part of their display when this occurs.
+
+traceset :    This notification is called whenever a trace is added/removed
+              from the traceset. As it affects all the data displayed by the
+              viewer, it sould redraw itself totally.
+
+filter :      FIXME : describe..
+
+current_time: Being able to zoom nearer a specific time or highlight a specific
+              time on every viewer in synchronicity implies that the viewer
+              has to shown a visual sign over the drawing or select an event
+              when it receives this notice. It should also inform the main
+              window with the appropriate report API function when a user
+              selects a specific time as being the current time.
+
+dividor :     This notice links the positions of the horizontal dividors
+              between the graphic display zone of every viewer and their Y axis,
+              typically showing processes, cpus, ...
+              
+
+Reporting Changes to the Main Window
+
+In most cases, the enclosing window knows about updates such as described
+in the Notification section higher. There are a few cases, however, where
+updates are caused by actions known by a view instance. For example,
+clicking in a view may update the current time; all viewers within
+the same window must be told about the new current time to change the
+currently highlighted time point. A viewer reports such events by calling
+lttvwindow_report_current_time on its lttvwindow.  The lttvwindow will
+consequently call current_time_notify for each of its contained viewers.
+
+
+Available report methods are :
+
+lttvwindow_report_time_window : reports the new time window.
+lttvwindow_report_current_time : reports the new current time.
+lttvwindow_report_dividor : reports the new horizontal dividor's position.
+lttvwindow_report_filter : reports the new filter object
+
+
+
+Requesting Events to Main Window
+
+Events can be requested by passing a EventsRequest structure to the main
+window.  They will be delivered later when the next g_idle functions
+will be called.  Event delivery is done by calling the event hook for
+this event ID, or the main event hooks. A pointer to the EventsRequest
+structure is passed as hook_data to the event hooks of the viewers.
+
+EventsRequest consists in 
+- a pointer to the viewer specific data structure
+- a start timestamp or position
+- a stop_flag, ending the read process when set to TRUE
+- a end timestamp and/or position and/or number of events to read
+- hook lists to call for traceset/trace/tracefile begin and end, and for each
+  event (event hooks and event_by_id hooks).
+  
+The main window will deliver events for every EventRequests it has
+pending through an algorithm that guarantee that all events requested,
+and only them, will be delivered to the viewer between the call of the
+tracefile_begin hooks and the call of the tracefile_end hooks.
+
+If a viewer wants to stop the event request at a certain point inside the
+event hooks, it has to set the stop_flag to TRUE and return TRUE from the
+hook function. Then return value will stop the process traceset. Then,
+the main window will look for the stop_flag and remove the EventRequests
+from its lists, calling the process_traceset_end for this request (it
+removes hooks from the context and calls the after hooks).
+
+It no stop_flag is risen, the end timestamp, end position or number
+of events to read has to be reached to determine the end of the
+request. Otherwise, the end of traceset does determine it.
+
+
+GTK Events
+
+Events and Signals
+
+GTK is quite different from the other graphical toolkits around
+there. The main difference resides in that there are many X Windows
+inside one GtkWindow, instead of just one. That means that X events are
+delivered by the glib main loop directly to the widget corresponding to
+the GdkWindow affected by the X event.
+
+Event delivery to a widget emits a signal on that widget. Then, if a
+handler is connected to this widget's signal, it will be executed. There
+are default handlers for signals, connected at class instantiation
+time. There is also the possibility to connect other handlers to these
+signals, which is what should be done in most cases when a viewer needs
+to interact with X in any way.
+
+
+
+Signal emission and propagation is described there : 
+
+http://www.gtk.org/tutorial/sec-signalemissionandpropagation.html
+
+For further information on the GTK main loop (now a wrapper over glib main loop)
+see :
+
+http://developer.gnome.org/doc/API/2.0/gtk/gtk-General.html
+http://developer.gnome.org/doc/API/2.0/glib/glib-The-Main-Event-Loop.html
+
+
+For documentation on event handling in GTK/GDK, see :
+
+http://developer.gnome.org/doc/API/2.0/gdk/gdk-Events.html
+http://developer.gnome.org/doc/API/2.0/gdk/gdk-Event-Structures.html
+
+
+Signals can be connected to handlers, emitted, propagated, blocked, 
+stopped. See :
+
+http://developer.gnome.org/doc/API/2.0/gobject/gobject-Signals.html
+
+
+
+
+The "expose_event"
+
+Provides the exposed region in the GdkEventExpose structure. 
+
+There are two ways of dealing with exposures. The first one is to directly
+draw on the screen and the second one is to draw in a pixmap buffer,
+and then to update the screen when necessary.
+
+In the first case, the expose event will be responsible for registering
+hooks to process_traceset and require time intervals to the main
+window. So, in this scenario, if a part of the screen is damaged, the
+trace has to be read to redraw the screen.
+
+In the second case, with a pixmap buffer, the expose handler is only
+responsible of showing the pixmap buffer on the screen. If the pixmap
+buffer has never been filled with a drawing, the expose handler may ask
+for it to be filled.
+
+The interest of using events request to the main window instead of reading
+the events directly from the trace comes from the fact that the main
+window does merge requests from the different viewers in the same tab so
+that the read loop and the state update is shared. As viewers will, in
+the common scenario, request the same events, only one pass through the
+trace that will call the right hooks for the right intervals will be done.
+
+When the traceset read is over for a events request, the traceset_end
+hook is called. It has the responsibility of finishing the drawing if
+some parts still need to be drawn and to show it on the screen (if the
+viewer uses a pixmap buffer).
+
+It can add dotted lines and such visual effects to enhance the user's
+experience.
+
+
+FIXME : explain other important events
+
+*/
+
+
+#ifndef LTTVWINDOW_H
+#define LTTVWINDOW_H
+
+/*! \file lttvwindow.h
+ * \brief API used by the graphical viewers to interact with their top window.
+ * 
+ * Main window (lttvwindow module) is the place to contain and display viewers. 
+ * Viewers (lttv plugins) interact with main window through this API.
+ * This header file should be included in each graphic module.
+ * 
+ */
+
+#include <gtk/gtk.h>
+#include <ltt/ltt.h>
+#include <ltt/time.h>
+#include <lttv/hook.h>
+#include <lttv/tracecontext.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+#include <lttvwindow/mainwindow.h>
+
+/* Module Related API */
+
+/* GQuark containing constructors of viewers in global attributes */
+extern GQuark LTTV_VIEWER_CONSTRUCTORS;
+
+/* constructor a the viewer */
+typedef GtkWidget* (*lttvwindow_viewer_constructor)(Tab *tab);
+
+
+/**
+ * Function to register a view constructor so that main window can generate
+ * a menu item and a toolbar item for the viewer in order to generate a new
+ * instance easily. A menu entry and toolbar item will be added to each main
+ * window.
+ * 
+ * It should be called by init function of the module.
+ *
+ * @param name name of the viewer : mainly used as tag for constructor
+ * @param menu_path path of the menu item. NULL : no menu entry.
+ * @param menu_text text of the menu item.
+ * @param pixmap Image shown on the toolbar item. NULL : no button.
+ * @param tooltip tooltip of the toolbar item.
+ * @param view_constructor constructor of the viewer. 
+ */
+
+void lttvwindow_register_constructor
+                            (char * name,
+                             char *  menu_path, 
+                             char *  menu_text,
+                             char ** pixmap,
+                             char *  tooltip,
+                             lttvwindow_viewer_constructor view_constructor);
+
+
+/**
+ * Function to unregister the viewer's constructor, release the space 
+ * occupied by menu_path, menu_text, pixmap, tooltip and constructor of the
+ * viewer.
+ * 
+ * It will be called when a module is unloaded.
+ * 
+ * @param view_constructor constructor of the viewer.
+ */
+
+void lttvwindow_unregister_constructor
+                            (lttvwindow_viewer_constructor view_constructor);
+
+
+
+
+/* Viewer Instance Related API */
+
+/**
+ * Structure used as hook_data for the time_window_notify hook.
+ */
+typedef struct _TimeWindowNotifyData {
+  TimeWindow *new_time_window;
+  TimeWindow *old_time_window;
+} TimeWindowNotifyData;
+
+
+/**
+ * Function to register a hook function that will be called by the main window
+ * when the time interval needs to be updated.
+ * 
+ * This register function is typically called by the constructor of the viewer.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook that sould be called by the main window when the time
+ *             interval changes. This hook function takes a
+ *             TimeWindowNotifyData* as call_data.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_register_time_window_notify(Tab *tab,
+                                            LttvHook    hook,
+                                            gpointer    hook_data);
+
+
+/**
+ * Function to unregister the time_window notification hook.
+ * 
+ * This unregister function is typically called by the destructor of the viewer.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook that sould be called by the main window when the time
+ *             interval changes. This hook function takes a
+ *             TimeWindowNotifyData* as call_data.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_unregister_time_window_notify(Tab *tab,
+                                              LttvHook    hook, 
+                                              gpointer    hook_data);
+
+
+/**
+ * Function to register a hook function that will be called by the main window
+ * when the traceset is changed. That means that the viewer must redraw
+ * itself completely or check if it's affected by the particular change to the
+ * traceset.
+ *
+ * This register function is typically called by the constructor of the viewer.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook that should be called whenever a change to the traceset
+ *             occurs. The call_data of this hook is a NULL pointer.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_register_traceset_notify(Tab *tab,
+                                         LttvHook    hook,
+                                         gpointer    hook_data);
+
+
+/**
+ * Function to unregister the traceset_notify hook.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook that should be called whenever a change to the traceset
+ *             occurs. The call_data of this hook is a NULL pointer.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_unregister_traceset_notify(Tab *tab,
+                                           LttvHook    hook,
+                                           gpointer    hook_data);
+
+
+/**
+ * Function to register a hook function for a viewer be completely redrawn.
+ * 
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_redraw_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data);
+
+/**
+ * Function to unregister a hook function for a viewer be completely redrawn.
+ *
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_redraw_notify(Tab *tab,
+              LttvHook hook, gpointer hook_data);
+
+
+/**
+ * Function to register a hook function for a viewer to re-do the events
+ * requests for the needed interval.
+ *
+ * This action is typically done after a "stop".
+ *
+ * The typical hook will remove all current requests for the viewer
+ * and make requests for missing information.
+ * 
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_register_continue_notify(Tab *tab,
+    LttvHook hook, gpointer hook_data);
+
+
+/**
+ * Function to unregister a hook function for a viewer to re-do the events
+ * requests for the needed interval.
+ *
+ * @param tab viewer's tab 
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+void lttvwindow_unregister_continue_notify(Tab *tab,
+              LttvHook hook, gpointer hook_data);
+
+
+/**
+ * Function to register a hook function for a viewer to set/update its 
+ * filter. 
+ *
+ * FIXME : Add information about what a filter is as seen from a viewer and how
+ * to use it.
+ *
+ * This register function is typically called by the constructor of the viewer.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function called by the main window when a filter change
+ *             occurs.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_register_filter_notify(Tab *tab,
+                                       LttvHook    hook,
+                                       gpointer    hook_data);
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update the filter of the viewer.
+ * 
+ * This unregistration is called by the destructor of the viewer.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function called by the main window when a filter change
+ *             occurs.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_unregister_filter_notify(Tab *tab,
+                                         LttvHook     hook,
+                                         gpointer     hook_data);
+
+
+/**
+ * Function to get the current filter of the main window : useful at viewer
+ * instanciation.
+ * 
+ * @param tab the tab the viewer belongs to.
+ *
+ * returns : the current filter.
+ */
+
+
+LttvFilter *lttvwindow_get_filter(Tab *tab);
+
+/**
+ * Function to register a hook function for a viewer to set/update its 
+ * current time.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function of the viewer that updates the current time. The
+ *             call_data is a LttTime* representing the new current time.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_register_current_time_notify(Tab *tab,
+                                             LttvHook    hook,
+                                             gpointer    hook_data);
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update the current time of the viewer.
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function of the viewer that updates the current time. The
+ *             call_data is a LttTime* representing the new current time.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_unregister_current_time_notify(Tab *tab,
+                                               LttvHook    hook,
+                                               gpointer    hook_data);
+
+/**
+ * Function to register a hook function for a viewer to set/update its 
+ * current position.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function of the viewer that updates the current time. The
+ *             call_data is a LttTime* representing the new current time.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_register_current_position_notify(Tab *tab,
+                                             LttvHook    hook,
+                                             gpointer    hook_data);
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update the current position of the viewer.
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function of the viewer that updates the current time. The
+ *             call_data is a LttTime* representing the new current time.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_unregister_current_position_notify(Tab *tab,
+                                               LttvHook    hook,
+                                               gpointer    hook_data);
+
+
+
+/**
+ * Function to register a hook function for a viewer to set/update the 
+ * dividor of the hpane. It provides a way to make the horizontal
+ * dividors of all the viewers linked together.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function of the viewer that will be called whenever a
+ *             dividor changes in another viewer. The call_data of this hook
+ *             is a gint*. The value of the integer is the new position of the
+ *             hpane dividor.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_register_dividor(Tab *tab,
+                                 LttvHook    hook,
+                                 gpointer    hook_data);
+
+
+/**
+ * Function to unregister a viewer's hook function which is used to 
+ * set/update hpane's dividor of the viewer.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook function of the viewer that will be called whenever a
+ *             dividor changes in another viewer. The call_data of this hook
+ *             is a gint*. The value of the integer is the new position of the
+ *             hpane dividor.
+ * @param hook_data hook data associated with the hook function. It will
+ *                  be typically a pointer to the viewer's data structure.
+ */
+
+void lttvwindow_unregister_dividor(Tab *tab,
+                                   LttvHook    hook,
+                                   gpointer    hook_data);
+
+
+
+/**
+ * Function to set the time interval of the current tab.a
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param time_interval new time window.
+ */
+
+void lttvwindow_report_time_window(Tab *tab,
+                                   TimeWindow time_window);
+
+/**
+ * Function to set the current time of the current tab.
+ * It will be called by a viewer's signal handle associated with 
+ * the button-release-event signal
+ * @param tab the tab the viewer belongs to.
+ * @param time current time.
+ */
+
+void lttvwindow_report_current_time(Tab *tab, 
+                                    LttTime time);
+
+
+/**
+ * Function to set the current event of the current tab.
+ * It will be called by a viewer's signal handle associated with 
+ * the button-release-event signal
+ * @param tab the tab the viewer belongs to.
+ * @param pos the current position.
+ */
+
+void lttvwindow_report_current_position(Tab *tab,
+                                        LttvTracesetContextPosition *pos);
+
+/**
+ * Function to set the position of the hpane's dividor (viewer).
+ * It will typically be called by a viewer's signal handle associated 
+ * with the motion_notify_event event/signal.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param position position of the hpane's dividor.
+ */
+
+void lttvwindow_report_dividor(Tab *tab, gint position);
+
+
+/* Structure sent to the events request hook */
+                                                /* Value considered as empty*/
+typedef struct _EventsRequest {
+  gpointer                     owner;           /* Owner of the request     */
+  gpointer                     viewer_data;     /* Unset : NULL             */
+  gboolean                     servicing;       /* service in progress: TRUE*/ 
+  LttTime                      start_time;      /* Unset : ltt_time_infinite*/
+  LttvTracesetContextPosition *start_position;  /* Unset : NULL             */
+  gboolean                     stop_flag;       /* Continue:TRUE Stop:FALSE */
+  LttTime                      end_time;        /* Unset : ltt_time_infinite*/
+  guint                        num_events;      /* Unset : G_MAXUINT        */
+  LttvTracesetContextPosition *end_position;    /* Unset : NULL             */
+  gint                         trace;           /* unset : -1               */
+  GArray                      *hooks;           /* Unset : NULL             */
+  LttvHooks                   *before_chunk_traceset; /* Unset : NULL       */
+  LttvHooks                   *before_chunk_trace;    /* Unset : NULL       */
+  LttvHooks                   *before_chunk_tracefile;/* Unset : NULL       */
+  LttvHooks                   *event;           /* Unset : NULL             */
+  LttvHooksById               *event_by_id;     /* Unset : NULL             */
+  LttvHooks                   *after_chunk_tracefile; /* Unset : NULL       */
+  LttvHooks                   *after_chunk_trace;     /* Unset : NULL       */
+  LttvHooks                   *after_chunk_traceset;  /* Unset : NULL       */
+  LttvHooks                   *before_request;  /* Unset : NULL             */
+  LttvHooks                   *after_request;   /* Unset : NULL             */
+} EventsRequest;
+
+/* Maximum number of events to proceed at once in a chunk */
+#define CHUNK_NUM_EVENTS 6000
+
+
+/**
+ * Function to request data in a specific time interval to the main window. The
+ * event request servicing is differed until the glib idle functions are
+ * called.
+ *
+ * The viewer has to provide hooks that should be associated with the event
+ * request.
+ *
+ * Either start time or start position must be defined in a EventRequest
+ * structure for it to be valid.
+ *
+ * end_time, end_position and num_events can all be defined. The first one
+ * to occur will be used as end criterion.
+ *
+ * The events_request memory will be managed by the main window once its
+ * pointer is passed by this function.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param events_requested Details about the event request.
+ */
+
+void lttvwindow_events_request(Tab                  *tab,
+                               EventsRequest  *events_request);
+
+/**
+ * Function to remove data requests related to a viewer.
+ *
+ * The existing requests's viewer gpointer is compared to the pointer
+ * given in argument to establish which data request should be removed.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param viewer a pointer to the viewer data structure
+ */
+
+void lttvwindow_events_request_remove_all(Tab            *tab,
+                                          gconstpointer   viewer);
+
+
+/**
+ * Function to see if there are events request pending.
+ *
+ * It tells if events requests are pending. Useful for checks in some events,
+ * i.e. detailed event list scrolling.
+ * 
+ * @param tab the tab the viewer belongs to.
+ * @param viewer a pointer to the viewer data structure
+ * @return : TRUE is events requests are pending, else FALSE.
+ */
+
+gboolean lttvwindow_events_request_pending(Tab            *tab);
+
+
+
+
+/**
+ * Function to get the current time interval shown on the current tab.
+ * It will be called by a viewer's hook function to update the 
+ * shown time interval of the viewer and also be called by the constructor
+ * of the viewer.
+ * @param tab viewer's tab 
+ * @return time window.
+ */
+
+TimeWindow lttvwindow_get_time_window(Tab *tab);
+
+
+/**
+ * Function to get the current time of the current tab.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @return the current tab's current time.
+ */
+
+LttTime lttvwindow_get_current_time(Tab *tab);
+
+
+/**
+ * Function to get the filter of the current tab.
+ * @param main_win, the main window the viewer belongs to.
+ * @param filter, a pointer to a filter.
+ */
+
+//LttvFilter *lttvwindow_get_filter(Tab *tab);
+
+/**
+ * Function to set the filter of the current tab.
+ * It should be called by the filter GUI to tell the
+ * main window to update the filter tab's lttv_filter.
+ *
+ * Notice : the lttv_filter object will be owned by the
+ *          main window after the return of this function.
+ *          Do NOT desallocate it.
+ * 
+ * @param main_win, the main window the viewer belongs to.
+ * @param filter, a pointer to a filter.
+ */
+
+void lttvwindow_report_filter(Tab *tab, LttvFilter *filter);
+
+
+
+/**
+ * Function to get the stats of the traceset 
+ * It must be non const so the viewer can modify it.
+ * FIXME : a set/get pair of functions would be more appropriate here.
+ * @param tab the tab the viewer belongs to.
+ * @return A pointer to Traceset statistics.
+ */
+
+LttvTracesetStats* lttvwindow_get_traceset_stats(Tab *tab);
+
+/**
+ * Function to get the context of the traceset 
+ * It must be non const so the viewer can add and remove hooks from it.
+ * @param tab the tab the viewer belongs to.
+ * @return Context of the current tab.
+ */
+
+
+LttvTracesetContext* lttvwindow_get_traceset_context(Tab *tab);
+
+
+/* set_time_window 
+ *
+ * It updates the time window of the tab, then calls the updatetimewindow
+ * hooks of each viewer.
+ *
+ * This is called whenever the scrollbar value changes.
+ *
+ * This is mostly an internal function.
+ */
+
+void set_time_window(Tab *tab, const TimeWindow *time_window);
+
+
+/* set_current_time
+ *
+ * It updates the current time of the tab, then calls the updatetimewindow
+ * hooks of each viewer.
+ *
+ * This is called whenever the current time value changes.
+ *
+ * This is mostly an internal function.
+ */
+
+void set_current_time(Tab *tab, const LttTime *current_time);
+
+void events_request_free(EventsRequest *events_request);
+
+GtkWidget *main_window_get_widget(Tab *tab);
+
+#endif //LTTVWINDOW_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c
new file mode 100644 (file)
index 0000000..7699202
--- /dev/null
@@ -0,0 +1,1863 @@
+/* This file is part of the Linux Trace Toolkit Graphic User Interface
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* This file is the API used to launch any background computation on a trace */
+
+/* Here is the implementation of the API */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <ltt/time.h>
+#include <ltt/trace.h>
+#include <glib.h>
+#include <lttv/lttv.h>
+#include <lttv/traceset.h>
+#include <lttv/attribute.h>
+#include <lttv/tracecontext.h>
+#include <lttvwindow/lttvwindowtraces.h>
+#include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
+#include <lttvwindow/mainwindow-private.h> /* for main window structure */
+
+extern GSList * g_main_window_list;
+
+typedef struct _BackgroundRequest {
+  LttvAttributeName module_name; /* Hook path in global attributes,
+                                    where all standard hooks under computation/.
+                                    i.e. modulename */
+  LttvTrace *trace; /* trace concerned */
+  GtkWidget *dialog;  /* Dialog linked with the request, may be NULL */
+  GtkWidget *parent_window; /* Parent window the dialog must be transient for */
+} BackgroundRequest;
+
+typedef struct _BackgroundNotify {
+  gpointer                     owner;
+  LttvTrace                   *trace; /* trace */
+  LttTime                      notify_time;
+  LttvTracesetContextPosition *notify_position;
+  LttvHooks                   *notify; /* Hook to call when the notify is
+                                          passed, or at the end of trace */
+} BackgroundNotify;
+
+
+
+/* Prototypes */
+gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
+
+/* Get a trace by its path name. 
+ *
+ * @param path path of the trace on the virtual file system.
+ * @return Pointer to trace if found
+ *         NULL is returned if the trace is not present
+ */
+
+LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
+{
+  guint i;
+
+  for(i=0;i<lttvwindowtraces_get_number();i++) {
+    LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
+    LttTrace *trace;
+    gchar *name;
+    g_assert(trace_v != NULL);
+
+    trace = lttv_trace(trace_v);
+    g_assert(trace != NULL);
+    name = g_quark_to_string(ltt_trace_name(trace));
+
+    if(strcmp(name, path) == 0) {
+      /* Found */
+      return trace_v;
+    }
+  }
+  
+  return NULL;
+}
+
+/* Get a trace by its number identifier */
+
+LttvTrace *lttvwindowtraces_get_trace(guint num)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *attribute;
+  LttvAttributeType type;
+  LttvAttributeName name;
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_TRACES)));
+  
+  type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value);
+
+  if(type == LTTV_POINTER) {
+    return (LttvTrace *)*(value.v_pointer);
+  }
+
+  return NULL;
+}
+
+/* Total number of traces */
+
+guint lttvwindowtraces_get_number()
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *attribute;
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_TRACES)));
+  return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute)) );
+}
+
+/* Add a trace to the global attributes */
+
+void lttvwindowtraces_add_trace(LttvTrace *trace)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *attribute;
+  LttvAttributeValue value;
+  guint num;
+  struct stat buf;
+  gchar attribute_path[PATH_MAX];
+
+  if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace))), &buf)) {
+    g_warning("lttvwindowtraces_add_trace: Trace %s not found",
+        g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
+    return;
+  }
+  g_assert(
+      snprintf(attribute_path, PATH_MAX, "%llu:%llu", buf.st_dev, buf.st_ino) >= 0);
+  
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_TRACES)));
+    
+  value = lttv_attribute_add(attribute,
+                     g_quark_from_string(attribute_path),
+                     LTTV_POINTER);
+
+  *(value.v_pointer) = (gpointer)trace;
+  
+  /* create new traceset and tracesetcontext */
+  LttvTraceset *ts;
+  LttvTracesetStats *tss;
+  //LttvTracesetContextPosition *sync_position;
+  
+  attribute = lttv_trace_attribute(trace);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_COMPUTATION_TRACESET,
+                                LTTV_POINTER,
+                                &value));
+  ts = lttv_traceset_new();
+  *(value.v_pointer) = ts;
+  lttv_traceset_add(ts,trace);
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_COMPUTATION_TRACESET_CONTEXT,
+                                LTTV_POINTER,
+                                &value));
+  tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+  *(value.v_pointer) = tss;
+  
+  lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
+#if 0
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_COMPUTATION_SYNC_POSITION,
+                                LTTV_POINTER,
+                                &value));
+
+  sync_position = lttv_traceset_context_position_new();
+  *(value.v_pointer) = sync_position;
+#endif //0
+  value = lttv_attribute_add(attribute,
+                     LTTV_REQUESTS_QUEUE,
+                     LTTV_POINTER);
+
+  value = lttv_attribute_add(attribute,
+                     LTTV_REQUESTS_CURRENT,
+                     LTTV_POINTER);
+  value = lttv_attribute_add(attribute,
+                     LTTV_NOTIFY_QUEUE,
+                     LTTV_POINTER);
+  
+  value = lttv_attribute_add(attribute,
+                     LTTV_NOTIFY_CURRENT,
+                     LTTV_POINTER);
+}
+
+/* Remove a trace from the global attributes */
+
+void lttvwindowtraces_remove_trace(LttvTrace *trace)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *attribute;
+  LttvAttributeValue value;
+  guint i;
+
+  g_assert(attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_TRACES)));
+
+  for(i=0;i<lttvwindowtraces_get_number();i++) {
+    LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
+    
+    g_assert(trace_v != NULL);
+
+    /* Remove and background computation that could be in progress */
+    g_idle_remove_by_data(trace_v);
+    
+    if(trace_v == trace) {
+      /* Found */
+      LttvAttribute *l_attribute;
+
+      /* destroy traceset and tracesetcontext */
+      LttvTraceset *ts;
+      LttvTracesetStats *tss;
+      //LttvTracesetContextPosition *sync_position;
+      
+      l_attribute = lttv_trace_attribute(trace);
+
+
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_REQUESTS_QUEUE);
+
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_REQUESTS_CURRENT);
+
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_NOTIFY_QUEUE);
+
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_NOTIFY_CURRENT);
+
+      g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
+                                    LTTV_COMPUTATION_TRACESET,
+                                    LTTV_POINTER,
+                                    &value));
+      ts = (LttvTraceset*)*(value.v_pointer);
+#if 0   
+      g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
+                                    LTTV_COMPUTATION_SYNC_POSITION,
+                                    LTTV_POINTER,
+                                    &value));
+      sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
+      lttv_traceset_context_position_destroy(sync_position);
+      
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_COMPUTATION_SYNC_POSITION);
+
+#endif //0
+      g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
+                                    LTTV_COMPUTATION_TRACESET_CONTEXT,
+                                    LTTV_POINTER,
+                                    &value));
+      tss = (LttvTracesetStats*)*(value.v_pointer);
+      
+      lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
+      g_object_unref(tss);
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_COMPUTATION_TRACESET_CONTEXT);
+      lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
+                                     LTTV_COMPUTATION_TRACESET);
+      /* Destroy the traceset and the trace also */
+      lttv_traceset_destroy(ts);
+
+      /* finally, remove the global attribute */
+      lttv_attribute_remove(attribute, i);
+
+      return;
+    }
+  }
+}
+
+static void destroy_dialog(BackgroundRequest *bg_req)
+{
+  gtk_widget_destroy(bg_req->dialog);
+  bg_req->dialog = NULL;
+}
+
+
+/**
+ * Function to request data from a specific trace
+ *
+ * The memory allocated for the request will be managed by the API.
+ * 
+ * @param widget the current Window
+ * @param trace the trace to compute
+ * @param module_name the name of the module which registered global computation
+ *                    hooks.
+ */
+
+void lttvwindowtraces_background_request_queue
+                     (GtkWidget *widget, LttvTrace *trace, gchar *module_name)
+{
+  BackgroundRequest *bg_req;
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *module_attribute;
+  LttvAttributeValue value;
+  LttvAttributeType type;
+  GSList **slist;
+  guint num;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_REQUESTS_QUEUE,
+                                LTTV_POINTER,
+                                &value));
+  slist = (GSList**)(value.v_pointer);
+
+  /* Verify that the calculator is loaded */
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     g_quark_from_string(module_name),
+                                     &value);
+  if(type == LTTV_NONE) {
+    g_critical("Missing background calculator %s", module_name);
+    return;
+  }
+
+  bg_req = g_new(BackgroundRequest,1);
+  bg_req->module_name = g_quark_from_string(module_name);
+  bg_req->trace = trace;
+
+  *slist = g_slist_append(*slist, bg_req);
+
+  /* Priority lower than live servicing */
+  g_idle_remove_by_data(trace);
+  g_idle_add_full((G_PRIORITY_HIGH_IDLE + 23),
+                  (GSourceFunc)lttvwindowtraces_process_pending_requests,
+                  trace,
+                  NULL);
+  /* FIXME : show message in status bar, need context and message id */
+  g_info("Background computation for %s started for trace %p", module_name,
+      trace);
+  GtkWidget *dialog = 
+    gtk_message_dialog_new(
+      GTK_WINDOW(widget),
+      GTK_DIALOG_DESTROY_WITH_PARENT,
+      GTK_MESSAGE_INFO, GTK_BUTTONS_OK, 
+      "Background computation for %s started for trace %s", 
+      module_name,
+      g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
+  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(widget));
+  g_signal_connect_swapped (dialog, "response",
+      G_CALLBACK (destroy_dialog),
+      bg_req);
+  bg_req->dialog = dialog;
+  /* the parent window might vanish : only use this pointer for a 
+   * comparison with existing windows */
+  bg_req->parent_window = gtk_widget_get_toplevel(widget);
+  gtk_widget_show(dialog);
+}
+
+/**
+ * Remove a background request from a trace.
+ *
+ * This should ONLY be used by the modules which registered the global hooks
+ * (module_name). If this is called by the viewers, it may lead to incomplete
+ * and incoherent background processing information.
+ *
+ * Even if the module which deals with the hooks removes the background
+ * requests, it may cause a problem if the module gets loaded again in the
+ * session : the data will be partially calculated. The calculation function
+ * must deal with this case correctly.
+ * 
+ * @param trace the trace to compute
+ * @param module_name the name of the module which registered global computation
+ *                    hooks.
+ */
+
+void lttvwindowtraces_background_request_remove
+                     (LttvTrace *trace, gchar *module_name)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+  GSList *iter = NULL;
+  GSList **slist;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_REQUESTS_QUEUE,
+                                LTTV_POINTER,
+                                &value));
+  slist = (GSList**)(value.v_pointer);
+
+  for(iter=*slist;iter!=NULL;) {
+    BackgroundRequest *bg_req = 
+              (BackgroundRequest *)iter->data;
+
+    if(bg_req->module_name == g_quark_from_string(module_name)) {
+      GSList *rem_iter = iter;
+      iter=g_slist_next(iter);
+      g_free(bg_req); 
+      *slist = g_slist_delete_link(*slist, rem_iter);
+    } else {
+      iter=g_slist_next(iter);
+    }
+  }
+}
+/**
+ * Find a background request in a trace
+ *
+ */
+
+gboolean lttvwindowtraces_background_request_find
+                     (LttvTrace *trace, gchar *module_name)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+  GSList *iter = NULL;
+  GSList **slist;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_REQUESTS_QUEUE,
+                                LTTV_POINTER,
+                                &value));
+  slist = (GSList**)(value.v_pointer);
+
+  for(iter=*slist;iter!=NULL;) {
+    BackgroundRequest *bg_req = 
+              (BackgroundRequest *)iter->data;
+
+    if(bg_req->module_name == g_quark_from_string(module_name)) {
+      return TRUE;
+    } else {
+      iter=g_slist_next(iter);
+    }
+  }
+  return FALSE;
+}
+/**
+ * Register a callback to be called when requested data is passed in the next
+ * queued background processing.
+ * 
+ * @param owner owner of the background notification
+ * @param trace the trace computed
+ * @param notify_time time when notification hooks must be called
+ * @param notify_position position when notification hooks must be called
+ * @param notify  Hook to call when the notify position is passed
+ */
+
+void lttvwindowtraces_background_notify_queue
+ (gpointer                     owner,
+  LttvTrace                   *trace,
+  LttTime                      notify_time,
+  const LttvTracesetContextPosition *notify_position,
+  const LttvHooks                   *notify)
+{
+  BackgroundNotify *bg_notify;
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+  GSList **slist;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_NOTIFY_QUEUE,
+                                LTTV_POINTER,
+                                &value));
+  slist = (GSList**)(value.v_pointer);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_COMPUTATION_TRACESET_CONTEXT,
+                                LTTV_POINTER,
+                                &value));
+  LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
+
+  bg_notify = g_new(BackgroundNotify,1);
+
+  bg_notify->owner = owner;
+  bg_notify->trace = trace;
+  bg_notify->notify_time = notify_time;
+  if(notify_position != NULL) {
+    bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
+    lttv_traceset_context_position_copy(bg_notify->notify_position,
+                                        notify_position);
+  } else {
+    bg_notify->notify_position = NULL;
+  }
+
+  bg_notify->notify = lttv_hooks_new();
+  lttv_hooks_add_list(bg_notify->notify, notify);
+
+  *slist = g_slist_append(*slist, bg_notify);
+}
+
+/**
+ * Register a callback to be called when requested data is passed in the current
+ * background processing.
+ * 
+ * @param owner owner of the background notification
+ * @param trace the trace computed
+ * @param notify_time time when notification hooks must be called
+ * @param notify_position position when notification hooks must be called
+ * @param notify  Hook to call when the notify position is passed
+ */
+
+void lttvwindowtraces_background_notify_current
+ (gpointer                     owner,
+  LttvTrace                   *trace,
+  LttTime                      notify_time,
+  const LttvTracesetContextPosition *notify_position,
+  const LttvHooks                   *notify)
+{
+  BackgroundNotify *bg_notify;
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+  GSList **slist;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_NOTIFY_CURRENT,
+                                LTTV_POINTER,
+                                &value));
+  slist = (GSList**)(value.v_pointer);
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_COMPUTATION_TRACESET_CONTEXT,
+                                LTTV_POINTER,
+                                &value));
+  LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
+
+
+  bg_notify = g_new(BackgroundNotify,1);
+
+  bg_notify->owner = owner;
+  bg_notify->trace = trace;
+  bg_notify->notify_time = notify_time;
+  if(notify_position!= NULL) {
+    bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
+    lttv_traceset_context_position_copy(bg_notify->notify_position,
+                                        notify_position);
+  } else {
+    bg_notify->notify_position = NULL;
+  }
+  bg_notify->notify = lttv_hooks_new();
+  lttv_hooks_add_list(bg_notify->notify, notify);
+
+  *slist = g_slist_append(*slist, bg_notify);
+}
+
+
+static void notify_request_free(BackgroundNotify *notify_req)
+{
+  if(notify_req == NULL) return;
+
+  if(notify_req->notify_position != NULL)
+    lttv_traceset_context_position_destroy(notify_req->notify_position);
+  if(notify_req->notify != NULL)
+    lttv_hooks_destroy(notify_req->notify);
+  g_free(notify_req);
+}
+
+/**
+ * Removes all the notifications requests from a specific viewer.
+ * 
+ * @param owner owner of the background notification
+ */
+
+void lttvwindowtraces_background_notify_remove(gpointer owner)
+{
+  guint i;
+
+  for(i=0;i<lttvwindowtraces_get_number();i++) {
+    LttvAttribute *attribute;
+    LttvAttributeValue value;
+    LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
+    GSList **slist;
+    GSList *iter = NULL;
+    
+    g_assert(trace_v != NULL);
+
+    attribute = lttv_trace_attribute(trace_v);
+
+    g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                  LTTV_NOTIFY_QUEUE,
+                                  LTTV_POINTER,
+                                  &value));
+    slist = (GSList**)(value.v_pointer);
+    for(iter=*slist;iter!=NULL;) {
+    
+      BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
+
+      if(bg_notify->owner == owner) {
+        GSList *rem_iter = iter;
+        iter=g_slist_next(iter);
+        notify_request_free(bg_notify);
+        *slist = g_slist_remove_link(*slist, rem_iter);
+      } else {
+        iter=g_slist_next(iter);
+      }
+    }
+
+    g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                  LTTV_NOTIFY_CURRENT,
+                                  LTTV_POINTER,
+                                  &value));
+    slist = (GSList**)(value.v_pointer);
+    for(iter=*slist;iter!=NULL;) {
+    
+      BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
+
+      if(bg_notify->owner == owner) {
+        GSList *rem_iter = iter;
+        iter=g_slist_next(iter);
+        notify_request_free(bg_notify);
+        *slist = g_slist_remove_link(*slist, rem_iter);
+      } else {
+        iter=g_slist_next(iter);
+      }
+    }
+  }
+}
+
+
+/* Background processing helper functions */
+
+void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
+                                            LttvTracesetContext *tsc,
+                                            LttvHooks *hook_adder)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *module_attribute;
+  LttvAttributeType type;
+  LttvAttributeValue value;
+
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(module_attribute),
+                                module_name)));
+
+  /* Call the module's hook adder */
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_HOOK_ADDER,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
+    if(hook_adder != NULL)
+      lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
+  }
+}
+                                            
+void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
+                                               LttvTracesetContext *tsc,
+                                               LttvHooks *hook_remover)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *module_attribute;
+  LttvAttributeType type;
+  LttvAttributeValue value;
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(module_attribute),
+                                module_name)));
+
+  /* Call the module's hook remover */
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_HOOK_REMOVER,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
+    if(hook_remover != NULL)
+      lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
+  }
+}
+
+void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
+                                        LttvTracesetContext *tsc)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *module_attribute;
+  LttvAttributeType type;
+  LttvAttributeValue value;
+  LttvHooks *before_chunk_traceset=NULL;
+  LttvHooks *before_chunk_trace=NULL;
+  LttvHooks *before_chunk_tracefile=NULL;
+  LttvHooks *event_hook=NULL;
+  LttvHooksById *event_hook_by_id=NULL;
+  LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
+
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(module_attribute),
+                                module_name)));
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_BEFORE_CHUNK_TRACESET,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_BEFORE_CHUNK_TRACE,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    before_chunk_trace = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_BEFORE_CHUNK_TRACEFILE,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_EVENT_HOOK,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    event_hook = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_EVENT_HOOK_BY_ID,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
+  }
+
+  lttv_process_traceset_begin(tsc,
+                              before_chunk_traceset,
+                              before_chunk_trace,
+                              before_chunk_tracefile,
+                              event_hook,
+                              event_hook_by_id);
+}
+
+
+
+void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
+                                       LttvTracesetContext *tsc)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *module_attribute;
+  LttvAttributeType type;
+  LttvAttributeValue value;
+  LttvHooks *after_chunk_traceset=NULL;
+  LttvHooks *after_chunk_trace=NULL;
+  LttvHooks *after_chunk_tracefile=NULL;
+  LttvHooks *event_hook=NULL;
+  LttvHooksById *event_hook_by_id=NULL;
+  LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+
+  g_assert(module_attribute =
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                LTTV_IATTRIBUTE(module_attribute),
+                                module_name)));
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_AFTER_CHUNK_TRACESET,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_AFTER_CHUNK_TRACE,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    after_chunk_trace = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_AFTER_CHUNK_TRACEFILE,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_EVENT_HOOK,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    event_hook = (LttvHooks*)*(value.v_pointer);
+  }
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                     LTTV_EVENT_HOOK_BY_ID,
+                                     &value);
+  if(type == LTTV_POINTER) {
+    event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
+  }
+  
+  lttv_process_traceset_end(tsc,
+                            after_chunk_traceset,
+                            after_chunk_trace,
+                            after_chunk_tracefile,
+                            event_hook,
+                            event_hook_by_id);
+
+}
+
+
+void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
+                                      LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+  value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
+                              LTTV_IN_PROGRESS,
+                              LTTV_INT);
+  /* the value is left unset. The only presence of the attribute is necessary.
+   */
+}
+
+void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
+                                        LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                         LTTV_IN_PROGRESS);
+}
+
+gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
+                                          LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeType type;
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_IN_PROGRESS,
+                                     &value);
+  /* The only presence of the attribute is necessary. */
+  if(type == LTTV_NONE)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+void lttvwindowtraces_set_ready(LttvAttributeName module_name,
+                                LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+  value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
+                              LTTV_READY,
+                              LTTV_INT);
+  /* the value is left unset. The only presence of the attribute is necessary.
+   */
+}
+
+void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
+                                  LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                         LTTV_READY);
+}
+
+gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
+                                    LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeType type;
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_READY,
+                                     &value);
+  /* The only presence of the attribute is necessary. */
+  if(type == LTTV_NONE)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+static gint find_window_widget(MainWindow *a, GtkWidget *b)
+{
+  if(a->mwindow == b) return 0;
+  else return -1;
+}
+
+
+/* lttvwindowtraces_process_pending_requests
+ * 
+ * This internal function gets called by g_idle, taking care of the pending
+ * requests.
+ *
+ */
+
+
+gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
+{
+  LttvTracesetContext *tsc;
+  LttvTracesetStats *tss;
+  LttvTraceset *ts;
+  //LttvTracesetContextPosition *sync_position;
+  LttvAttribute *attribute;
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  GSList **list_out, **list_in, **notify_in, **notify_out;
+  LttvAttributeValue value;
+  LttvAttributeType type;
+  gboolean ret_val;
+
+  if(trace == NULL)
+    return FALSE;
+   
+  attribute = lttv_trace_attribute(trace);
+  
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_REQUESTS_QUEUE,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  list_out = (GSList**)(value.v_pointer);
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_REQUESTS_CURRENT,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  list_in = (GSList**)(value.v_pointer);
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_NOTIFY_QUEUE,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  notify_out = (GSList**)(value.v_pointer);
+  
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_NOTIFY_CURRENT,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  notify_in = (GSList**)(value.v_pointer);
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_COMPUTATION_TRACESET,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  ts = (LttvTraceset*)*(value.v_pointer);
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_COMPUTATION_TRACESET_CONTEXT,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  tsc = (LttvTracesetContext*)*(value.v_pointer);
+  tss = (LttvTracesetStats*)*(value.v_pointer);
+  g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
+  g_assert(LTTV_IS_TRACESET_STATS(tss));
+#if 0
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_COMPUTATION_SYNC_POSITION,
+                                     &value);
+  g_assert(type == LTTV_POINTER);
+  sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
+#endif //0
+  /* There is no events requests pending : we should never have been called! */
+  g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
+  /* 0.1 Lock traces */
+  {
+    guint iter_trace=0;
+    
+    for(iter_trace=0; 
+        iter_trace<lttv_traceset_number(tsc->ts);
+        iter_trace++) {
+      LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
+
+      if(lttvwindowtraces_lock(trace_v) != 0)
+        return TRUE; /* Cannot get trace lock, try later */
+
+    }
+  }
+  /* 0.2 Sync tracefiles */
+  //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
+  lttv_process_traceset_synchronize_tracefiles(tsc);
+  /* 1. Before processing */
+  {
+    /* if list_in is empty */
+    if(g_slist_length(*list_in) == 0) {
+
+      {
+        /* - Add all requests in list_out to list_in, empty list_out */
+        GSList *iter = *list_out;
+
+        while(iter != NULL) {
+          gboolean remove = FALSE;
+          gboolean free_data = FALSE;
+
+          BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+
+          remove = TRUE;
+          free_data = FALSE;
+          *list_in = g_slist_append(*list_in, bg_req);
+
+          /* Go to next */
+          if(remove)
+          {
+            GSList *remove_iter = iter;
+
+            iter = g_slist_next(iter);
+            if(free_data) g_free(remove_iter->data);
+            *list_out = g_slist_remove_link(*list_out, remove_iter);
+          } else { // not remove
+            iter = g_slist_next(iter);
+          }
+        }
+      }
+
+      {
+        GSList *iter = *list_in;
+        /* - for each request in list_in */
+        while(iter != NULL) {
+          
+          BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+          /* - set hooks'in_progress flag to TRUE */
+          lttvwindowtraces_set_in_progress(bg_req->module_name,
+                                           bg_req->trace);
+
+          /* - call before request hook */
+          /* Get before request hook */
+          LttvAttribute *module_attribute;
+
+          g_assert(module_attribute =
+              LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                 LTTV_IATTRIBUTE(g_attribute),
+                                 LTTV_COMPUTATION)));
+
+          g_assert(module_attribute =
+              LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                        LTTV_IATTRIBUTE(module_attribute),
+                                        bg_req->module_name)));
+          
+          type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                             LTTV_BEFORE_REQUEST,
+                                             &value);
+          g_assert(type == LTTV_POINTER);
+          LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
+          if(before_request != NULL) lttv_hooks_call(before_request, tsc);
+          
+          iter = g_slist_next(iter);
+        }
+      }
+
+      /* - seek trace to start */
+      {
+        LttTime start = { 0, 0};
+        lttv_process_traceset_seek_time(tsc, start);
+      }
+
+      /* - Move all notifications from notify_out to notify_in. */
+      {
+        GSList *iter = *notify_out;
+        g_assert(g_slist_length(*notify_in) == 0);
+
+        while(iter != NULL) {
+          gboolean remove = FALSE;
+          gboolean free_data = FALSE;
+
+          BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
+
+          remove = TRUE;
+          free_data = FALSE;
+          *notify_in = g_slist_append(*notify_in, notify_req);
+
+          /* Go to next */
+          if(remove)
+          {
+            GSList *remove_iter = iter;
+
+            iter = g_slist_next(iter);
+            if(free_data) 
+                 notify_request_free((BackgroundNotify*)remove_iter->data);
+            *notify_out = g_slist_remove_link(*notify_out, remove_iter);
+          } else { // not remove
+            iter = g_slist_next(iter);
+          }
+        }
+      }
+      {
+        GSList *iter = *list_in;
+        LttvHooks *hook_adder = lttv_hooks_new();
+        /* - for each request in list_in */
+        while(iter != NULL) {
+          
+          BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+          /*- add hooks to context*/
+          lttvwindowtraces_add_computation_hooks(bg_req->module_name,
+                                                 tsc,
+                                                 hook_adder);
+          iter = g_slist_next(iter);
+        }
+        lttv_hooks_call(hook_adder,tsc);
+        lttv_hooks_destroy(hook_adder);
+      }
+
+
+    }
+
+    {
+      GSList *iter = *list_in;
+      /* - for each request in list_in */
+      while(iter != NULL) {
+        
+        BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+        /*- Call before chunk hooks for list_in*/
+        lttvwindowtraces_call_before_chunk(bg_req->module_name,
+                                               tsc);
+        iter = g_slist_next(iter);
+      }
+    }
+
+  }
+  /* 2. call process traceset middle for a chunk */
+  {
+    /*(assert list_in is not empty! : should not even be called in that case)*/
+    LttTime end = ltt_time_infinite;
+    g_assert(g_slist_length(*list_in) != 0);
+    
+    lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
+  }
+
+  /* 3. After the chunk */
+  {
+    /*  3.1 call after_chunk hooks for list_in */
+    {
+      GSList *iter = *list_in;
+      /* - for each request in list_in */
+      while(iter != NULL) {
+        
+        BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+        /* - Call after chunk hooks for list_in */
+        lttvwindowtraces_call_after_chunk(bg_req->module_name,
+                                                  tsc);
+        iter = g_slist_next(iter);
+      }
+    }
+
+    /* 3.2 for each notify_in */
+    {
+      GSList *iter = *notify_in;
+      LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
+        
+      while(iter != NULL) {
+        gboolean remove = FALSE;
+        gboolean free_data = FALSE;
+
+        BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
+
+        /* - if current time >= notify time, call notify and remove from
+         * notify_in.
+         * - if current position >= notify position, call notify and remove
+         * from notify_in.
+         */
+        if( (tfc != NULL &&
+              ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
+           ||
+            (notify_req->notify_position != NULL && 
+                     lttv_traceset_context_ctx_pos_compare(tsc,
+                              notify_req->notify_position) >= 0)
+           ) {
+
+          lttv_hooks_call(notify_req->notify, notify_req);
+
+          remove = TRUE;
+          free_data = TRUE;
+        }
+
+        /* Go to next */
+        if(remove)
+        {
+          GSList *remove_iter = iter;
+
+          iter = g_slist_next(iter);
+          if(free_data) 
+               notify_request_free((BackgroundNotify*)remove_iter->data);
+          *notify_in = g_slist_remove_link(*notify_in, remove_iter);
+        } else { // not remove
+          iter = g_slist_next(iter);
+        }
+      }
+    }
+
+    {
+      LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
+      /* 3.3 if end of trace reached */
+      if(tfc != NULL)
+        g_debug("Current time : %lu sec, %lu nsec",
+            tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
+      if(tfc == NULL || ltt_time_compare(tfc->timestamp,
+                         tsc->time_span.end_time) > 0) {
+
+        {
+          GSList *iter = *list_in;
+          LttvHooks *hook_remover = lttv_hooks_new();
+          /* - for each request in list_in */
+          while(iter != NULL) {
+            
+            BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+            /* - remove hooks from context */
+            lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
+                                                      tsc,
+                                                      hook_remover);
+            iter = g_slist_next(iter);
+          }
+          lttv_hooks_call(hook_remover,tsc);
+          lttv_hooks_destroy(hook_remover);
+        }
+          
+        /* - for each request in list_in */
+        {
+          GSList *iter = *list_in;
+          
+          while(iter != NULL) {
+            gboolean remove = FALSE;
+            gboolean free_data = FALSE;
+
+            BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+
+            /* - set hooks'in_progress flag to FALSE */
+            lttvwindowtraces_unset_in_progress(bg_req->module_name,
+                                               bg_req->trace);
+            /* - set hooks'ready flag to TRUE */
+            lttvwindowtraces_set_ready(bg_req->module_name,
+                                       bg_req->trace);
+            /* - call after request hook */
+            /* Get after request hook */
+            LttvAttribute *module_attribute;
+
+            g_assert(module_attribute =
+                LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                   LTTV_IATTRIBUTE(g_attribute),
+                                   LTTV_COMPUTATION)));
+
+            g_assert(module_attribute =
+                LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
+                                          LTTV_IATTRIBUTE(module_attribute),
+                                          bg_req->module_name)));
+            
+            type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
+                                               LTTV_AFTER_REQUEST,
+                                               &value);
+            g_assert(type == LTTV_POINTER);
+            LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
+
+            if(after_request != NULL) lttv_hooks_call(after_request, tsc);
+            
+            if(bg_req->dialog != NULL)
+              gtk_widget_destroy(bg_req->dialog);
+            GtkWidget *parent_window;
+            if(g_slist_find_custom(g_main_window_list,
+                  bg_req->parent_window,
+                  (GCompareFunc)find_window_widget))
+              parent_window = GTK_WIDGET(bg_req->parent_window);
+            else
+              parent_window = NULL;
+
+            GtkWidget *dialog = 
+              gtk_message_dialog_new(GTK_WINDOW(parent_window),
+                GTK_DIALOG_DESTROY_WITH_PARENT,
+                GTK_MESSAGE_INFO, GTK_BUTTONS_OK, 
+                "Background computation %s finished for trace %s", 
+                g_quark_to_string(bg_req->module_name),
+                g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
+            if(parent_window != NULL)
+              gtk_window_set_transient_for(GTK_WINDOW(dialog),
+                  GTK_WINDOW(parent_window));
+            g_signal_connect_swapped (dialog, "response",
+                G_CALLBACK (gtk_widget_destroy),
+                dialog);
+            gtk_widget_show(dialog);
+
+            /* - remove request */
+            remove = TRUE;
+            free_data = TRUE;
+
+            /* Go to next */
+            if(remove)
+            {
+              GSList *remove_iter = iter;
+
+              iter = g_slist_next(iter);
+              if(free_data) g_free(remove_iter->data);
+              *list_in = g_slist_remove_link(*list_in, remove_iter);
+            } else { // not remove
+              iter = g_slist_next(iter);
+            }
+          }
+        }
+
+        /* - for each notifications in notify_in */
+        {
+          GSList *iter = *notify_in;
+          
+          while(iter != NULL) {
+            gboolean remove = FALSE;
+            gboolean free_data = FALSE;
+
+            BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
+
+            /* - call notify and remove from notify_in */
+            lttv_hooks_call(notify_req->notify, notify_req);
+            remove = TRUE;
+            free_data = TRUE;
+
+            /* Go to next */
+            if(remove)
+            {
+              GSList *remove_iter = iter;
+
+              iter = g_slist_next(iter);
+              if(free_data) 
+                    notify_request_free((BackgroundNotify*)remove_iter->data);
+              *notify_in = g_slist_remove_link(*notify_in, remove_iter);
+            } else { // not remove
+              iter = g_slist_next(iter);
+            }
+          }
+        }
+        {
+          /* - reset the context */
+          LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
+          LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
+        }
+        /* - if list_out is empty */
+        if(g_slist_length(*list_out) == 0) {
+          /* - return FALSE (scheduler stopped) */
+          g_debug("Background computation scheduler stopped");
+          g_info("Background computation finished for trace %p", trace);
+          /* FIXME : remove status bar info, need context id and message id */
+
+          ret_val = FALSE;
+        } else {
+          ret_val = TRUE;
+        }
+      } else {
+        /* 3.4 else, end of trace not reached */
+        /* - return TRUE (scheduler still registered) */
+        g_debug("Background computation left");
+        ret_val = TRUE;
+      }
+    }
+  }
+  /* 4. Unlock traces */
+  {
+    lttv_process_traceset_get_sync_data(tsc);
+    //lttv_traceset_context_position_save(tsc, sync_position);
+    guint iter_trace;
+    
+    for(iter_trace=0; 
+        iter_trace<lttv_traceset_number(tsc->ts);
+        iter_trace++) {
+      LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
+
+      lttvwindowtraces_unlock(trace_v);
+    }
+  }
+  return ret_val;
+}
+
+
+
+/**
+ * Register the background computation hooks for a specific module. It adds the
+ * computation hooks to the global attrubutes, under "computation/module name".
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ */
+void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
+                                          LttvHooks *before_chunk_traceset,
+                                          LttvHooks *before_chunk_trace,
+                                          LttvHooks *before_chunk_tracefile,
+                                          LttvHooks *after_chunk_traceset,
+                                          LttvHooks *after_chunk_trace,
+                                          LttvHooks *after_chunk_tracefile,
+                                          LttvHooks *before_request,
+                                          LttvHooks *after_request,
+                                          LttvHooks *event_hook,
+                                          LttvHooksById *event_hook_by_id,
+                                          LttvHooks *hook_adder,
+                                          LttvHooks *hook_remover)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *attribute;
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_CHUNK_TRACESET,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = before_chunk_traceset;
+  
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_CHUNK_TRACE,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = before_chunk_trace;
+  
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_CHUNK_TRACEFILE,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = before_chunk_tracefile;
+  
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_CHUNK_TRACESET,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = after_chunk_traceset;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_CHUNK_TRACE,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = after_chunk_trace;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_CHUNK_TRACEFILE,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = after_chunk_tracefile;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_REQUEST,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = before_request;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_REQUEST,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = after_request;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_EVENT_HOOK,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = event_hook;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_EVENT_HOOK_BY_ID,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = event_hook_by_id;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_HOOK_ADDER,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = hook_adder;
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_HOOK_REMOVER,
+                                LTTV_POINTER,
+                                &value));
+  *(value.v_pointer) = hook_remover;
+
+}
+
+
+/**
+ * It removes all the requests than can be currently processed by the
+ * background computation algorithm for all the traces (list_in and list_out).
+ *
+ * Leaves the flag to in_progress or none.. depending if current or queue
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ */
+void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
+{
+  guint i;
+
+  for(i=0;i<lttvwindowtraces_get_number();i++) {
+    LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
+    g_assert(trace_v != NULL);
+    LttTrace *trace;
+    LttvAttribute *attribute = lttv_trace_attribute(trace_v);
+    LttvAttributeValue value;
+    GSList **queue, **current;
+    GSList *iter;
+    
+    g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                  LTTV_REQUESTS_QUEUE,
+                                  LTTV_POINTER,
+                                  &value));
+    queue = (GSList**)(value.v_pointer);
+    
+    iter = *queue;
+    while(iter != NULL) {
+      gboolean remove = FALSE;
+      gboolean free_data = FALSE;
+
+      BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+
+      if(bg_req->module_name == module_name) {
+        remove = TRUE;
+        free_data = TRUE;
+      }
+
+      /* Go to next */
+      if(remove)
+      {
+        GSList *remove_iter = iter;
+
+        iter = g_slist_next(iter);
+        if(free_data) g_free(remove_iter->data);
+        *queue = g_slist_remove_link(*queue, remove_iter);
+      } else { // not remove
+        iter = g_slist_next(iter);
+      }
+    }
+    
+        
+    g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                  LTTV_REQUESTS_CURRENT,
+                                  LTTV_POINTER,
+                                  &value));
+    current = (GSList**)(value.v_pointer);
+    
+    iter = *current;
+    while(iter != NULL) {
+      gboolean remove = FALSE;
+      gboolean free_data = FALSE;
+
+      BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+
+      if(bg_req->module_name == module_name) {
+        remove = TRUE;
+        free_data = TRUE;
+      }
+
+      /* Go to next */
+      if(remove)
+      {
+        GSList *remove_iter = iter;
+
+        iter = g_slist_next(iter);
+        if(free_data) g_free(remove_iter->data);
+        *current = g_slist_remove_link(*current, remove_iter);
+      } else { // not remove
+        iter = g_slist_next(iter);
+      }
+    }
+  }
+}
+
+
+/**
+ * Unregister the background computation hooks for a specific module.
+ *
+ * It also removes all the requests than can be currently processed by the
+ * background computation algorithm for all the traces (list_in and list_out).
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ */
+
+void lttvwindowtraces_unregister_computation_hooks
+                                     (LttvAttributeName module_name)
+{
+  LttvAttribute *g_attribute = lttv_global_attributes();
+  LttvAttribute *attribute;
+  LttvAttributeValue value;
+
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+                                module_name)));
+
+
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_CHUNK_TRACESET,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
+  if(before_chunk_traceset != NULL)
+    lttv_hooks_destroy(before_chunk_traceset);
+  
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_CHUNK_TRACE,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
+  if(before_chunk_trace != NULL)
+    lttv_hooks_destroy(before_chunk_trace);
+  
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_CHUNK_TRACEFILE,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
+  if(before_chunk_tracefile != NULL)
+    lttv_hooks_destroy(before_chunk_tracefile);
+  
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_CHUNK_TRACESET,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
+  if(after_chunk_traceset != NULL)
+    lttv_hooks_destroy(after_chunk_traceset);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_CHUNK_TRACE,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
+  if(after_chunk_trace != NULL)
+    lttv_hooks_destroy(after_chunk_trace);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_CHUNK_TRACEFILE,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
+  if(after_chunk_tracefile != NULL)
+    lttv_hooks_destroy(after_chunk_tracefile);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_BEFORE_REQUEST,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
+  if(before_request != NULL)
+    lttv_hooks_destroy(before_request);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_AFTER_REQUEST,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
+  if(after_request != NULL)
+    lttv_hooks_destroy(after_request);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_EVENT_HOOK,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
+  if(event_hook != NULL)
+    lttv_hooks_destroy(event_hook);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_EVENT_HOOK_BY_ID,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
+  if(event_hook_by_id != NULL)
+    lttv_hooks_by_id_destroy(event_hook_by_id);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_HOOK_ADDER,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
+  if(hook_adder != NULL)
+    lttv_hooks_destroy(hook_adder);
+  g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+                                LTTV_HOOK_REMOVER,
+                                LTTV_POINTER,
+                                &value));
+  LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
+  if(hook_remover != NULL)
+    lttv_hooks_destroy(hook_remover);
+
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_EVENT_HOOK_BY_ID);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_EVENT_HOOK);
+
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_AFTER_REQUEST);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_BEFORE_REQUEST);
+
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_AFTER_CHUNK_TRACEFILE);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_AFTER_CHUNK_TRACE);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_AFTER_CHUNK_TRACESET);
+
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_BEFORE_CHUNK_TRACEFILE);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_BEFORE_CHUNK_TRACE);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_BEFORE_CHUNK_TRACESET);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_HOOK_ADDER);
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_HOOK_REMOVER);
+
+  /* finally, remove module name */
+  g_assert(attribute = 
+      LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+                                LTTV_COMPUTATION)));
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                                     module_name);
+
+}
+
+/**
+ * Lock a trace so no other instance can use it.
+ *
+ * @param trace The trace to lock.
+ * @return 0 on success, -1 if cannot get lock.
+ */
+gint lttvwindowtraces_lock(LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeValue value;
+  LttvAttributeType type;
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_LOCK,
+                                     &value);
+  /* Verify the absence of the lock. */
+  if(type != LTTV_NONE) {
+    g_critical("Cannot take trace lock");
+    return -1;
+  }
+
+  value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
+                              LTTV_LOCK,
+                              LTTV_INT);
+  /* the value is left unset. The only presence of the attribute is necessary.
+   */
+
+  return 0;
+}
+
+/**
+ * Unlock a trace.
+ *
+ * @param trace The trace to unlock.
+ * @return 0 on success, -1 if cannot unlock (not locked ?).
+ */
+gint lttvwindowtraces_unlock(LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeType type;
+  LttvAttributeValue value;
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_LOCK,
+                                     &value);
+  /* Verify the presence of the lock. */
+  if(type == LTTV_NONE) {
+    g_critical("Cannot release trace lock");
+    return -1;
+  }
+
+  lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+                         LTTV_LOCK);
+
+  return 0;
+}
+
+/**
+ * Verify if a trace is locked.
+ *
+ * @param trace The trace to verify.
+ * @return TRUE if locked, FALSE is unlocked.
+ */
+gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
+{
+  LttvAttribute *attribute = lttv_trace_attribute(trace);
+  LttvAttributeType type;
+  LttvAttributeValue value;
+
+  type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
+                                     LTTV_LOCK,
+                                     &value);
+  /* The only presence of the attribute is necessary. */
+  if(type == LTTV_NONE)
+    return FALSE;
+  else
+    return TRUE;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.h
new file mode 100644 (file)
index 0000000..2345030
--- /dev/null
@@ -0,0 +1,321 @@
+/* This file is part of the Linux Trace Toolkit Graphic User Interface
+ * Copyright (C) 2003-2004 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* This file is the API used to launch any background computation on a trace */
+
+/* lttvwindowtraces
+ *
+ * This API consists in two main parts. The first one is for the background
+ * computation provider and the second is for the viewer which needs this
+ * information.
+ *
+ * A computation provider, i.e. a statistics computation module or a state
+ * computation module, have two things in common : they append data to a trace
+ * in an extensible container (LttvAttributes). This extended information, once
+ * computed, can be kept all along with the trace and does not need to be
+ * recomputed : a computation done on a trace must result in a identical result
+ * each time it is done.
+ *
+ * This API provides functions for computation provider to register their
+ * computation functions (or computation functions insertion and removal
+ * functions). Once the computation provider is registered with its module name,
+ * extended computation for a trace can be requested by any viewer by specifying
+ * the module name, as we will describe in a moment.
+ *
+ * A viewer which needs extended information about a trace must ask for it to be
+ * computed by doing a background computation request. It may also ask to be
+ * notified of the completion of its request by doing a notify request.
+ *
+ * Before asking for the computation, it must check for its readiness. If it is
+ * ready, the information has already been computed, so it is ready to use. If
+ * the information is not ready, in must check whether or not the processing of
+ * this task is in progress. If it is, it must not do any background computation
+ * request. It must only do a background notification request of the current
+ * processing to be informed of its completion. If the information is not ready
+ * and not being processed, then the viewer may do a background computation
+ * request and add a notify request to the notify queue.
+ *
+ * When a context takes control of a trace, it must lock the trace. This is a
+ * way of ensuring that not conflict will occur between two traceset contexts
+ * and shared traces. It will generate an error if a context try to get a lock
+ * on a trace what is not unlocked. Upon every trace locking,
+ * lttv_process_traceset_synchronize_tracefiles should be used to resynchronize
+ * the traces with the trace context information.
+ *
+ * The usefulness of the lock in this framework can be questionable in a
+ * single threaded environment, but can be great in the eventuality of
+ * multiple threads.
+ * 
+ */
+
+
+
+#ifndef LTTVWINDOWTRACES_H
+#define LTTVWINDOWTRACES_H
+
+#include <ltt/time.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+typedef GQuark LttvTraceInfo;
+
+extern LttvTraceInfo LTTV_TRACES,
+              LTTV_COMPUTATION,
+              LTTV_REQUESTS_QUEUE,
+              LTTV_REQUESTS_CURRENT,
+              LTTV_NOTIFY_QUEUE,
+              LTTV_NOTIFY_CURRENT,
+              LTTV_COMPUTATION_TRACESET,
+              LTTV_COMPUTATION_TRACESET_CONTEXT,
+              LTTV_COMPUTATION_SYNC_POSITION,
+              LTTV_BEFORE_CHUNK_TRACESET,
+              LTTV_BEFORE_CHUNK_TRACE,
+              LTTV_BEFORE_CHUNK_TRACEFILE,
+              LTTV_AFTER_CHUNK_TRACESET,
+              LTTV_AFTER_CHUNK_TRACE,
+              LTTV_AFTER_CHUNK_TRACEFILE,
+              LTTV_BEFORE_REQUEST,
+              LTTV_AFTER_REQUEST,
+              LTTV_EVENT_HOOK,
+              LTTV_EVENT_HOOK_BY_ID,
+              LTTV_HOOK_ADDER,
+              LTTV_HOOK_REMOVER,
+              LTTV_IN_PROGRESS,
+              LTTV_READY,
+              LTTV_LOCK;
+              
+
+
+/* Get a trace by its path name. 
+ *
+ * @param path path of the trace on the virtual file system.
+ * @return Pointer to trace if found
+ *        NULL is returned if the trace is not present
+ */
+
+LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path);
+
+/* Get a trace by its number identifier */
+
+LttvTrace *lttvwindowtraces_get_trace(guint num);
+
+/* Total number of traces */
+
+guint lttvwindowtraces_get_number();
+
+/* Add a trace to the global attributes */
+
+void lttvwindowtraces_add_trace(LttvTrace *trace);
+
+/* Remove a trace from the global attributes */
+
+void lttvwindowtraces_remove_trace(LttvTrace *trace);
+
+
+/**
+ * Function to request data from a specific trace
+ *
+ * The memory allocated for the request will be managed by the API.
+ * 
+ * @param tab parent Window
+ * @param trace the trace to compute
+ * @param module_name the name of the module which registered global computation
+ *                    hooks.
+ */
+
+void lttvwindowtraces_background_request_queue
+                     (GtkWidget *widget, LttvTrace *trace, gchar *module_name);
+
+/**
+ * Remove a background request from a trace.
+ *
+ * This should ONLY be used by the modules which registered the global hooks
+ * (module_name). If this is called by the viewers, it may lead to incomplete
+ * and incoherent background processing information.
+ *
+ * Even if the module which deals with the hooks removes the background
+ * requests, it may cause a problem if the module gets loaded again in the
+ * session : the data will be partially calculated. The calculation function
+ * must deal with this case correctly.
+ * 
+ * @param trace the trace to compute
+ * @param module_name the name of the module which registered global computation
+ *                    hooks.
+ */
+
+void lttvwindowtraces_background_request_remove
+                     (LttvTrace *trace, gchar *module_name);
+                     
+
+                     
+/**
+ * Find a background request in a trace
+ *
+ */
+
+gboolean lttvwindowtraces_background_request_find
+                     (LttvTrace *trace, gchar *module_name);
+                     
+/**
+ * Register a callback to be called when requested data is passed in the next
+ * queued background processing.
+ * 
+ * @param owner owner of the background notification
+ * @param trace the trace computed
+ * @param notify_time time when notification hooks must be called
+ * @param notify_position position when notification hooks must be called
+ * @param notify  Hook to call when the notify position is passed
+ */
+
+void lttvwindowtraces_background_notify_queue
+ (gpointer                     owner,
+  LttvTrace                   *trace,
+  LttTime                      notify_time,
+  const LttvTracesetContextPosition *notify_position,
+  const LttvHooks                   *notify);
+
+/**
+ * Register a callback to be called when requested data is passed in the current
+ * background processing.
+ * 
+ * @param owner owner of the background notification
+ * @param trace the trace computed
+ * @param notify_time time when notification hooks must be called
+ * @param notify_position position when notification hooks must be called
+ * @param notify  Hook to call when the notify position is passed
+ */
+
+void lttvwindowtraces_background_notify_current
+ (gpointer                     owner,
+  LttvTrace                   *trace,
+  LttTime                      notify_time,
+  const LttvTracesetContextPosition *notify_position,
+  const LttvHooks                   *notify);
+
+/**
+ * Removes all the notifications requests from a specific viewer.
+ * 
+ * @param owner owner of the background notification
+ */
+
+void lttvwindowtraces_background_notify_remove(gpointer owner);
+
+
+/**
+ * Tells if the information computed by a module for a trace is ready.
+ *
+ * Must be checked before a background processing request.
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ * @param trace The trace for which the information is verified.
+ */
+
+gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
+                                    LttvTrace *trace);
+
+/**
+ * Tells if the information computed by a module for a trace is being processed.
+ * 
+ * Must be checked before a background processing request.
+ *
+ * If it is effectively processed, the typical thing to do is to call
+ * lttvwindowtraces_background_notify_current to be notified when the current
+ * processing will be over.
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ * @param trace The trace for which the information is verified.
+ */
+
+gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
+                                    LttvTrace *trace);
+
+/**
+ * Register the background computation hooks for a specific module. It adds the
+ * computation hooks to the global attrubutes, under "computation/module name"
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ */
+void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
+                                          LttvHooks *before_chunk_traceset,
+                                          LttvHooks *before_chunk_trace,
+                                          LttvHooks *before_chunk_tracefile,
+                                          LttvHooks *after_chunk_traceset,
+                                          LttvHooks *after_chunk_trace,
+                                          LttvHooks *after_chunk_tracefile,
+                                          LttvHooks *before_request,
+                                          LttvHooks *after_request,
+                                          LttvHooks *event_hook,
+                                          LttvHooksById *event_hook_by_id,
+                                          LttvHooks *hook_adder,
+                                          LttvHooks *hook_remover);
+/**
+ * Unregister the background computation hooks for a specific module.
+ *
+ * It also removes all the requests than can be currently processed by the
+ * background computation algorithm for all the traces (list_in and list_out).
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ */
+
+void lttvwindowtraces_unregister_computation_hooks
+                                     (LttvAttributeName module_name);
+
+
+/**
+ * It removes all the requests than can be currently processed by the
+ * background computation algorithm for all the traces (list_in and list_out).
+ *
+ * Leaves the flag to in_progress or none.. depending if current or queue
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ *                    information.
+ */
+void lttvwindowtraces_unregister_requests(LttvAttributeName module_name);
+
+
+/**
+ * Lock a trace so no other instance can use it.
+ *
+ * @param trace The trace to lock.
+ * @return 0 on success, -1 if cannot get lock.
+ */
+gint lttvwindowtraces_lock(LttvTrace *trace);
+
+
+/**
+ * Unlock a trace.
+ *
+ * @param trace The trace to unlock.
+ * @return 0 on success, -1 if cannot unlock (not locked ?).
+ */
+gint lttvwindowtraces_unlock(LttvTrace *trace);
+
+/**
+ * Verify if a trace is locked.
+ *
+ * @param trace The trace to verify.
+ * @return TRUE if locked, FALSE is unlocked.
+ */
+gint lttvwindowtraces_get_lock_state(LttvTrace *trace);
+
+
+#endif //LTTVWINDOWTRACES_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow-private.h
new file mode 100644 (file)
index 0000000..4c72216
--- /dev/null
@@ -0,0 +1,134 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef _MAIN_WINDOW_PRIVATE_
+#define _MAIN_WINDOW_PRIVATE_
+
+#include <gtk/gtk.h>
+
+#include <ltt/ltt.h>
+#include <lttv/attribute.h>
+#include <lttv/traceset.h>
+#include <lttv/tracecontext.h>
+#include <lttv/hook.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+//#include <lttvwindow/gtkmultivpaned.h>
+#include <lttvwindow/mainwindow.h>
+
+#define SCROLL_STEP_PER_PAGE 10.0
+
+struct _TracesetInfo {
+  //FIXME? TracesetContext and stats in same or different variable ?
+  LttvTracesetStats * traceset_context;
+  LttvTraceset * traceset;
+};
+
+struct _MainWindow{
+  GtkWidget*      mwindow;            /* Main Window */
+  int             window_width;
+
+  /* Status bar information */
+  //  guint         MainSBarContextID;    /* Context ID of main status bar */
+  //  guint         BegTimeSBarContextID; /* Context ID of BegTime status bar */
+  //  guint         EndTimeSBarContextID; /* Context ID of EndTime status bar */
+  
+  /* Child windows */
+  //openTracesetWindow*  OpenTracesetWindow;/* Window to get prof and proc file*/
+  //viewTimeFrameWindow* ViewTimeFrameWindow;/*Window to select time frame */
+  //gotoEventWindow*     GotoEventWindow; /*search for event description*/
+  //openFilterWindow*    OpenFilterWindow; /* Open a filter selection window */
+  GtkWidget*           help_contents;/* Window to display help contents */
+  GtkWidget*           about_box;    /* Window  about information */
+  //  lttv_trace_filter * filter; /* trace filter associated with the window */
+
+  /* Attributes for trace reading hooks local to the main window */
+  LttvIAttribute * attributes;
+  
+  //Tab * tab;
+  //Tab * current_tab;
+
+};
+
+
+struct _Tab{
+  GtkWidget *label;
+  
+  GtkWidget *vbox; /* contains viewer_container and scrollbar */
+  //GtkWidget *multivpaned;
+  GtkWidget *viewer_container;
+  GtkWidget *scrollbar;
+
+  /* Paste zones */
+  GtkTooltips *tooltips;
+  
+  /* time bar */
+  GtkWidget *MTimebar;
+  GtkWidget *MEventBox1a;
+  GtkWidget *MText1a;
+  GtkWidget *MEventBox1b;
+  GtkWidget *MText1b;
+  GtkWidget *MEntry1;
+  GtkWidget *MText2;
+  GtkWidget *MEntry2;
+  GtkWidget *MText3a;
+  GtkWidget *MEventBox3b;
+  GtkWidget *MText3b;
+  GtkWidget *MEntry3;
+  GtkWidget *MText4;
+  GtkWidget *MEntry4;
+  GtkWidget *MText5a;
+  GtkWidget *MEventBox5b;
+  GtkWidget *MText5b;
+  GtkWidget *MEntry5;
+  GtkWidget *MText6;
+  GtkWidget *MEntry6;
+  GtkWidget *MText7;
+   
+  // startTime is the left of the visible area. Corresponds to the scrollbar
+  // value.
+  // Time_Width is a zoom dependant value (corresponding to page size)
+  TimeWindow time_window;
+  gboolean time_manager_lock;
+  
+  // The current time is the time selected in the visible area by the user,
+  // not the scrollbar value.
+  LttTime current_time;
+  gboolean current_time_manager_lock;
+
+  LttvIAttribute * attributes;
+
+  //struct _Tab * next;
+  MainWindow  * mw;
+
+  /* Traceset related information */
+  TracesetInfo * traceset_info; 
+
+  /* Filter to apply to the tab's traceset */
+  LttvFilter *filter;
+
+  /* A list of time requested for the next process trace */
+  GSList *events_requests;
+  gboolean events_request_pending;
+  LttvAttribute *interrupted_state;
+};
+
+#endif /* _MAIN_WINDOW_PRIVATE_ */
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/mainwindow.h
new file mode 100644 (file)
index 0000000..9874d0d
--- /dev/null
@@ -0,0 +1,41 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef _MAIN_WINDOW_
+#define _MAIN_WINDOW_
+
+#include <glib.h>
+#include <ltt/time.h>
+
+typedef struct _MainWindow MainWindow;
+typedef struct _TimeWindow TimeWindow;
+typedef struct _Tab Tab;
+typedef struct _TracesetInfo TracesetInfo;
+
+struct _TimeWindow {
+       LttTime start_time;
+       LttTime time_width;
+  double time_width_double;
+       LttTime end_time;
+}; 
+
+
+
+#endif /* _MAIN_WINDOW_ */
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/menu.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/menu.c
new file mode 100644 (file)
index 0000000..5235aca
--- /dev/null
@@ -0,0 +1,79 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttvwindow/menu.h>
+
+
+LttvMenus *lttv_menus_new() {
+  return g_array_new(FALSE, FALSE, sizeof(LttvMenuClosure));
+}
+
+/* MD: delete elements of the array also, but don't free pointed addresses
+ * (functions).
+ */
+void lttv_menus_destroy(LttvMenus *h) {
+  g_debug("lttv_menus_destroy()");
+  g_array_free(h, TRUE);
+}
+
+LttvMenuClosure lttv_menus_add(LttvMenus *h,
+    lttvwindow_viewer_constructor f,
+    char* menu_path, char* menu_text, GtkWidget *widget)
+{
+  LttvMenuClosure c;
+
+  c.con = f;
+  c.menu_path = menu_path;
+  c.menu_text = menu_text;
+  c.widget = widget;
+  if(h != NULL) g_array_append_val(h,c);
+
+  return c;
+}
+
+GtkWidget *lttv_menus_remove(LttvMenus *h, lttvwindow_viewer_constructor f)
+{
+  LttvMenuClosure * tmp;
+  guint i;
+  GtkWidget *widget;
+  
+  for(i=0;i<h->len;i++){
+    tmp = & g_array_index(h, LttvMenuClosure, i);
+    if(tmp->con == f) {
+      widget = tmp->widget;
+      break;
+    }
+  }
+  if(i<h->len){
+    g_array_remove_index(h, i);
+    return widget;
+  }else return NULL;
+  
+}
+
+unsigned lttv_menus_number(LttvMenus *h)
+{
+  return h->len;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/menu.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/menu.h
new file mode 100644 (file)
index 0000000..87ccdee
--- /dev/null
@@ -0,0 +1,46 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef MENU_H
+#define MENU_H
+
+#include <gtk/gtk.h>
+#include <lttvwindow/lttvwindow.h>
+
+
+typedef GArray LttvMenus;
+
+typedef struct _LttvMenuClosure {
+  lttvwindow_viewer_constructor con;
+  char * menu_path;
+  char * menu_text;
+  GtkWidget *widget;
+} LttvMenuClosure;
+
+
+LttvMenus *lttv_menus_new();
+
+void lttv_menus_destroy(LttvMenus *h);
+
+LttvMenuClosure lttv_menus_add(LttvMenus *h, lttvwindow_viewer_constructor f, char* menuPath, char * menuText, GtkWidget *widget);
+
+GtkWidget *lttv_menus_remove(LttvMenus *h, lttvwindow_viewer_constructor f);
+
+unsigned lttv_menus_number(LttvMenus *h);
+
+#endif // MENU_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/support.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/support.c
new file mode 100644 (file)
index 0000000..fddd4cf
--- /dev/null
@@ -0,0 +1,162 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+
+#include "support.h"
+
+GtkWidget*
+lookup_widget                          (GtkWidget       *widget,
+                                        const gchar     *widget_name)
+{
+  GtkWidget *parent, *found_widget;
+
+  for (;;)
+    {
+      if (GTK_IS_MENU (widget))
+        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+      else
+        parent = widget->parent;
+      if (!parent)
+        parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
+      if (parent == NULL)
+        break;
+      widget = parent;
+    }
+
+  found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
+                                                 widget_name);
+  if (!found_widget)
+    g_warning ("Widget not found: %s", widget_name);
+  return found_widget;
+}
+
+static GList *pixmaps_directories = NULL;
+
+/* Use this function to set the directory containing installed pixmaps. */
+void
+add_pixmap_directory                   (const gchar     *directory)
+{
+  pixmaps_directories = g_list_prepend (pixmaps_directories,
+                                        g_strdup (directory));
+}
+
+/* This is an internally used function to find pixmap files. */
+static gchar*
+find_pixmap_file                       (const gchar     *filename)
+{
+  GList *elem;
+
+  /* We step through each of the pixmaps directory to find it. */
+  elem = pixmaps_directories;
+  while (elem)
+    {
+      gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
+                                         G_DIR_SEPARATOR_S, filename);
+      if (g_file_test (pathname, G_FILE_TEST_EXISTS))
+        return pathname;
+      g_free (pathname);
+      elem = elem->next;
+    }
+  return NULL;
+}
+
+/* This is an internally used function to create pixmaps. */
+GtkWidget*
+create_pixmap                          (GtkWidget       *widget,
+                                        const gchar     *filename)
+{
+  gchar *pathname = NULL;
+  GtkWidget *pixmap;
+
+  if (!filename || !filename[0])
+      return gtk_image_new ();
+
+  pathname = find_pixmap_file (filename);
+
+  if (!pathname)
+    {
+      g_warning ("Couldn't find pixmap file: %s", filename);
+      return gtk_image_new ();
+    }
+
+  pixmap = gtk_image_new_from_file (pathname);
+  g_free (pathname);
+  return pixmap;
+}
+
+/* This is an internally used function to create pixmaps. */
+GdkPixbuf*
+create_pixbuf                          (const gchar     *filename)
+{
+  gchar *pathname = NULL;
+  GdkPixbuf *pixbuf;
+  GError *error = NULL;
+
+  if (!filename || !filename[0])
+      return NULL;
+
+  pathname = find_pixmap_file (filename);
+
+  if (!pathname)
+    {
+      g_warning ("Couldn't find pixmap file: %s", filename);
+      return NULL;
+    }
+
+  pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
+  if (!pixbuf)
+    {
+      fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
+               pathname, error->message);
+      g_error_free (error);
+    }
+  g_free (pathname);
+  return pixbuf;
+}
+
+/* This is used to set ATK action descriptions. */
+void
+glade_set_atk_action_description       (AtkAction       *action,
+                                        const gchar     *action_name,
+                                        const gchar     *description)
+{
+  gint n_actions, i;
+
+  n_actions = atk_action_get_n_actions (action);
+  for (i = 0; i < n_actions; i++)
+    {
+      if (!strcmp (atk_action_get_name (action, i), action_name))
+        atk_action_set_description (action, i, description);
+    }
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/support.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/support.h
new file mode 100644 (file)
index 0000000..6297519
--- /dev/null
@@ -0,0 +1,62 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+/*
+ * Public Functions.
+ */
+
+/*
+ * This function returns a widget in a component created by Glade.
+ * Call it with the toplevel widget in the component (i.e. a window/dialog),
+ * or alternatively any widget in the component, and the name of the widget
+ * you want returned.
+ */
+GtkWidget*  lookup_widget              (GtkWidget       *widget,
+                                        const gchar     *widget_name);
+
+
+/* Use this function to set the directory containing installed pixmaps. */
+void        add_pixmap_directory       (const gchar     *directory);
+
+
+/*
+ * Private Functions.
+ */
+
+/* This is used to create the pixmaps used in the interface. */
+GtkWidget*  create_pixmap              (GtkWidget       *widget,
+                                        const gchar     *filename);
+
+/* This is used to create the pixbufs used in the interface. */
+GdkPixbuf*  create_pixbuf              (const gchar     *filename);
+
+/* This is used to set ATK action descriptions. */
+void        glade_set_atk_action_description (AtkAction       *action,
+                                              const gchar     *action_name,
+                                              const gchar     *description);
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/test_main.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/test_main.c
new file mode 100644 (file)
index 0000000..02ea36c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Initial main.c file generated by Glade. Edit as required.
+ * Glade will not overwrite this file.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gmodule.h>
+
+#include "interface.h"
+#include "support.h"
+#include <lttvwindow/mainWindow.h>
+#include "callbacks.h"
+
+/* global variable */
+systemView * gSysView;
+
+typedef void (*call_Event_Selected_Hook)(void * call_data);
+call_Event_Selected_Hook selected_hook = NULL;
+GModule *gm;
+view_constructor gConstructor = NULL;
+
+int
+main (int argc, char *argv[])
+{
+  GModule *gm;
+  GtkWidget * ToolMenuTitle_menu, *insert_view;
+  GtkWidget *window1;
+  mainWindow * mw = g_new(mainWindow, 1);
+  gSysView = g_new(systemView, 1);
+
+#ifdef ENABLE_NLS
+  bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  textdomain (GETTEXT_PACKAGE);
+#endif
+
+  gtk_set_locale ();
+  gtk_init (&argc, &argv);
+
+  add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
+  add_pixmap_directory ("pixmaps");
+  add_pixmap_directory ("../pixmaps");
+
+  /*
+   * The following code was added by Glade to create one of each component
+   * (except popup menus), just so that you see something after building
+   * the project. Delete any components that you don't want shown initially.
+   */
+  window1 = create_MWindow ();
+  gtk_widget_show (window1);
+
+  mw->MWindow = window1;
+  mw->SystemView = gSysView;
+  mw->Tab = NULL;
+  mw->CurrentTab = NULL;
+  //  mw->Attributes = lttv_attributes_new();
+
+  //test
+
+  gm = g_module_open("/home1/yangxx/poly/lttv/modules/libguiEvents.la",0);
+  printf("Main : the address of gm : %d\n", gm);
+  if(!g_module_symbol(gm, "get_constructor", (gpointer)&get_constructor)){
+    g_error("can not get constructor\n");
+  }  
+  if(!g_module_symbol(gm, "call_Event_Selected_Hook", (gpointer)&selected_hook)){
+    g_error("can not get selected hook\n");
+  }  
+
+  gConstructor = get_constructor();
+  ToolMenuTitle_menu = lookup_widget(mw->MWindow,"ToolMenuTitle_menu");
+  insert_view = gtk_menu_item_new_with_mnemonic ("insert_view");
+  gtk_widget_show (insert_view);
+  gtk_container_add (GTK_CONTAINER (ToolMenuTitle_menu), insert_view);
+  g_signal_connect ((gpointer) insert_view, "activate",
+                    G_CALLBACK (insertViewTest),
+                    NULL);  
+  //end
+
+  gSysView->EventDB = NULL;
+  gSysView->SystemInfo = NULL;
+  gSysView->Options  = NULL;
+  gSysView->Window = mw;
+  gSysView->Next = NULL;
+
+  g_object_set_data(G_OBJECT(window1), "systemView", (gpointer)gSysView);
+  g_object_set_data(G_OBJECT(window1), "mainWindow", (gpointer)mw);
+
+  gtk_main ();
+  return 0;
+}
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.c
new file mode 100644 (file)
index 0000000..a01986d
--- /dev/null
@@ -0,0 +1,77 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttvwindow/toolbar.h>
+
+LttvToolbars *lttv_toolbars_new() {
+  return g_array_new(FALSE, FALSE, sizeof(LttvToolbarClosure));
+}
+
+/* MD: delete elements of the array also, but don't free pointed addresses
+ * (functions).
+ */
+void lttv_toolbars_destroy(LttvToolbars *h) {
+  g_debug("lttv_toolbars_destroy");
+  g_array_free(h, TRUE);
+}
+
+LttvToolbarClosure lttv_toolbars_add(LttvToolbars *h,
+    lttvwindow_viewer_constructor f,
+    char* tooltip, char ** pixmap, GtkWidget *widget)
+{
+  LttvToolbarClosure c;
+
+  c.con = f;
+  c.tooltip = tooltip;
+  c.pixmap = pixmap;
+  c.widget = widget;
+  if(h != NULL) g_array_append_val(h,c);
+
+  return c;
+}
+
+GtkWidget *lttv_toolbars_remove(LttvToolbars *h, lttvwindow_viewer_constructor f)
+{
+  LttvToolbarClosure * tmp;
+  guint i;
+  GtkWidget *widget;
+
+  for(i=0;i<h->len;i++){
+    tmp = & g_array_index(h, LttvToolbarClosure, i);
+    if(tmp->con == f) {
+      widget = tmp->widget;
+      break;
+    }
+  }
+  if(i<h->len){
+    g_array_remove_index(h, i);
+    return widget;
+  }else return NULL;
+}
+
+unsigned lttv_toolbars_number(LttvToolbars *h)
+{
+  return h->len;
+}
+
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/lttvwindow/toolbar.h
new file mode 100644 (file)
index 0000000..2fb4b39
--- /dev/null
@@ -0,0 +1,48 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Xiangxiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef TOOLBAR_H
+#define TOOLBAR_H
+
+#include <lttvwindow/lttvwindow.h>
+#include <gtk/gtk.h>
+
+typedef GArray LttvToolbars;
+
+typedef struct _LttvToolbarClosure {
+  lttvwindow_viewer_constructor con;
+  char * tooltip;
+  char ** pixmap;
+  GtkWidget *widget;
+} LttvToolbarClosure;
+
+LttvToolbars *lttv_toolbars_new();
+
+void lttv_toolbars_destroy(LttvToolbars *h);
+
+LttvToolbarClosure lttv_toolbars_add(LttvToolbars *h,
+                       lttvwindow_viewer_constructor f,
+                       char* tooltip,
+                       char ** pixmap,
+                       GtkWidget *widget);
+
+GtkWidget *lttv_toolbars_remove(LttvToolbars *h, lttvwindow_viewer_constructor f);
+
+unsigned lttv_toolbars_number(LttvToolbars *h);
+
+#endif // TOOLBAR_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/mainwin.glade b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/mainwin.glade
new file mode 100644 (file)
index 0000000..0d4cd97
--- /dev/null
@@ -0,0 +1,760 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="MWindow">
+  <property name="width_request">100</property>
+  <property name="height_request">50</property>
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Main window</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">600</property>
+  <property name="default_height">400</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <signal name="destroy" handler="on_MWindow_destroy" last_modification_time="Tue, 10 Jun 2003 16:31:35 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="MVbox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+       <widget class="GtkHBox" id="MMenuBox">
+         <property name="visible">True</property>
+         <property name="homogeneous">False</property>
+         <property name="spacing">0</property>
+
+         <child>
+           <widget class="GtkMenuBar" id="MenuMain">
+             <property name="visible">True</property>
+
+             <child>
+               <widget class="GtkMenuItem" id="FileMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_File</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="FileMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="FileMenuNewTitle">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">New</property>
+                         <property name="use_underline">True</property>
+
+                         <child>
+                           <widget class="GtkMenu" id="FileMenuNewTitle_menu">
+
+                             <child>
+                               <widget class="GtkMenuItem" id="EmptyTraceset">
+                                 <property name="visible">True</property>
+                                 <property name="label" translatable="yes">Empty trace set</property>
+                                 <property name="use_underline">True</property>
+                                 <signal name="activate" handler="on_empty_traceset_activate" last_modification_time="Tue, 10 Jun 2003 15:03:01 GMT"/>
+                               </widget>
+                             </child>
+
+                             <child>
+                               <widget class="GtkMenuItem" id="CloneTraceset">
+                                 <property name="visible">True</property>
+                                 <property name="label" translatable="yes">Clone trace set</property>
+                                 <property name="use_underline">True</property>
+                                 <signal name="activate" handler="on_clone_traceset_activate" last_modification_time="Tue, 10 Jun 2003 15:03:22 GMT"/>
+                               </widget>
+                             </child>
+
+                             <child>
+                               <widget class="GtkMenuItem" id="FileMenuNewSep">
+                                 <property name="visible">True</property>
+                               </widget>
+                             </child>
+
+                             <child>
+                               <widget class="GtkMenuItem" id="Tab">
+                                 <property name="visible">True</property>
+                                 <property name="label" translatable="yes">Tab</property>
+                                 <property name="use_underline">True</property>
+                                 <signal name="activate" handler="on_tab_activate" last_modification_time="Tue, 10 Jun 2003 15:03:37 GMT"/>
+                               </widget>
+                             </child>
+                           </widget>
+                         </child>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="OpenTraceset">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Open</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_open_activate" last_modification_time="Tue, 10 Jun 2003 15:03:47 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Close">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Close</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_close_activate" last_modification_time="Tue, 10 Jun 2003 15:03:56 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="CloseTab">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Close Tab</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_close_tab_activate" last_modification_time="Tue, 10 Jun 2003 15:04:06 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="FileMenuSeparator1">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="AddTrace">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Add Trace</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_add_trace_activate" last_modification_time="Tue, 10 Jun 2003 15:04:14 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="RemoveTrace">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Remove Trace</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_remove_trace_activate" last_modification_time="Tue, 10 Jun 2003 15:04:24 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Save">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Save</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_save_activate" last_modification_time="Tue, 10 Jun 2003 15:04:36 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="SaveAs">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Save As</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_save_as_activate" last_modification_time="Tue, 10 Jun 2003 15:04:45 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="FileMenuSeparator2">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Quit">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Quit</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_quit_activate" last_modification_time="Tue, 10 Jun 2003 15:04:53 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="EditMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_Edit</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="EditMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Cut">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-cut</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_cut_activate" last_modification_time="Tue, 10 Jun 2003 15:05:00 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Copy">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-copy</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_copy_activate" last_modification_time="Tue, 10 Jun 2003 15:05:06 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Paste">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-paste</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_paste_activate" last_modification_time="Tue, 10 Jun 2003 15:05:14 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkImageMenuItem" id="Delete">
+                         <property name="visible">True</property>
+                         <property name="label">gtk-delete</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_delete_activate" last_modification_time="Tue, 10 Jun 2003 15:05:22 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="ViewMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_View</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="ViewMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ZoomIn">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Zoom in</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_zoom_in_activate" last_modification_time="Tue, 10 Jun 2003 15:05:30 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ZoomOut">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Zoom out</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_zoom_out_activate" last_modification_time="Tue, 10 Jun 2003 15:05:37 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ZoomExtended">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Zoom extended</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_zoom_extended_activate" last_modification_time="Tue, 10 Jun 2003 15:05:44 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ViewMenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="GoToTime">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Go to time</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_go_to_time_activate" last_modification_time="Tue, 10 Jun 2003 15:05:50 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ShowTimeFrame">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Show time frame</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_show_time_frame_activate" last_modification_time="Tue, 10 Jun 2003 15:06:00 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="ToolMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">Tools</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="ToolMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="MoveViewerUp">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Move viewer up</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_move_viewer_up_activate" last_modification_time="Tue, 10 Jun 2003 15:06:05 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="MoveViewerDown">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Move viewer down</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_move_viewer_down_activate" last_modification_time="Tue, 10 Jun 2003 15:06:14 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="RemoveViewer">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Remove viewer</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_remove_viewer_activate" last_modification_time="Tue, 10 Jun 2003 15:06:21 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="ToolMenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="insert_viewer_test">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Insert viewer test</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_insert_viewer_test_activate" last_modification_time="Mon, 16 Jun 2003 16:43:52 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="PluginMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">Plugins</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="PluginMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="LoadModule">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Load module</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_load_module_activate" last_modification_time="Tue, 10 Jun 2003 15:06:30 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="UnloadModule">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Unload module</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_unload_module_activate" last_modification_time="Tue, 10 Jun 2003 15:06:39 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="AddModuleSearchPath">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Add module search path</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_add_module_search_path_activate" last_modification_time="Tue, 10 Jun 2003 15:06:50 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+
+             <child>
+               <widget class="GtkMenuItem" id="OptionMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">Options</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="OptionMenuTitle_menu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Color">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Color</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_color_activate" last_modification_time="Tue, 10 Jun 2003 15:06:58 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="OptMenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="OpenFilter">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Filter</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_filter_activate" last_modification_time="Tue, 10 Jun 2003 15:07:04 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="SaveConfiguration">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Save configuration</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_save_configuration_activate" last_modification_time="Tue, 10 Jun 2003 15:07:12 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkMenuBar" id="MenuHelp">
+             <property name="visible">True</property>
+
+             <child>
+               <widget class="GtkMenuItem" id="HelpMenuTitle">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">_Help</property>
+                 <property name="use_underline">True</property>
+
+                 <child>
+                   <widget class="GtkMenu" id="HelpMenu">
+
+                     <child>
+                       <widget class="GtkMenuItem" id="Content">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Content</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_content_activate" last_modification_time="Tue, 10 Jun 2003 15:07:19 GMT"/>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="HelpmenuSeparator">
+                         <property name="visible">True</property>
+                       </widget>
+                     </child>
+
+                     <child>
+                       <widget class="GtkMenuItem" id="About">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">About...</property>
+                         <property name="use_underline">True</property>
+                         <signal name="activate" handler="on_about_activate" last_modification_time="Tue, 10 Jun 2003 15:07:28 GMT"/>
+                       </widget>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+             <property name="pack_type">GTK_PACK_END</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkToolbar" id="MToolbar1">
+         <property name="visible">True</property>
+         <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+         <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+         <property name="tooltips">True</property>
+
+         <child>
+           <widget class="button" id="tlbEmptyTraceset">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">New window with empty trace set</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">filenew.png</property>
+             <signal name="clicked" handler="on_button_new_clicked" last_modification_time="Thu, 05 Jun 2003 18:24:14 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbOpenTraceset">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">open a trace set</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">fileopen.png</property>
+             <signal name="clicked" handler="on_button_open_clicked" last_modification_time="Thu, 05 Jun 2003 18:24:37 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbAddTrace">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Add a trace </property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">edit_add_22.png</property>
+             <signal name="clicked" handler="on_button_add_trace_clicked" last_modification_time="Thu, 05 Jun 2003 18:30:00 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbRemoveTrace">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Remove a trace</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">edit_remove_22.png</property>
+             <signal name="clicked" handler="on_button_remove_trace_clicked" last_modification_time="Thu, 05 Jun 2003 18:30:09 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbSave">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">save the current trace set</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">filesave.png</property>
+             <signal name="clicked" handler="on_button_save_clicked" last_modification_time="Thu, 05 Jun 2003 18:25:30 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbSaveAs">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">save as </property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">filesaveas.png</property>
+             <signal name="clicked" handler="on_button_save_as_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:10 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbZoomIn">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Zoom in</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">stock_zoom_in_24.png</property>
+             <property name="new_group">True</property>
+             <signal name="clicked" handler="on_button_zoom_in_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:01 GMT"/>
+           </widget>
+           <packing>
+             <property name="new_group">True</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbZoomOut">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Zoom out</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">stock_zoom_out_24.png</property>
+             <signal name="clicked" handler="on_button_zoom_out_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:32 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbZoomExtended">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Zoom extended</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">stock_zoom_fit_24.png</property>
+             <signal name="clicked" handler="on_button_zoom_extended_clicked" last_modification_time="Thu, 05 Jun 2003 18:26:48 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbGoToTime">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Go to time</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">gtk-jump-to.png</property>
+             <signal name="clicked" handler="on_button_go_to_time_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:07 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbShowTimeFrame">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Show time frame</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">mini-display.xpm</property>
+             <signal name="clicked" handler="on_button_show_time_frame_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:21 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbMoveViewerUp">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Move up current viewer</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">1uparrow.png</property>
+             <property name="new_group">True</property>
+             <signal name="clicked" handler="on_button_move_up_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:41 GMT"/>
+           </widget>
+           <packing>
+             <property name="new_group">True</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbMoveViewerDown">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Move down current viewer</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">1downarrow.png</property>
+             <signal name="clicked" handler="on_button_move_down_clicked" last_modification_time="Thu, 05 Jun 2003 18:28:59 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="button" id="tlbRemoveViewer">
+             <property name="border_width">1</property>
+             <property name="visible">True</property>
+             <property name="tooltip" translatable="yes">Delete current viewer</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">True</property>
+             <property name="icon">remove.png</property>
+             <signal name="clicked" handler="on_button_delete_viewer_clicked" last_modification_time="Thu, 05 Jun 2003 18:29:26 GMT"/>
+           </widget>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkToolbar" id="MToolbar2">
+         <property name="visible">True</property>
+         <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+         <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
+         <property name="tooltips">True</property>
+
+         <child>
+           <placeholder/>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkNotebook" id="MNotebook">
+         <property name="visible">True</property>
+         <property name="can_focus">True</property>
+         <property name="show_tabs">True</property>
+         <property name="show_border">True</property>
+         <property name="tab_pos">GTK_POS_TOP</property>
+         <property name="scrollable">False</property>
+         <property name="enable_popup">False</property>
+         <signal name="switch_page" handler="on_MNotebook_switch_page" last_modification_time="Tue, 17 Jun 2003 17:00:29 GMT"/>
+
+         <child>
+           <placeholder/>
+         </child>
+
+         <child>
+           <widget class="GtkLabel" id="label1">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes"></property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">False</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+           </widget>
+           <packing>
+             <property name="type">tab</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkStatusbar" id="MStatusbar">
+         <property name="visible">True</property>
+         <property name="has_resize_grip">True</property>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">False</property>
+       </packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/mainwin.gladep b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/mainwin.gladep
new file mode 100644 (file)
index 0000000..3158684
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+  <name>MainWin</name>
+  <program_name>mainwin</program_name>
+  <gnome_support>FALSE</gnome_support>
+  <gettext_support>FALSE</gettext_support>
+  <output_build_files>FALSE</output_build_files>
+  <backup_source_files>FALSE</backup_source_files>
+</glade-project>
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1downarrow.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1downarrow.png
new file mode 100644 (file)
index 0000000..30e0602
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1downarrow.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1uparrow.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1uparrow.png
new file mode 100644 (file)
index 0000000..7bb1b68
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/1uparrow.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/Makefile.am
new file mode 100644 (file)
index 0000000..7106496
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# Makefile for LTT New generation user interface
+#
+# Created by Mathieu Desnoyers on September 30, 2003
+#
+
+EXTRA_DIST =  \
+       1downarrow.png\
+       1uparrow.png\
+       edit_add_22.png\
+       edit_remove_22.png\
+       filenew.png\
+       fileopen.png\
+       filesave.png\
+       filesaveas.png\
+       gtk-add.png\
+       gtk-jump-to.png\
+       mini-display.xpm\
+       move_message.xpm\
+       remove.png\
+       remove1.png\
+       stock_zoom_fit_24.png\
+       stock_zoom_in_24.png\
+       stock_zoom_out_24.png\
+       stock_stop_24.png\
+       stock_redo_24.png\
+       stock_refresh_24.png\
+       close.png\
+       stock_jump_to_24.png\
+       lttv-color-list.png
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/close.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/close.png
new file mode 100644 (file)
index 0000000..3506f4b
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/close.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_add_22.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_add_22.png
new file mode 100644 (file)
index 0000000..c46aed2
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_add_22.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_remove_22.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_remove_22.png
new file mode 100644 (file)
index 0000000..1a2f87c
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/edit_remove_22.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filenew.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filenew.png
new file mode 100644 (file)
index 0000000..cba0053
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filenew.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/fileopen.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/fileopen.png
new file mode 100644 (file)
index 0000000..f92ef90
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/fileopen.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesave.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesave.png
new file mode 100644 (file)
index 0000000..6a9adc1
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesave.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesaveas.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesaveas.png
new file mode 100644 (file)
index 0000000..ef0e8c7
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/filesaveas.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-add.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-add.png
new file mode 100644 (file)
index 0000000..e517f41
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-add.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-jump-to.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-jump-to.png
new file mode 100644 (file)
index 0000000..8039c0e
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/gtk-jump-to.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/lttv-color-list.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/lttv-color-list.png
new file mode 100644 (file)
index 0000000..2fc6651
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/lttv-color-list.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/mini-display.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/mini-display.xpm
new file mode 100644 (file)
index 0000000..e1e34a5
--- /dev/null
@@ -0,0 +1,25 @@
+/* XPM */
+static char * mini-display_xpm[] = {
+"16 16 6 1",
+"      c None s None",
+".     c #808080",
+"X     c white",
+"o     c black",
+"O     c blue",
+"+     c #c0c0c0",
+"                ",
+"  ............  ",
+" .XXXXXXXXXXXXo ",
+" .Xooooooooo.Xo ",
+" .XoOOOOOOOO.Xo ",
+" .XoOXOOOOOO.Xo ",
+" .XoOOOOOOOO.Xo ",
+" .XoOOOOOOOO.Xo ",
+" .XoOOOOOOOO.Xo ",
+" .XoOOOOOOOO.Xo ",
+" .Xo.........Xo ",
+" .XXXXXXXXXXXXo ",
+"  oooooooooooo  ",
+"    .XXXX+.o    ",
+"  oooooooooooo  ",
+"                "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/move_message.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/move_message.xpm
new file mode 100644 (file)
index 0000000..846febb
--- /dev/null
@@ -0,0 +1,59 @@
+/* XPM */
+static char * 16_move_message_xpm[] = {
+"16 16 40 1",
+"      c None",
+".     c #010101",
+"+     c #2F2F2F",
+"@     c #A7A4A0",
+"#     c #FCFCFC",
+"$     c #64625F",
+"%     c #95938E",
+"&     c #FBFBFB",
+"*     c #F9F8F6",
+"=     c #FBFAFA",
+"-     c #F6F5F1",
+";     c #7D7B78",
+">     c #EAE8E3",
+",     c #969491",
+"'     c #F6F4F1",
+")     c #81807C",
+"!     c #E5E3DE",
+"~     c #000000",
+"{     c #928F8B",
+"]     c #FBFBFA",
+"^     c #F7F5F2",
+"/     c #F5F3F0",
+"(     c #F7F6F4",
+"_     c #B5B2AC",
+":     c #A09C97",
+"<     c #F0EFEB",
+"[     c #E4E2DD",
+"}     c #AEABA6",
+"|     c #92908B",
+"1     c #E8E6E1",
+"2     c #B0ADA7",
+"3     c #F7F6F2",
+"4     c #F5F4F0",
+"5     c #6B6A68",
+"6     c #83817E",
+"7     c #E1DFDA",
+"8     c #E2DFD9",
+"9     c #E2E0DB",
+"0     c #E3E1DC",
+"a     c #E6E4DF",
+"                ",
+" . . . . . .    ",
+".           .   ",
+"                ",
+".           .   ",
+"    .+......... ",
+".  .@#########$.",
+"   .#%&*#*=*-;>.",
+".  .#*,=*=*')'!.",
+" ~ .#**{]*^)*/!.",
+"   .#*(_)#):-<[.",
+"   .#(}**)^^|1[.",
+"   .#2*/34^/>51.",
+"   .678887990a$.",
+"    ........... ",
+"                "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove.png
new file mode 100644 (file)
index 0000000..8127ee4
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove1.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove1.png
new file mode 100644 (file)
index 0000000..cc6338b
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/remove1.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png
new file mode 100644 (file)
index 0000000..52f7f60
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_jump_to_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_redo_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_redo_24.png
new file mode 100644 (file)
index 0000000..9a5ef57
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_redo_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_refresh_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_refresh_24.png
new file mode 100644 (file)
index 0000000..c7e691b
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_refresh_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_stop_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_stop_24.png
new file mode 100644 (file)
index 0000000..89c2124
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_stop_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_fit_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_fit_24.png
new file mode 100644 (file)
index 0000000..585e970
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_fit_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_in_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_in_24.png
new file mode 100644 (file)
index 0000000..1ac4864
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_in_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_out_24.png b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_out_24.png
new file mode 100644 (file)
index 0000000..d67a87d
Binary files /dev/null and b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/lttvwindow/pixmaps/stock_zoom_out_24.png differ
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/Makefile.am
new file mode 100644 (file)
index 0000000..cf582c2
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libguistatistics.la
+libguistatistics_la_LDFLAGS = -module
+libguistatistics_la_SOURCES = statistics.c
+
+EXTRA_DIST = \
+               hGuiStatisticInsert.xpm
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/hGuiStatisticInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/hGuiStatisticInsert.xpm
new file mode 100644 (file)
index 0000000..1a78b4d
--- /dev/null
@@ -0,0 +1,27 @@
+/* XPM */
+static char * hGuiStatisticInsert_xpm[] = {
+"22 22 2 1",
+"      c None",
+".     c #800080",
+"                      ",
+"                      ",
+"                      ",
+"   ..............     ",
+"   ....        ...    ",
+"    ....         .    ",
+"     ....        .    ",
+"      ....            ",
+"       ....           ",
+"        ....          ",
+"         ....         ",
+"          ...         ",
+"         ...          ",
+"        ...           ",
+"       ...            ",
+"      ...             ",
+"     ...         .    ",
+"    ...          .    ",
+"   ...         ...    ",
+"   ..............     ",
+"                      ",
+"                      "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/statistics.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/statistics/statistics.c
new file mode 100644 (file)
index 0000000..b9b341e
--- /dev/null
@@ -0,0 +1,712 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 XangXiu Yang
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttv/tracecontext.h>
+#include <lttv/hook.h>
+#include <lttv/state.h>
+#include <lttv/stats.h>
+
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+
+#include "hGuiStatisticInsert.xpm"
+
+#define PATH_LENGTH        256  /* CHECK */
+#define MAX_NUMBER_EVENT "max_number_event"
+
+//???????????????6
+//static GPtrArray  * statistic_traceset;
+
+/** Array containing instanced objects. Used when module is unloaded */
+static GSList *g_statistic_viewer_data_list = NULL ;
+
+typedef struct _StatisticViewerData StatisticViewerData;
+
+static void request_background_data(StatisticViewerData *svd);
+GtkWidget *guistatistic_get_widget(StatisticViewerData *svd);
+
+//! Statistic Viewer's constructor hook
+GtkWidget *h_gui_statistic(Tab *tab);
+//! Statistic Viewer's constructor
+StatisticViewerData *gui_statistic(Tab *tab);
+//! Statistic Viewer's destructor
+void gui_statistic_destructor(StatisticViewerData *statistic_viewer_data);
+
+static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
+
+void statistic_destroy_hash_key(gpointer key);
+void statistic_destroy_hash_data(gpointer data);
+
+void show_traceset_stats(StatisticViewerData * statistic_viewer_data);
+void show_tree(StatisticViewerData * statistic_viewer_data,
+         LttvAttribute* stats,  GtkTreeIter* parent);
+void show_statistic(StatisticViewerData * statistic_viewer_data,
+         LttvAttribute* stats, GtkTextBuffer* buf);
+
+
+gboolean statistic_traceset_changed(void * hook_data, void * call_data);
+//void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data, 
+//           LttvTracesetContext * tsc);
+//void statistic_remove_context_hooks(StatisticViewerData *statistic_viewer_data, 
+//           LttvTracesetContext * tsc);
+
+//gboolean statistic_insert_traceset_stats(void * stats);
+
+enum
+{
+   NAME_COLUMN,
+   N_COLUMNS
+};
+
+struct _StatisticViewerData{
+  Tab *tab;
+  //LttvTracesetStats * stats;
+  int                 size;
+
+  //gboolean     shown;       //indicate if the statistic is shown or not
+  //char *       filter_key;
+
+  GtkWidget    * hpaned_v;
+  GtkTreeStore * store_m;
+  GtkWidget    * tree_v;
+
+  //scroll window containing Tree View
+  GtkWidget * scroll_win_tree;
+
+  GtkWidget    * text_v;  
+  //scroll window containing Text View
+  GtkWidget * scroll_win_text;
+
+  // Selection handler 
+  GtkTreeSelection *select_c;
+  
+  //hash 
+  GHashTable *statistic_hash;
+};
+
+
+
+
+/* Action to do when background computation completed.
+ *
+ * Eventually, will have to check that every requested traces are finished
+ * before doing the redraw. It will save unnecessary processor usage.
+ */
+
+static gint background_ready(void *hook_data, void *call_data)
+{
+  StatisticViewerData *svd = (StatisticViewerData *)hook_data;
+  Tab *tab = svd->tab;
+  LttvTrace *trace = (LttvTrace*)call_data;
+
+  g_debug("statistics viewer : background computation data ready.");
+
+  gtk_tree_store_clear (svd->store_m);
+
+  lttv_stats_sum_traceset(lttvwindow_get_traceset_stats(tab));
+  show_traceset_stats(svd);
+
+  return 0;
+}
+
+/* Request background computation. Verify if it is in progress or ready first.
+ *
+ * Right now, for all loaded traces.
+ *
+ * Later : must be only for each trace in the tab's traceset.
+ */
+static void request_background_data(StatisticViewerData *svd)
+{
+  gint num_traces = lttvwindowtraces_get_number();
+  gint i;
+  LttvTrace *trace;
+
+  LttvHooks *background_ready_hook = 
+    lttv_hooks_new();
+  lttv_hooks_add(background_ready_hook, background_ready, svd,
+      LTTV_PRIO_DEFAULT);
+  
+  for(i=0;i<num_traces;i++) {
+    trace = lttvwindowtraces_get_trace(i);
+
+    if(lttvwindowtraces_get_ready(g_quark_from_string("stats"),trace)==FALSE) {
+
+      if(lttvwindowtraces_get_in_progress(g_quark_from_string("stats"),
+                                          trace) == FALSE) {
+        /* We first remove requests that could have been done for the same
+         * information. Happens when two viewers ask for it before servicing
+         * starts.
+         */
+        if(!lttvwindowtraces_background_request_find(trace, "stats"))
+          lttvwindowtraces_background_request_queue(
+              main_window_get_widget(svd->tab), trace, "stats");
+        lttvwindowtraces_background_notify_queue(svd,
+                                                 trace,
+                                                 ltt_time_infinite,
+                                                 NULL,
+                                                 background_ready_hook);
+      } else { /* in progress */
+      
+        lttvwindowtraces_background_notify_current(svd,
+                                                   trace,
+                                                   ltt_time_infinite,
+                                                   NULL,
+                                                   background_ready_hook);
+      
+      }
+    } else {
+      /* ready */
+      lttv_hooks_call(background_ready_hook, NULL);
+    }
+  }
+  lttv_hooks_destroy(background_ready_hook);
+}
+
+
+GtkWidget *guistatistic_get_widget(StatisticViewerData *svd)
+{
+  return svd->hpaned_v;
+}
+
+
+void
+gui_statistic_destructor(StatisticViewerData *statistic_viewer_data)
+{
+  Tab *tab = statistic_viewer_data->tab;
+
+  /* May already been done by GTK window closing */
+  if(GTK_IS_WIDGET(guistatistic_get_widget(statistic_viewer_data))){
+    g_info("widget still exists");
+  }
+  if(tab != NULL) {
+    lttvwindow_unregister_traceset_notify(statistic_viewer_data->tab,
+                                          statistic_traceset_changed,
+                                          statistic_viewer_data);
+  }
+  lttvwindowtraces_background_notify_remove(statistic_viewer_data);
+
+  g_hash_table_destroy(statistic_viewer_data->statistic_hash);
+  g_statistic_viewer_data_list =
+    g_slist_remove(g_statistic_viewer_data_list, statistic_viewer_data);
+  g_free(statistic_viewer_data);
+}
+
+
+/**
+ * Statistic Viewer's constructor hook
+ *
+ * This constructor is given as a parameter to the menuitem and toolbar button
+ * registration. It creates the list.
+ * @param parent_window A pointer to the parent window.
+ * @return The widget created.
+ */
+GtkWidget *
+h_gui_statistic(Tab *tab)
+{
+  StatisticViewerData* statistic_viewer_data = gui_statistic(tab) ;
+
+  if(statistic_viewer_data)
+    return guistatistic_get_widget(statistic_viewer_data);
+  else return NULL;
+  
+}
+
+#if 0
+gboolean statistic_insert_traceset_stats(void * stats)
+{
+  int i, len;
+  gpointer s;
+
+  len = statistic_traceset->len;
+  for(i=0;i<len;i++){
+    s = g_ptr_array_index(statistic_traceset, i);
+    if(s == stats) break;    
+  }
+  if(i==len){
+    g_ptr_array_add(statistic_traceset, stats);
+    return TRUE;
+  }
+  return FALSE;
+}
+#endif //0
+
+/**
+ * Statistic Viewer's constructor
+ *
+ * This constructor is used to create StatisticViewerData data structure.
+ * @return The Statistic viewer data created.
+ */
+StatisticViewerData *
+gui_statistic(Tab *tab)
+{
+  GtkCellRenderer *renderer;
+  GtkTreeViewColumn *column;
+
+  StatisticViewerData* statistic_viewer_data = g_new(StatisticViewerData,1);
+
+  statistic_viewer_data->tab  = tab;
+ // statistic_viewer_data->stats  =
+ //         lttvwindow_get_traceset_stats(statistic_viewer_data->tab);
+ // statistic_viewer_data->calculate_stats = 
+ //   statistic_insert_traceset_stats((void *)statistic_viewer_data->stats);
+
+  lttvwindow_register_traceset_notify(statistic_viewer_data->tab,
+                                      statistic_traceset_changed,
+                                      statistic_viewer_data);
+  statistic_viewer_data->statistic_hash = g_hash_table_new_full(g_str_hash,
+                                                  g_str_equal,
+                                                  statistic_destroy_hash_key,
+                                                  NULL);
+
+  statistic_viewer_data->hpaned_v  = gtk_hpaned_new();
+  statistic_viewer_data->store_m = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING);
+  statistic_viewer_data->tree_v  = 
+    gtk_tree_view_new_with_model (
+        GTK_TREE_MODEL (statistic_viewer_data->store_m));
+  g_object_unref (G_OBJECT (statistic_viewer_data->store_m));
+
+  // Setup the selection handler
+  statistic_viewer_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (statistic_viewer_data->tree_v));
+  gtk_tree_selection_set_mode (statistic_viewer_data->select_c, GTK_SELECTION_SINGLE);
+  g_signal_connect (G_OBJECT (statistic_viewer_data->select_c), "changed",
+        G_CALLBACK (tree_selection_changed_cb),
+        statistic_viewer_data);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Statistic Name",
+                 renderer,
+                 "text", NAME_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  //  gtk_tree_view_column_set_fixed_width (column, 45);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (statistic_viewer_data->tree_v), column);
+
+
+  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (statistic_viewer_data->tree_v), FALSE);
+
+  statistic_viewer_data->scroll_win_tree = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data->scroll_win_tree), 
+         GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
+
+  gtk_container_add (GTK_CONTAINER (statistic_viewer_data->scroll_win_tree), statistic_viewer_data->tree_v);
+  gtk_paned_pack1(GTK_PANED(statistic_viewer_data->hpaned_v),statistic_viewer_data->scroll_win_tree, TRUE, FALSE);
+  gtk_paned_set_position(GTK_PANED(statistic_viewer_data->hpaned_v), 160);
+
+  statistic_viewer_data->scroll_win_text = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data->scroll_win_text), 
+         GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
+
+  statistic_viewer_data->text_v = gtk_text_view_new ();
+  
+  gtk_text_view_set_editable(GTK_TEXT_VIEW(statistic_viewer_data->text_v),FALSE);
+  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(statistic_viewer_data->text_v),FALSE);
+  gtk_container_add (GTK_CONTAINER (statistic_viewer_data->scroll_win_text), statistic_viewer_data->text_v);
+  gtk_paned_pack2(GTK_PANED(statistic_viewer_data->hpaned_v), statistic_viewer_data->scroll_win_text, TRUE, FALSE);
+
+  gtk_container_set_border_width(
+      GTK_CONTAINER(statistic_viewer_data->hpaned_v), 1);
+  
+  gtk_widget_show(statistic_viewer_data->scroll_win_tree);
+  gtk_widget_show(statistic_viewer_data->scroll_win_text);
+  gtk_widget_show(statistic_viewer_data->tree_v);
+  gtk_widget_show(statistic_viewer_data->text_v);
+  gtk_widget_show(statistic_viewer_data->hpaned_v);
+
+  g_object_set_data_full(
+      G_OBJECT(guistatistic_get_widget(statistic_viewer_data)),
+      "statistic_viewer_data",
+      statistic_viewer_data,
+      (GDestroyNotify)gui_statistic_destructor);
+
+  /* Add the object's information to the module's array */
+  g_statistic_viewer_data_list = g_slist_append(
+      g_statistic_viewer_data_list,
+      statistic_viewer_data);
+
+  request_background_data(statistic_viewer_data);
+  return statistic_viewer_data;
+}
+
+static void
+tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
+{
+  StatisticViewerData *statistic_viewer_data = (StatisticViewerData*)data;
+  GtkTreeIter iter;
+  GtkTreeModel *model = GTK_TREE_MODEL(statistic_viewer_data->store_m);
+  gchar *event;
+  GtkTextBuffer* buf;
+  gchar * str;
+  GtkTreePath * path;
+  GtkTextIter   text_iter;
+  LttvAttribute * stats;
+
+  if (gtk_tree_selection_get_selected (selection, &model, &iter))
+    {
+      gtk_tree_model_get (model, &iter, NAME_COLUMN, &event, -1);
+
+      path = gtk_tree_model_get_path(GTK_TREE_MODEL(model),&iter);
+      str = gtk_tree_path_to_string (path);
+      stats = (LttvAttribute*)g_hash_table_lookup (statistic_viewer_data->statistic_hash,str);
+      g_free(str);
+      
+      buf =  gtk_text_view_get_buffer((GtkTextView*)statistic_viewer_data->text_v);
+      gtk_text_buffer_set_text(buf,"Statistic for  '", -1);
+      gtk_text_buffer_get_end_iter(buf, &text_iter);
+      gtk_text_buffer_insert(buf, &text_iter, event, strlen(event));      
+      gtk_text_buffer_get_end_iter(buf, &text_iter);
+      gtk_text_buffer_insert(buf, &text_iter, "' :\n\n",5);
+      
+      show_statistic(statistic_viewer_data, stats, buf);
+
+      g_free (event);
+    }
+}
+
+void statistic_destroy_hash_key(gpointer key)
+{
+  g_free(key);
+}
+
+#ifdef DEBUG
+#include <stdio.h>
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+#endif //DEBUG
+
+void show_traceset_stats(StatisticViewerData * statistic_viewer_data)
+{
+  Tab *tab = statistic_viewer_data->tab;
+  int i, nb;
+  LttvTraceset *ts;
+  LttvTraceStats *tcs;
+  LttSystemDescription *desc;
+  LttvTracesetStats * tscs = lttvwindow_get_traceset_stats(tab);
+  gchar * str, trace_str[PATH_LENGTH];
+  GtkTreePath * path;
+  GtkTreeIter   iter;
+  GtkTreeStore * store = statistic_viewer_data->store_m;
+
+  if(tscs->stats == NULL) return;
+#ifdef DEBUG
+  lttv_attribute_write_xml(tscs->stats, stdout, 1, 4);
+#endif //DEBUG
+  
+  ts = tscs->parent.parent.ts;
+  nb = lttv_traceset_number(ts);
+  if(nb == 0)return;
+
+  gtk_tree_store_append (store, &iter, NULL);  
+  gtk_tree_store_set (store, &iter,
+          NAME_COLUMN, "Traceset statistics",
+          -1);  
+  path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+  str = gtk_tree_path_to_string (path);
+  g_hash_table_insert(statistic_viewer_data->statistic_hash,
+          (gpointer)str, tscs->stats);
+  show_tree(statistic_viewer_data, tscs->stats, &iter);
+
+  //show stats for all traces
+  for(i = 0 ; i < nb ; i++) {
+    tcs = (LttvTraceStats *)(LTTV_TRACESET_CONTEXT(tscs)->traces[i]);
+#if 0 //FIXME
+    desc = ltt_trace_system_description(tcs->parent.parent.t);    
+    LttTime start_time = ltt_trace_system_description_trace_start_time(desc);
+    sprintf(trace_str, "Trace on system %s at time %lu.%09lu", 
+            ltt_trace_system_description_node_name(desc),
+            start_time.tv_sec,
+            start_time.tv_nsec);
+#endif //0
+    sprintf(trace_str, g_quark_to_string(ltt_trace_name(tcs->parent.parent.t)));
+    gtk_tree_store_append (store, &iter, NULL);  
+    gtk_tree_store_set (store, &iter,NAME_COLUMN,trace_str,-1);  
+    path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+    str = gtk_tree_path_to_string (path);
+    g_hash_table_insert(statistic_viewer_data->statistic_hash,
+      (gpointer)str,tcs->stats);
+    show_tree(statistic_viewer_data, tcs->stats, &iter);
+#ifdef DEBUG
+    lttv_attribute_write_xml(tcs->stats, stdout, 3, 4);
+#endif //DEBUG
+  }
+}
+
+void show_tree(StatisticViewerData * statistic_viewer_data,
+         LttvAttribute* stats,  GtkTreeIter* parent)
+{
+  int i, nb;
+  LttvAttribute *subtree;
+  LttvAttributeName name;
+  LttvAttributeValue value;
+  LttvAttributeType type;
+  gchar * str, dir_str[PATH_LENGTH];
+  GtkTreePath * path;
+  GtkTreeIter   iter;
+  GtkTreeStore * store = statistic_viewer_data->store_m;
+
+  nb = lttv_attribute_get_number(stats);
+  for(i = 0 ; i < nb ; i++) {
+    type = lttv_attribute_get(stats, i, &name, &value);
+    switch(type) {
+     case LTTV_GOBJECT:
+        if(LTTV_IS_ATTRIBUTE(*(value.v_gobject))) {
+    sprintf(dir_str, "%s", g_quark_to_string(name));
+          subtree = (LttvAttribute *)*(value.v_gobject);
+    gtk_tree_store_append (store, &iter, parent);  
+    gtk_tree_store_set (store, &iter,NAME_COLUMN,dir_str,-1);  
+    path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+    str = gtk_tree_path_to_string (path);
+    g_hash_table_insert(statistic_viewer_data->statistic_hash,
+            (gpointer)str, subtree);
+          show_tree(statistic_viewer_data, subtree, &iter);
+        }
+        break;
+      default:
+  break;
+    }
+  }    
+}
+
+void show_statistic(StatisticViewerData * statistic_viewer_data,
+        LttvAttribute* stats, GtkTextBuffer* buf)
+{
+  int i, nb , flag;
+  LttvAttributeName name;
+  LttvAttributeValue value;
+  LttvAttributeType type;
+  gchar type_name[PATH_LENGTH], type_value[PATH_LENGTH];
+  GtkTextIter   text_iter;
+  
+  flag = 0;
+  nb = lttv_attribute_get_number(stats);
+  for(i = 0 ; i < nb ; i++) {
+    type = lttv_attribute_get(stats, i, &name, &value);
+    sprintf(type_name,"%s", g_quark_to_string(name));
+    type_value[0] = '\0';
+    switch(type) {
+      case LTTV_INT:
+        sprintf(type_value, " :  %d\n", *value.v_int);
+        break;
+      case LTTV_UINT:
+        sprintf(type_value, " :  %u\n", *value.v_uint);
+        break;
+      case LTTV_LONG:
+        sprintf(type_value, " :  %ld\n", *value.v_long);
+        break;
+      case LTTV_ULONG:
+        sprintf(type_value, " :  %lu\n", *value.v_ulong);
+        break;
+      case LTTV_FLOAT:
+        sprintf(type_value, " :  %f\n", (double)*value.v_float);
+        break;
+      case LTTV_DOUBLE:
+        sprintf(type_value, " :  %f\n", *value.v_double);
+        break;
+      case LTTV_TIME:
+        sprintf(type_value, " :  %10lu.%09lu\n", value.v_time->tv_sec, 
+            value.v_time->tv_nsec);
+        break;
+      case LTTV_POINTER:
+        sprintf(type_value, " :  POINTER\n");
+        break;
+      case LTTV_STRING:
+        sprintf(type_value, " :  %s\n", *value.v_string);
+        break;
+      default:
+        break;
+    }
+    if(strlen(type_value)){
+      flag = 1;
+      strcat(type_name,type_value);
+      gtk_text_buffer_get_end_iter(buf, &text_iter);
+      gtk_text_buffer_insert(buf, &text_iter, type_name, strlen(type_name));
+    }
+  }
+
+  if(flag == 0){
+    sprintf(type_value, "No statistic information in this directory.\nCheck in subdirectories please.\n");
+    gtk_text_buffer_get_end_iter(buf, &text_iter);
+    gtk_text_buffer_insert(buf, &text_iter, type_value, strlen(type_value));
+
+  }
+}
+
+gboolean statistic_traceset_changed(void * hook_data, void * call_data)
+{
+  StatisticViewerData *statistic_viewer_data = (StatisticViewerData*) hook_data;
+  
+  request_background_data(statistic_viewer_data);
+
+  return FALSE;
+}
+
+#if 0
+void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data, 
+           LttvTracesetContext * tsc)
+{
+  gint i, j, nbi, nb_tracefile;
+  LttTrace *trace;
+  LttvTraceContext *tc;
+  LttvTracefileContext *tfc;
+  LttvTracesetSelector  * ts_s;
+  LttvTraceSelector     * t_s;
+  LttvTracefileSelector * tf_s;
+  gboolean selected;
+
+  ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(statistic_viewer_data->hpaned_v), 
+              statistic_viewer_data->filter_key);
+
+  //if there are hooks for traceset, add them here
+  
+  nbi = lttv_traceset_number(tsc->ts);
+  for(i = 0 ; i < nbi ; i++) {
+    t_s = lttv_traceset_selector_trace_get(ts_s,i);
+    selected = lttv_trace_selector_get_selected(t_s);
+    if(!selected) continue;
+    tc = tsc->traces[i];
+    trace = tc->t;
+    //if there are hooks for trace, add them here
+
+    nb_tracefile = ltt_trace_control_tracefile_number(trace) +
+        ltt_trace_per_cpu_tracefile_number(trace);
+    
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tf_s = lttv_trace_selector_tracefile_get(t_s,j);
+      selected = lttv_tracefile_selector_get_selected(tf_s);
+      if(!selected) continue;
+      tfc = tc->tracefiles[j];
+      
+      //if there are hooks for tracefile, add them here
+      //      lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL,
+      //               statistic_viewer_data->before_event_hooks,NULL);
+    }
+  }  
+
+  lttv_stats_add_event_hooks(LTTV_TRACESET_STATS(tsc));
+  
+}
+
+void statistic_remove_context_hooks(StatisticViewerData * statistic_viewer_data, 
+        LttvTracesetContext * tsc)
+{
+  gint i, j, nbi, nb_tracefile;
+  LttTrace *trace;
+  LttvTraceContext *tc;
+  LttvTracefileContext *tfc;
+  LttvTracesetSelector  * ts_s;
+  LttvTraceSelector     * t_s;
+  LttvTracefileSelector * tf_s;
+  gboolean selected;
+
+  ts_s = (LttvTracesetSelector*)g_object_get_data(G_OBJECT(statistic_viewer_data->hpaned_v), 
+              statistic_viewer_data->filter_key);
+
+  //if there are hooks for traceset, remove them here
+  
+  nbi = lttv_traceset_number(tsc->ts);
+  for(i = 0 ; i < nbi ; i++) {
+    t_s = lttv_traceset_selector_trace_get(ts_s,i);
+    selected = lttv_trace_selector_get_selected(t_s);
+    if(!selected) continue;
+    tc = tsc->traces[i];
+    trace = tc->t;
+    //if there are hooks for trace, remove them here
+
+    nb_tracefile = ltt_trace_control_tracefile_number(trace) +
+        ltt_trace_per_cpu_tracefile_number(trace);
+    
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tf_s = lttv_trace_selector_tracefile_get(t_s,j);
+      selected = lttv_tracefile_selector_get_selected(tf_s);
+      if(!selected) continue;
+      tfc = tc->tracefiles[j];
+      
+      //if there are hooks for tracefile, remove them here
+      //      lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL,
+      //            statistic_viewer_data->before_event_hooks,NULL);
+    }
+  }
+
+  lttv_stats_remove_event_hooks(LTTV_TRACESET_STATS(tsc));
+}
+#endif //0
+
+/**
+ * plugin's init function
+ *
+ * This function initializes the Statistic Viewer functionnality through the
+ * gtkTraceSet API.
+ */
+static void init() {
+
+  lttvwindow_register_constructor("guistatistics",
+                                  "/",
+                                  "Insert Statistic Viewer",
+                                  hGuiStatisticInsert_xpm,
+                                  "Insert Statistic Viewer",
+                                  h_gui_statistic);
+}
+
+void statistic_destroy_walk(gpointer data, gpointer user_data)
+{
+  StatisticViewerData *svd = (StatisticViewerData*)data;
+
+  g_debug("CFV.c : statistic_destroy_walk, %p", svd);
+  /* May already have been done by GTK window closing */
+  if(GTK_IS_WIDGET(guistatistic_get_widget(svd)))
+    gtk_widget_destroy(guistatistic_get_widget(svd));
+}
+
+/**
+ * plugin's destroy function
+ *
+ * This function releases the memory reserved by the module and unregisters
+ * everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+  
+  g_slist_foreach(g_statistic_viewer_data_list, statistic_destroy_walk, NULL );    
+  g_slist_free(g_statistic_viewer_data_list);
+
+  lttvwindow_unregister_constructor(h_gui_statistic);
+  
+}
+
+
+LTTV_MODULE("guistatistics", "Statistics viewer", \
+    "Graphical module to view statistics about processes, CPUs and systems", \
+    init, destroy, "lttvwindow")
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/Makefile.am
new file mode 100644 (file)
index 0000000..0c04b19
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Makefile for LTT New generation user interface : plugins.
+#
+# Created by Mathieu Desnoyers on May 6, 2003
+#
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+AM_CFLAGS += $(GTK_CFLAGS)
+AM_CFLAGS += -DPACKAGE_DATA_DIR=\""$(datadir)"\" -DPACKAGE_BIN_DIR=\""$(bindir)"\"
+LIBS += $(GLIB_LIBS)
+LIBS += $(GTK_LIBS) -L${top_srcdir}/lttv/modules/gui/lttvwindow/lttvwindow -llttvwindow
+LIBS += $(UTIL_LIBS)
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libguitracecontrol.la
+libguitracecontrol_la_LDFLAGS = -module
+libguitracecontrol_la_SOURCES = tracecontrol.c
+
+EXTRA_DIST = \
+    hTraceControlInsert.xpm TraceControlStart.xpm TraceControlPause.xpm \
+               TraceControlStop.xpm
+    
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlPause.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlPause.xpm
new file mode 100644 (file)
index 0000000..ac2c273
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */
+static char * TraceControlPause_xpm[] = {
+"22 22 5 1",
+"      c None",
+".     c #000000",
+"+     c #570404",
+"@     c #EE8100",
+"#     c #053C0A",
+"        .....         ",
+"       .......        ",
+"      ...+++...       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ...+++...       ",
+"      .........       ",
+"      ...@@@...       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ...@@@...       ",
+"      .........       ",
+"      ...###...       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"       ..###..        ",
+"       .......        ",
+"       .......        ",
+"        .....         "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlStart.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlStart.xpm
new file mode 100644 (file)
index 0000000..fc225d0
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */
+static char * TraceControlStart_xpm[] = {
+"22 22 5 1",
+"      c None",
+".     c #000000",
+"+     c #570404",
+"@     c #6B3A00",
+"#     c #12E826",
+"        .....         ",
+"       .......        ",
+"      ...+++...       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ...+++...       ",
+"      .........       ",
+"      ...@@@...       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ...@@@...       ",
+"      .........       ",
+"      ...###...       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"       ..###..        ",
+"       .......        ",
+"       .......        ",
+"        .....         "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlStop.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/TraceControlStop.xpm
new file mode 100644 (file)
index 0000000..b01067b
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */
+static char * TraceControlStop_xpm[] = {
+"22 22 5 1",
+"      c None",
+".     c #000000",
+"+     c #D00A0A",
+"@     c #6B3A00",
+"#     c #053C0A",
+"        .....         ",
+"       .......        ",
+"      ...+++...       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ...+++...       ",
+"      .........       ",
+"      ...@@@...       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ...@@@...       ",
+"      .........       ",
+"      ...###...       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"       ..###..        ",
+"       .......        ",
+"       .......        ",
+"        .....         "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/hTraceControlInsert.xpm b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/hTraceControlInsert.xpm
new file mode 100644 (file)
index 0000000..fecc665
--- /dev/null
@@ -0,0 +1,30 @@
+/* XPM */
+static char * hTraceControlInsert_xpm[] = {
+"22 22 5 1",
+"      c None",
+".     c #000000",
+"+     c #D00A0A",
+"@     c #EE8100",
+"#     c #12E826",
+"        .....         ",
+"       .......        ",
+"      ...+++...       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ..+++++..       ",
+"      ...+++...       ",
+"      .........       ",
+"      ...@@@...       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ..@@@@@..       ",
+"      ...@@@...       ",
+"      .........       ",
+"      ...###...       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"      ..#####..       ",
+"       ..###..        ",
+"       .......        ",
+"       .......        ",
+"        .....         "};
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/tracecontrol.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/gui/tracecontrol/tracecontrol.c
new file mode 100644 (file)
index 0000000..a44fa27
--- /dev/null
@@ -0,0 +1,1092 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+
+#include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttvwindowtraces.h>
+
+#include "hTraceControlInsert.xpm"
+#include "TraceControlStart.xpm"
+#include "TraceControlPause.xpm"
+#include "TraceControlStop.xpm"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pty.h>
+#include <utmp.h>
+#include <sys/wait.h>
+#include <sys/poll.h>
+#include <errno.h>
+
+#define MAX_ARGS_LEN PATH_MAX * 10
+
+GSList *g_control_list = NULL ;
+
+/*! \file lttv/modules/gui/tracecontrol/tracecontrol.c
+ *  \brief Graphic trace start/stop control interface.
+ *
+ * This plugin interacts with lttctl to start/stop tracing. It needs to take the
+ * root password to be able to interact with lttctl.
+ *
+ */
+
+typedef struct _ControlData ControlData;
+
+/*
+ * Prototypes
+ */
+GtkWidget *guicontrol_get_widget(ControlData *tcd);
+ControlData *gui_control(Tab *tab);
+void gui_control_destructor(ControlData *tcd);
+GtkWidget* h_guicontrol(Tab *tab);
+void control_destroy_walk(gpointer data, gpointer user_data);
+  
+/*
+ * Callback functions
+ */
+
+static void start_clicked (GtkButton *button, gpointer user_data);
+static void pause_clicked (GtkButton *button, gpointer user_data);
+static void unpause_clicked (GtkButton *button, gpointer user_data);
+static void stop_clicked (GtkButton *button, gpointer user_data);
+
+
+/**
+ *  @struct _ControlData
+ *  
+ *  @brief Main structure of gui control
+ */
+struct _ControlData {
+  Tab *tab;                             /**< current tab of module */
+
+  GtkWidget *window;                  /**< window */
+  
+  GtkWidget *main_box;                /**< main container */
+  GtkWidget *start_button;
+  GtkWidget *pause_button;
+  GtkWidget *unpause_button;
+  GtkWidget *stop_button;
+  GtkWidget *username_label;
+  GtkWidget *username_entry;
+  GtkWidget *password_label;
+  GtkWidget *password_entry;
+  GtkWidget *channel_dir_label;
+  GtkWidget *channel_dir_entry;
+  GtkWidget *trace_dir_label;
+  GtkWidget *trace_dir_entry;
+  GtkWidget *trace_name_label;
+  GtkWidget *trace_name_entry;
+  GtkWidget *trace_mode_label;
+  GtkWidget *trace_mode_combo;
+  GtkWidget *start_daemon_label;
+  GtkWidget *start_daemon_check;
+  GtkWidget *append_label;
+  GtkWidget *append_check;
+  GtkWidget *optional_label;
+  GtkWidget *subbuf_size_label;
+  GtkWidget *subbuf_size_entry;
+  GtkWidget *subbuf_num_label;
+  GtkWidget *subbuf_num_entry;
+  GtkWidget *lttctl_path_label;
+  GtkWidget *lttctl_path_entry;
+  GtkWidget *lttd_path_label;
+  GtkWidget *lttd_path_entry;
+  GtkWidget *fac_path_label;
+  GtkWidget *fac_path_entry;
+};
+
+/**
+ *  @fn GtkWidget* guicontrol_get_widget(ControlData*)
+ * 
+ *  This function returns the current main widget 
+ *  used by this module
+ *  @param tcd the module struct
+ *  @return The main widget
+ */
+GtkWidget*
+guicontrol_get_widget(ControlData *tcd)
+{
+  return tcd->window;
+}
+
+/**
+ *  @fn ControlData* gui_control(Tab*)
+ * 
+ *  Constructor is used to create ControlData data structure.
+ *  @param tab The tab structure used by the widget
+ *  @return The Filter viewer data created.
+ */
+ControlData*
+gui_control(Tab *tab)
+{
+  g_debug("filter::gui_control()");
+
+  unsigned i;
+  GtkCellRenderer *renderer;
+  GtkTreeViewColumn *column;
+
+  ControlData* tcd = g_new(ControlData,1);
+
+  tcd->tab  = tab;
+
+  tcd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(tcd->window), "LTTng Trace Control");
+  /* 
+   * Initiating GtkTable layout 
+   * starts with 2 rows and 5 columns and 
+   * expands when expressions added
+   */
+  tcd->main_box = gtk_table_new(14,7,FALSE);
+  gtk_table_set_row_spacings(GTK_TABLE(tcd->main_box),5);
+  gtk_table_set_col_spacings(GTK_TABLE(tcd->main_box),5);
+  
+  gtk_container_add(GTK_CONTAINER(tcd->window), GTK_WIDGET(tcd->main_box));
+  
+  GList *focus_chain = NULL;
+  
+  /*
+   * start/pause/stop buttons
+   */
+  GdkPixbuf *pixbuf;
+  GtkWidget *image;
+  pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStart_xpm);
+  image = gtk_image_new_from_pixbuf(pixbuf);
+  tcd->start_button = gtk_button_new_with_label("start");
+  //2.6 gtk_button_set_image(GTK_BUTTON(tcd->start_button), image);
+  g_object_set(G_OBJECT(tcd->start_button), "image", image, NULL);
+  gtk_button_set_alignment(GTK_BUTTON(tcd->start_button), 0.0, 0.0);
+  gtk_widget_show (tcd->start_button);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_button,6,7,0,1,GTK_FILL,GTK_FILL,2,2);
+  
+  pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm);
+  image = gtk_image_new_from_pixbuf(pixbuf);
+  tcd->pause_button = gtk_button_new_with_label("pause");
+  //2.6 gtk_button_set_image(GTK_BUTTON(tcd->pause_button), image);
+  g_object_set(G_OBJECT(tcd->pause_button), "image", image, NULL);
+  gtk_button_set_alignment(GTK_BUTTON(tcd->pause_button), 0.0, 0.0);
+  gtk_widget_show (tcd->pause_button);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->pause_button,6,7,1,2,GTK_FILL,GTK_FILL,2,2);
+
+  pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm);
+  image = gtk_image_new_from_pixbuf(pixbuf);
+  tcd->unpause_button = gtk_button_new_with_label("unpause");
+  //2.6 gtk_button_set_image(GTK_BUTTON(tcd->unpause_button), image);
+  g_object_set(G_OBJECT(tcd->unpause_button), "image", image, NULL);
+  gtk_button_set_alignment(GTK_BUTTON(tcd->unpause_button), 0.0, 0.0);
+  gtk_widget_show (tcd->unpause_button);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->unpause_button,6,7,2,3,GTK_FILL,GTK_FILL,2,2);
+
+  pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStop_xpm);
+  image = gtk_image_new_from_pixbuf(pixbuf);
+  tcd->stop_button = gtk_button_new_with_label("stop");
+  //2.6 gtk_button_set_image(GTK_BUTTON(tcd->stop_button), image);
+  g_object_set(G_OBJECT(tcd->stop_button), "image", image, NULL);
+  gtk_button_set_alignment(GTK_BUTTON(tcd->stop_button), 0.0, 0.0);
+  gtk_widget_show (tcd->stop_button);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->stop_button,6,7,3,4,GTK_FILL,GTK_FILL,2,2);
+  
+  /*
+   *  First half of the filter window
+   *  - textual entry of filter expression
+   *  - processing button
+   */
+  tcd->username_label = gtk_label_new("Username:");
+  gtk_widget_show (tcd->username_label);
+  tcd->username_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->username_entry),"root");
+  gtk_widget_show (tcd->username_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->username_label,0,2,0,1,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->username_entry,2,6,0,1,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+
+
+  tcd->password_label = gtk_label_new("Password:");
+  gtk_widget_show (tcd->password_label);
+  tcd->password_entry = gtk_entry_new();
+  gtk_entry_set_visibility(GTK_ENTRY(tcd->password_entry), FALSE);
+  gtk_widget_show (tcd->password_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->password_label,0,2,1,2,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->password_entry,2,6,1,2,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+
+  tcd->channel_dir_label = gtk_label_new("Channel directory:");
+  gtk_widget_show (tcd->channel_dir_label);
+  tcd->channel_dir_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->channel_dir_entry),"/mnt/relayfs/ltt");
+  gtk_widget_show (tcd->channel_dir_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->channel_dir_label,0,2,2,3,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->channel_dir_entry,2,6,2,3,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  tcd->trace_dir_label = gtk_label_new("Trace directory:");
+  gtk_widget_show (tcd->trace_dir_label);
+  tcd->trace_dir_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->trace_dir_entry),"/tmp/trace1");
+  gtk_widget_show (tcd->trace_dir_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_dir_label,0,2,3,4,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_dir_entry,2,6,3,4,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  tcd->trace_name_label = gtk_label_new("Trace name:");
+  gtk_widget_show (tcd->trace_name_label);
+  tcd->trace_name_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->trace_name_entry),"trace");
+  gtk_widget_show (tcd->trace_name_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_name_label,0,2,4,5,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_name_entry,2,6,4,5,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  tcd->trace_mode_label = gtk_label_new("Trace mode ");
+  gtk_widget_show (tcd->trace_mode_label);
+  tcd->trace_mode_combo = gtk_combo_box_new_text();
+  gtk_combo_box_append_text(GTK_COMBO_BOX(tcd->trace_mode_combo), 
+      "normal");
+  gtk_combo_box_append_text(GTK_COMBO_BOX(tcd->trace_mode_combo), 
+      "flight recorder");
+  gtk_combo_box_set_active(GTK_COMBO_BOX(tcd->trace_mode_combo), 0);
+  gtk_widget_show (tcd->trace_mode_combo);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_mode_label,0,2,5,6,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_mode_combo,2,6,5,6,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  tcd->start_daemon_label = gtk_label_new("Start daemon ");
+  gtk_widget_show (tcd->start_daemon_label);
+  tcd->start_daemon_check = gtk_check_button_new();
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd->start_daemon_check), TRUE);
+  gtk_widget_show (tcd->start_daemon_check);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_daemon_label,0,2,6,7,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_daemon_check,2,6,6,7,GTK_FILL,GTK_FILL,0,0);
+  
+  tcd->append_label = gtk_label_new("Append to trace ");
+  gtk_widget_show (tcd->append_label);
+  tcd->append_check = gtk_check_button_new();
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd->append_check), FALSE);
+  gtk_widget_show (tcd->append_check);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->append_label,0,2,7,8,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->append_check,2,6,7,8,GTK_FILL,GTK_FILL,0,0);
+
+
+  tcd->optional_label = gtk_label_new("Optional fields ");
+  gtk_widget_show (tcd->optional_label);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->optional_label,0,6,8,9,GTK_FILL,GTK_FILL,2,2);
+
+  tcd->subbuf_size_label = gtk_label_new("Subbuffer size:");
+  gtk_widget_show (tcd->subbuf_size_label);
+  tcd->subbuf_size_entry = gtk_entry_new();
+  gtk_widget_show (tcd->subbuf_size_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_size_label,0,2,9,10,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_size_entry,2,6,9,10,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  tcd->subbuf_num_label = gtk_label_new("Number of subbuffers:");
+  gtk_widget_show (tcd->subbuf_num_label);
+  tcd->subbuf_num_entry = gtk_entry_new();
+  gtk_widget_show (tcd->subbuf_num_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_label,0,2,10,11,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_entry,2,6,10,11,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  tcd->lttctl_path_label = gtk_label_new("path to lttctl:");
+  gtk_widget_show (tcd->lttctl_path_label);
+  tcd->lttctl_path_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->lttctl_path_entry),PACKAGE_BIN_DIR "/lttctl");
+  gtk_widget_show (tcd->lttctl_path_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_label,0,2,11,12,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_entry,2,6,11,12,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+
+  tcd->lttd_path_label = gtk_label_new("path to lttd:");
+  gtk_widget_show (tcd->lttd_path_label);
+  tcd->lttd_path_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->lttd_path_entry),PACKAGE_BIN_DIR "/lttd");
+  gtk_widget_show (tcd->lttd_path_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_label,0,2,12,13,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_entry,2,6,12,13,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  
+  tcd->fac_path_label = gtk_label_new("path to facilities:");
+  gtk_widget_show (tcd->fac_path_label);
+  tcd->fac_path_entry = gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(tcd->fac_path_entry),PACKAGE_DATA_DIR "/" PACKAGE "/facilities");
+  gtk_widget_set_size_request(tcd->fac_path_entry, 250, -1);
+  gtk_widget_show (tcd->fac_path_entry);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_label,0,2,13,14,GTK_FILL,GTK_FILL,2,2);
+  gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_entry,2,6,13,14,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
+  focus_chain = g_list_append (focus_chain, tcd->username_entry);
+  focus_chain = g_list_append (focus_chain, tcd->password_entry);
+  focus_chain = g_list_append (focus_chain, tcd->start_button);
+  focus_chain = g_list_append (focus_chain, tcd->pause_button);
+  focus_chain = g_list_append (focus_chain, tcd->unpause_button);
+  focus_chain = g_list_append (focus_chain, tcd->stop_button);
+  focus_chain = g_list_append (focus_chain, tcd->channel_dir_entry);
+  focus_chain = g_list_append (focus_chain, tcd->trace_dir_entry);
+  focus_chain = g_list_append (focus_chain, tcd->trace_name_entry);
+  focus_chain = g_list_append (focus_chain, tcd->trace_mode_combo);
+  focus_chain = g_list_append (focus_chain, tcd->start_daemon_check);
+  focus_chain = g_list_append (focus_chain, tcd->append_check);
+  focus_chain = g_list_append (focus_chain, tcd->subbuf_size_entry);
+  focus_chain = g_list_append (focus_chain, tcd->subbuf_num_entry);
+  focus_chain = g_list_append (focus_chain, tcd->lttctl_path_entry);
+  focus_chain = g_list_append (focus_chain, tcd->lttd_path_entry);
+  focus_chain = g_list_append (focus_chain, tcd->fac_path_entry);
+
+  gtk_container_set_focus_chain(GTK_CONTAINER(tcd->main_box), focus_chain);
+
+  g_list_free(focus_chain);
+
+  g_signal_connect(G_OBJECT(tcd->start_button), "clicked",
+      (GCallback)start_clicked, tcd);
+  g_signal_connect(G_OBJECT(tcd->pause_button), "clicked", 
+      (GCallback)pause_clicked, tcd);
+  g_signal_connect(G_OBJECT(tcd->unpause_button), "clicked", 
+      (GCallback)unpause_clicked, tcd);
+  g_signal_connect(G_OBJECT(tcd->stop_button), "clicked", 
+      (GCallback)stop_clicked, tcd);
+
+  /* 
+   * show main container 
+   */
+  gtk_widget_show(tcd->main_box);
+  gtk_widget_show(tcd->window);
+  
+  
+  g_object_set_data_full(
+      G_OBJECT(guicontrol_get_widget(tcd)),
+      "control_viewer_data",
+      tcd,
+      (GDestroyNotify)gui_control_destructor);
+
+  g_control_list = g_slist_append(
+      g_control_list,
+      tcd);
+  
+  return tcd;
+}
+
+
+/**
+ *  @fn void gui_control_destructor(ControlData*)
+ * 
+ *  Destructor for the filter gui module
+ *  @param tcd The module structure
+ */
+void
+gui_control_destructor(ControlData *tcd)
+{
+  Tab *tab = tcd->tab;
+
+  /* May already been done by GTK window closing */
+  if(GTK_IS_WIDGET(guicontrol_get_widget(tcd))){
+    g_info("widget still exists");
+  }
+//  if(tab != NULL) {
+//    lttvwindow_unregister_traceset_notify(tcd->tab,
+//                                          filter_traceset_changed,
+//                                          filter_viewer_data);
+//  }
+  lttvwindowtraces_background_notify_remove(tcd);
+  
+  g_control_list = g_slist_remove(g_control_list, tcd);
+  g_free(tcd);
+}
+
+static int execute_command(const gchar *command, const gchar *username,
+    const gchar *password, const gchar *lttd_path, const gchar *fac_path)
+{
+  pid_t pid;
+  int fdpty;
+  pid = forkpty(&fdpty, NULL, NULL, NULL);
+  int retval = 0;
+
+  if(pid > 0) {
+    /* parent */
+    gchar buf[256];
+    int status;
+    ssize_t count;
+    /* discuss with su */
+    struct timeval timeout;
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+
+    struct pollfd pollfd;
+    int num_rdy;
+    int num_hup = 0;
+
+
+    /* Read the output from the child terminal before the prompt. If no data in
+     * 200 ms, we stop reading to give the password */
+    g_info("Reading from child console...");
+    sleep(1); /* make sure the child is ready */
+    while(1) {
+      pollfd.fd = fdpty;
+      pollfd.events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
+
+      num_rdy = poll(&pollfd, 1, 200);
+#if 0
+      if(num_rdy == -1) {
+        perror("Poll error");
+        goto wait_child;
+      }
+#endif //0
+      
+      /* Timeout : stop waiting for chars */
+      if(num_rdy == 0) break;
+
+      switch(pollfd.revents) {
+        case POLLERR:
+          g_warning("Error returned in polling fd\n");
+          num_hup++;
+          break;
+        case POLLHUP:
+          g_info("Polling FD : hung up.");
+          num_hup++;
+          break;
+        case POLLNVAL:
+          g_warning("Polling fd tells it is not open");
+          num_hup++;
+          break;
+        case POLLPRI:
+        case POLLIN:
+          count = read (fdpty, buf, 256);
+          if(count > 0) {
+            buf[count] = '\0';
+            printf("%s", buf);
+          } else if(count == -1) {
+            perror("Error in read");
+            goto wait_child;
+          }
+          break;
+      }
+      if(num_hup > 0) {
+        g_warning("Child hung up too fast");
+        goto wait_child;
+      }
+    }
+    
+    /* Write the password */
+    g_info("Got su prompt, now writing password...");
+    int ret;
+    ret = write(fdpty, password, strlen(password));
+    if(ret < 0) perror("Error in write");
+    ret = write(fdpty, "\n", 1);
+    if(ret < 0) perror("Error in write");
+    fsync(fdpty);
+
+    /* Take the output from the terminal and show it on the real console */
+    g_info("Getting data from child terminal...");
+    while(1) {
+      int num_hup = 0;
+      pollfd.fd = fdpty;
+      pollfd.events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
+
+      num_rdy = poll(&pollfd, 1, -1);
+#if 0
+      if(num_rdy == -1) {
+        perror("Poll error");
+        goto wait_child;
+      }
+#endif //0
+      if(num_rdy == 0) break;
+
+      switch(pollfd.revents) {
+        case POLLERR:
+          g_warning("Error returned in polling fd\n");
+          num_hup++;
+          break;
+        case POLLHUP:
+          g_info("Polling FD : hung up.");
+          num_hup++;
+          break;
+        case POLLNVAL:
+          g_warning("Polling fd tells it is not open");
+          num_hup++;
+          break;
+        case POLLPRI:
+        case POLLIN:
+          count = read (fdpty, buf, 256);
+          if(count > 0) {
+            buf[count] = '\0';
+            printf("%s", buf);
+          } else if(count == -1) {
+            perror("Error in read");
+            goto wait_child;
+          }
+          break;
+      }
+      if(num_hup > 0) goto wait_child;
+    }
+wait_child:
+    g_info("Waiting for child exit...");
+    
+    ret = waitpid(pid, &status, 0);
+    
+    if(ret == -1) {
+      g_warning("An error occured in wait : %s",
+          strerror(errno));
+    } else {
+      if(WIFEXITED(status))
+        if(WEXITSTATUS(status) != 0) {
+          retval = WEXITSTATUS(status);
+          g_warning("An error occured in the su command : %s",
+              strerror(retval));
+        }
+    }
+
+    g_info("Child exited.");
+
+  } else if(pid == 0) {
+    /* Setup environment variables */
+    if(strcmp(lttd_path, "") != 0)
+      setenv("LTT_DAEMON", lttd_path, 1);
+    if(strcmp(fac_path, "") != 0)
+      setenv("LTT_FACILITIES", fac_path, 1);
+   
+    g_message("Executing (as %s) : %s\n", username, command);
+    
+    execlp("su", "su", "-p", "-c", command, username, NULL);
+    exit(-1); /* not supposed to happen! */
+    
+    //gint ret = execvp();
+  
+  } else {
+    /* error */
+    g_warning("Error happened when forking for su");
+  }
+
+  return retval;
+}
+
+
+/* Callbacks */
+
+void start_clicked (GtkButton *button, gpointer user_data)
+{
+  ControlData *tcd = (ControlData*)user_data;
+
+  const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
+  const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
+  const gchar *channel_dir =
+    gtk_entry_get_text(GTK_ENTRY(tcd->channel_dir_entry));
+  const gchar *trace_dir = gtk_entry_get_text(GTK_ENTRY(tcd->trace_dir_entry));
+  const gchar *trace_name =
+    gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
+  
+  const gchar *trace_mode_sel;
+  GtkTreeIter iter;
+  
+  gtk_combo_box_get_active_iter(GTK_COMBO_BOX(tcd->trace_mode_combo), &iter);
+  gtk_tree_model_get(
+      gtk_combo_box_get_model(GTK_COMBO_BOX(tcd->trace_mode_combo)),
+      &iter, 0, &trace_mode_sel, -1);
+  //const gchar *trace_mode_sel =
+    //2.6+ gtk_combo_box_get_active_text(GTK_COMBO_BOX(tcd->trace_mode_combo));
+  const gchar *trace_mode;
+  if(strcmp(trace_mode_sel, "normal") == 0)
+    trace_mode = "normal";
+  else
+    trace_mode = "flight";
+  
+  gboolean start_daemon =
+    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd->start_daemon_check));
+
+  gboolean append =
+    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd->append_check));
+  
+  const gchar *subbuf_size =
+    gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_size_entry));
+  const gchar *subbuf_num =
+    gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_num_entry));
+  const gchar *lttctl_path =
+    gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
+  const gchar *lttd_path = gtk_entry_get_text(GTK_ENTRY(tcd->lttd_path_entry));
+  const gchar *fac_path = gtk_entry_get_text(GTK_ENTRY(tcd->fac_path_entry));
+
+
+  /* Setup arguments to su */
+  /* child */
+  gchar args[MAX_ARGS_LEN];
+  gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
+  args[0] = '\0';
+  
+  /* Command */
+  strncat(args, "exec", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  if(strcmp(lttctl_path, "") == 0)
+    strncat(args, "lttctl", args_left);
+  else
+    strncat(args, lttctl_path, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* channel dir */
+  strncat(args, "-l ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, channel_dir, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* trace dir */
+  strncat(args, "-t ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, trace_dir, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  
+  /* name */
+  strncat(args, "-n ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, trace_name, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* trace mode */
+  strncat(args, "-m ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, trace_mode, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* Start daemon ? */
+  if(start_daemon) {
+    strncat(args, "-d", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  } else {
+    /* Simply create the channel and then start tracing */
+    strncat(args, "-b", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  }
+
+
+  /* Append to trace ? */
+  if(append) {
+    /* space */
+    strncat(args, " ", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+    strncat(args, "-a", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  }
+  /* optional arguments */
+  /* subbuffer size */
+  if(strcmp(subbuf_size, "") != 0) {
+    /* space */
+    strncat(args, " ", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+    strncat(args, "-z ", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+    strncat(args, subbuf_size, args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  }
+
+  /* number of subbuffers */
+  if(strcmp(subbuf_num, "") != 0) {
+    /* space */
+    strncat(args, " ", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+    strncat(args, "-x ", args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+    strncat(args, subbuf_num, args_left);
+    args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  }
+
+  
+  int retval = execute_command(args, username, password, lttd_path, fac_path);
+
+  if(retval) {
+    gchar msg[256];
+    guint msg_left = 256;
+
+    strcpy(msg, "A problem occured when executing the su command : ");
+    msg_left = 256 - strlen(msg) - 1;
+    strncat(msg, strerror(retval), msg_left);
+    GtkWidget *dialogue = 
+      gtk_message_dialog_new(
+        GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
+        GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+        GTK_MESSAGE_ERROR,
+        GTK_BUTTONS_OK,
+        msg);
+    gtk_dialog_run(GTK_DIALOG(dialogue));
+    gtk_widget_destroy(dialogue);
+  }
+  
+}
+
+
+void pause_clicked (GtkButton *button, gpointer user_data)
+{
+  ControlData *tcd = (ControlData*)user_data;
+
+  const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
+  const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
+  const gchar *trace_name =
+    gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
+  const gchar *lttd_path = "";
+  const gchar *fac_path = "";
+  
+  const gchar *lttctl_path =
+    gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
+
+  /* Setup arguments to su */
+  /* child */
+  gchar args[MAX_ARGS_LEN];
+  gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
+  args[0] = '\0';
+
+  /* Command */
+  strncat(args, "exec", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  if(strcmp(lttctl_path, "") == 0)
+    strncat(args, "lttctl", args_left);
+  else
+    strncat(args, lttctl_path, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  
+  /* name */
+  strncat(args, "-n ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, trace_name, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  /* Simply pause tracing */
+  strncat(args, "-q", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  int retval = execute_command(args, username, password, lttd_path, fac_path);
+  if(retval) {
+    gchar msg[256];
+    guint msg_left = 256;
+
+    strcpy(msg, "A problem occured when executing the su command : ");
+    msg_left = 256 - strlen(msg) - 1;
+    strncat(msg, strerror(retval), msg_left);
+    GtkWidget *dialogue = 
+      gtk_message_dialog_new(
+        GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
+        GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+        GTK_MESSAGE_ERROR,
+        GTK_BUTTONS_OK,
+        msg);
+    gtk_dialog_run(GTK_DIALOG(dialogue));
+    gtk_widget_destroy(dialogue);
+  }
+}
+
+void unpause_clicked (GtkButton *button, gpointer user_data)
+{
+  ControlData *tcd = (ControlData*)user_data;
+
+  const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
+  const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
+  const gchar *trace_name =
+    gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
+  const gchar *lttd_path = "";
+  const gchar *fac_path = "";
+  
+  const gchar *lttctl_path =
+    gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
+
+  /* Setup arguments to su */
+  /* child */
+  gchar args[MAX_ARGS_LEN];
+  gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
+  args[0] = '\0';
+
+  /* Command */
+  strncat(args, "exec", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  if(strcmp(lttctl_path, "") == 0)
+    strncat(args, "lttctl", args_left);
+  else
+    strncat(args, lttctl_path, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  
+  /* name */
+  strncat(args, "-n ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, trace_name, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  /* Simply unpause tracing */
+  strncat(args, "-s", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  int retval = execute_command(args, username, password, lttd_path, fac_path);
+  if(retval) {
+    gchar msg[256];
+    guint msg_left = 256;
+
+    strcpy(msg, "A problem occured when executing the su command : ");
+    msg_left = 256 - strlen(msg) - 1;
+    strncat(msg, strerror(retval), msg_left);
+    GtkWidget *dialogue = 
+      gtk_message_dialog_new(
+        GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
+        GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+        GTK_MESSAGE_ERROR,
+        GTK_BUTTONS_OK,
+        msg);
+    gtk_dialog_run(GTK_DIALOG(dialogue));
+    gtk_widget_destroy(dialogue);
+  }
+}
+
+void stop_clicked (GtkButton *button, gpointer user_data)
+{
+  ControlData *tcd = (ControlData*)user_data;
+
+  const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
+  const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
+  const gchar *trace_name =
+    gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
+  const gchar *lttd_path = "";
+  const gchar *fac_path = "";
+  
+  const gchar *lttctl_path =
+    gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
+  const gchar *trace_dir = gtk_entry_get_text(GTK_ENTRY(tcd->trace_dir_entry));
+
+  /* Setup arguments to su */
+  /* child */
+  gchar args[MAX_ARGS_LEN];
+  gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
+  args[0] = '\0';
+
+  /* Command */
+  strncat(args, "exec", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  if(strcmp(lttctl_path, "") == 0)
+    strncat(args, "lttctl", args_left);
+  else
+    strncat(args, lttctl_path, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  
+  /* name */
+  strncat(args, "-n ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  strncat(args, trace_name, args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  /* space */
+  strncat(args, " ", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+  /* Simply stop tracing and destroy channel */
+  strncat(args, "-R", args_left);
+  args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+  int retval = execute_command(args, username, password, lttd_path, fac_path);
+  if(retval) {
+    gchar msg[256];
+    guint msg_left = 256;
+
+    strcpy(msg, "A problem occured when executing the su command : ");
+    msg_left = 256 - strlen(msg) - 1;
+    strncat(msg, strerror(retval), msg_left);
+    GtkWidget *dialogue =
+      gtk_message_dialog_new(
+        GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
+        GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
+        GTK_MESSAGE_ERROR,
+        GTK_BUTTONS_OK,
+        msg);
+    gtk_dialog_run(GTK_DIALOG(dialogue));
+    gtk_widget_destroy(dialogue);
+    return;
+  }
+
+  /* Ask to the user if he wants to open the trace in a new window */
+  GtkWidget *dialogue;
+  GtkWidget *label;
+  gint id;
+  
+  dialogue = gtk_dialog_new_with_buttons("Open trace ?",
+      GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
+      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+      GTK_STOCK_YES,GTK_RESPONSE_ACCEPT,
+      GTK_STOCK_NO,GTK_RESPONSE_REJECT,
+      NULL);
+  label = gtk_label_new("Do you want to open the trace in LTTV ?");
+  gtk_widget_show(label);
+
+  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialogue)->vbox),
+      label);
+
+  id = gtk_dialog_run(GTK_DIALOG(dialogue));
+
+  switch(id){
+    case GTK_RESPONSE_ACCEPT:
+      {
+        create_main_window_with_trace(trace_dir);
+      }
+      break;
+    case GTK_RESPONSE_REJECT:
+    default:
+      break;
+  }
+  gtk_widget_destroy(dialogue);
+
+}
+
+
+/**
+ *  @fn GtkWidget* h_guicontrol(Tab*)
+ * 
+ *  Control Module's constructor hook
+ *
+ *  This constructor is given as a parameter to the menuitem and toolbar button
+ *  registration. It creates the list.
+ *  @param tab A pointer to the parent window.
+ *  @return The widget created.
+ */
+GtkWidget *
+h_guicontrol(Tab *tab)
+{
+  ControlData* f = gui_control(tab) ;
+
+  return NULL;
+}
+
+/**
+ *  @fn static void init()
+ * 
+ *  This function initializes the Filter Viewer functionnality through the
+ *  gtkTraceSet API.
+ */
+static void init() {
+
+  lttvwindow_register_constructor("guicontrol",
+                                  "/",
+                                  "Insert Tracing Control Module",
+                                  hTraceControlInsert_xpm,
+                                  "Insert Tracing Control Module",
+                                  h_guicontrol);
+}
+
+/**
+ *  @fn void control_destroy_walk(gpointer,gpointer)
+ * 
+ *  Initiate the destruction of the current gui module
+ *  on the GTK Interface
+ */
+void 
+control_destroy_walk(gpointer data, gpointer user_data)
+{
+  ControlData *tcd = (ControlData*)data;
+
+  g_debug("traceontrol.c : control_destroy_walk, %p", tcd);
+
+  /* May already have been done by GTK window closing */
+  if(GTK_IS_WIDGET(guicontrol_get_widget(tcd)))
+    gtk_widget_destroy(guicontrol_get_widget(tcd));
+}
+
+/**
+ *  @fn static void destroy()
+ *  @brief plugin's destroy function
+ *
+ *  This function releases the memory reserved by the module and unregisters
+ *  everything that has been registered in the gtkTraceSet API.
+ */
+static void destroy() {
+  g_slist_foreach(g_control_list, control_destroy_walk, NULL );
+  
+  lttvwindow_unregister_constructor(h_guicontrol);
+  
+}
+
+
+LTTV_MODULE("guitracecontrol", "Trace Control Window", \
+    "Graphical module that let user control kernel tracing", \
+    init, destroy, "lttvwindow")
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/Makefile.am b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/Makefile.am
new file mode 100644 (file)
index 0000000..e65919e
--- /dev/null
@@ -0,0 +1,17 @@
+
+
+AM_CFLAGS = $(GLIB_CFLAGS) 
+LIBS += $(GLIB_LIBS) -lgobject-2.0 -L${top_srcdir}/ltt -llttvtraceread
+
+libdir = ${lttvplugindir}
+
+lib_LTLIBRARIES = libtextDump.la libbatchAnalysis.la libtextFilter.la
+libtextDump_la_LDFLAGS = -module
+libtextDump_la_SOURCES = textDump.c
+libbatchAnalysis_la_LDFLAGS = -module
+libbatchAnalysis_la_SOURCES = batchAnalysis.c
+libtextFilter_la_LDFLAGS = -module
+libtextFilter_la_SOURCES = textFilter.c
+
+noinst_HEADERS = \
+       batchanalysis.h
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/batchAnalysis.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/batchAnalysis.c
new file mode 100644 (file)
index 0000000..9cd2927
--- /dev/null
@@ -0,0 +1,245 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* This module inserts a hook in the program main loop. This hook processes 
+   all the events in the main tracefile. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+#include <lttv/option.h>
+#include <lttv/module.h>
+#include <lttv/tracecontext.h>
+#include <lttv/state.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+#include <ltt/trace.h>
+
+static LttvTraceset *traceset;
+
+static LttvHooks
+  *before_traceset,
+  *after_traceset,
+  *before_trace,
+  *after_trace,
+  *before_tracefile,
+  *after_tracefile,
+  *event_hook,
+  *main_hooks;
+
+static char *a_trace;
+
+static gboolean a_stats;
+
+void lttv_trace_option(void *hook_data)
+{ 
+  LttTrace *trace;
+
+  trace = ltt_trace_open(a_trace);
+  if(trace == NULL) g_critical("cannot open trace %s", a_trace);
+  lttv_traceset_add(traceset, lttv_trace_new(trace));
+}
+
+
+static gboolean process_traceset(void *hook_data, void *call_data)
+{
+  LttvAttributeValue value_expression, value_filter;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  LttvTracesetStats *tscs;
+
+  LttvTracesetContext *tc;
+
+  LttTime start, end;
+
+  g_info("BatchAnalysis begin process traceset");
+
+  tscs = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
+  tc = &tscs->parent.parent;
+
+  g_info("BatchAnalysis initialize context");
+
+  lttv_context_init(tc, traceset);
+  lttv_state_add_event_hooks(&tscs->parent);
+  if(a_stats) lttv_stats_add_event_hooks(tscs);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/expression",
+      LTTV_POINTER, &value_expression));
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/lttv_filter",
+      LTTV_POINTER, &value_filter));
+
+  *(value_filter.v_pointer) = lttv_filter_new();
+  g_debug("Filter string: %s",((GString*)*(value_expression.v_pointer))->str);
+  
+  lttv_filter_append_expression(*(value_filter.v_pointer),((GString*)*(value_expression.v_pointer))->str);
+  
+  //lttv_traceset_context_add_hooks(tc,
+  //before_traceset, after_traceset, NULL, before_trace, after_trace,
+  //NULL, before_tracefile, after_tracefile, NULL, before_event, after_event);
+  lttv_process_traceset_begin(tc,
+                              before_traceset,
+                              before_trace,
+                              before_tracefile,
+                              event_hook,
+                              NULL);
+
+  start.tv_sec = 0;
+  start.tv_nsec = 0;
+  end.tv_sec = G_MAXULONG;
+  end.tv_nsec = G_MAXULONG;
+
+  g_info("BatchAnalysis process traceset");
+
+  lttv_process_traceset_seek_time(tc, start);
+  lttv_process_traceset_middle(tc,
+                               end,
+                               G_MAXULONG,
+                               NULL);
+
+
+  //lttv_traceset_context_remove_hooks(tc,
+  //before_traceset, after_traceset, NULL, before_trace, after_trace,
+  //NULL, before_tracefile, after_tracefile, NULL, before_event, after_event);
+  lttv_process_traceset_end(tc,
+                            after_traceset,
+                            after_trace,
+                            after_tracefile,
+                            event_hook,
+                            NULL);
+
+  g_info("BatchAnalysis destroy context");
+
+  lttv_filter_destroy(*(value_filter.v_pointer));
+  lttv_state_remove_event_hooks(&tscs->parent);
+  if(a_stats) lttv_stats_remove_event_hooks(tscs);
+  lttv_context_fini(tc);
+  g_object_unref(tscs);
+
+  g_info("BatchAnalysis end process traceset");
+  return FALSE;
+}
+
+
+static void init()
+{
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  g_info("Init batchAnalysis.c");
+
+  lttv_option_add("trace", 't', 
+      "add a trace to the trace set to analyse", 
+      "pathname of the directory containing the trace", 
+      LTTV_OPT_STRING, &a_trace, lttv_trace_option, NULL);
+
+  a_stats = FALSE;
+  lttv_option_add("stats", 's', 
+      "write the traceset and trace statistics", 
+      "", 
+      LTTV_OPT_NONE, &a_stats, NULL, NULL);
+
+
+  traceset = lttv_traceset_new();
+
+  before_traceset = lttv_hooks_new();
+  after_traceset = lttv_hooks_new();
+  before_trace = lttv_hooks_new();
+  after_trace = lttv_hooks_new();
+  before_tracefile = lttv_hooks_new();
+  after_tracefile = lttv_hooks_new();
+  //before_event = lttv_hooks_new();
+  //after_event = lttv_hooks_new();
+  event_hook = lttv_hooks_new();
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_traceset;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_traceset;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_trace;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_trace;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/before",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = before_tracefile;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/after",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = after_tracefile;
+  //g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/before",
+  //    LTTV_POINTER, &value));
+  //*(value.v_pointer) = before_event;
+  //g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/after",
+  //    LTTV_POINTER, &value));
+  //*(value.v_pointer) = after_event;
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event",
+      LTTV_POINTER, &value));
+  *(value.v_pointer) = event_hook;
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before",
+      LTTV_POINTER, &value));
+  g_assert((main_hooks = *(value.v_pointer)) != NULL);
+  lttv_hooks_add(main_hooks, process_traceset, NULL, LTTV_PRIO_DEFAULT);
+}
+
+static void destroy()
+{
+  guint i, nb;
+
+  LttvTrace *trace;
+
+  g_info("Destroy batchAnalysis.c");
+
+  lttv_option_remove("trace");
+  lttv_option_remove("stats");
+
+  lttv_hooks_destroy(before_traceset);
+  lttv_hooks_destroy(after_traceset);
+  lttv_hooks_destroy(before_trace);
+  lttv_hooks_destroy(after_trace);
+  lttv_hooks_destroy(before_tracefile);
+  lttv_hooks_destroy(after_tracefile);
+  //lttv_hooks_destroy(before_event);
+  //lttv_hooks_destroy(after_event);
+  lttv_hooks_destroy(event_hook);
+  lttv_hooks_remove_data(main_hooks, process_traceset, NULL);
+
+  nb = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb ; i++) {
+    trace = lttv_traceset_get(traceset, i);
+    ltt_trace_close(lttv_trace(trace));
+    /* This will be done by lttv_traceset_destroy */
+    //lttv_trace_destroy(trace);
+  }
+
+  lttv_traceset_destroy(traceset); 
+}
+
+LTTV_MODULE("batchAnalysis", "Batch processing of a trace", \
+    "Run through a trace calling all the registered hooks", \
+    init, destroy, "state", "stats", "option","textFilter")
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/batchanalysis.h b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/batchanalysis.h
new file mode 100644 (file)
index 0000000..19fda35
--- /dev/null
@@ -0,0 +1,62 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+#ifndef BATCH_ANALYSIS_H
+#define BATCH_ANALYSIS_H
+
+/* The batch analysis module defines a main traceset and command line options
+   to specify the traces in the main traceset. It then processes that
+   traceset calling hooks lists at various stages of the analysis.
+
+   The hooks lists are defined in the global attributes for these various 
+   stages of the analysis. Loaded modules may add hooks to these lists.
+   Thus, by requesting that a certain module be loaded, the analysis may
+   produce additional information as the module adds hooks and these hooks
+   are called during the analysis.
+
+   The hooks lists defined are as follows. These may be split in more
+   specific lists eventually to select the hooks applicable to state update,
+   incremental or batch processing...
+   /hooks/traceset/before
+       Before analyzing a traceset.
+
+   /hooks/traceset/after
+       After analyzing a traceset.
+
+   /hooks/trace/before
+       Before each trace.
+
+   /hooks/trace/after
+       After each trace.
+
+   /hooks/tracefile/before
+       Before each tracefile.
+
+   /hooks/tracefile/after
+       After each tracefile.
+
+   /hooks/event/before
+       Before each event.
+
+   /hooks/event/after
+       After each event.
+
+*/
+
+#endif // BATCH_ANALYSIS_H
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/textDump.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/textDump.c
new file mode 100644 (file)
index 0000000..dbb8ec0
--- /dev/null
@@ -0,0 +1,362 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *               2005 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/* The text dump facility needs to print headers before the trace set and
+   before each trace, to print each event, and to print statistics
+   after each trace. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttv/option.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/attribute.h>
+#include <lttv/iattribute.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+#include <lttv/print.h>
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <stdio.h>
+
+static gboolean
+  a_field_names,
+  a_state,
+  a_cpu_stats,
+  a_process_stats;
+
+static char
+  *a_file_name = NULL;
+
+static LttvHooks
+  *before_traceset,
+  *after_traceset,
+  *before_trace,
+  *event_hook;
+
+
+static void 
+print_tree(FILE *fp, GString *indent, LttvAttribute *tree)
+{
+  int i, nb, saved_length;
+
+  LttvAttribute *subtree;
+
+  LttvAttributeName name;
+
+  LttvAttributeValue value;
+
+  LttvAttributeType type;
+
+  nb = lttv_attribute_get_number(tree);
+  for(i = 0 ; i < nb ; i++) {
+    type = lttv_attribute_get(tree, i, &name, &value);
+    fprintf(fp, "%s%s: ", indent->str, g_quark_to_string(name));
+
+    switch(type) {
+      case LTTV_INT:
+        fprintf(fp, "%d\n", *value.v_int);
+        break;
+      case LTTV_UINT:
+        fprintf(fp, "%u\n", *value.v_uint);
+        break;
+      case LTTV_LONG:
+        fprintf(fp, "%ld\n", *value.v_long);
+        break;
+      case LTTV_ULONG:
+        fprintf(fp, "%lu\n", *value.v_ulong);
+        break;
+      case LTTV_FLOAT:
+        fprintf(fp, "%f\n", (double)*value.v_float);
+        break;
+      case LTTV_DOUBLE:
+        fprintf(fp, "%f\n", *value.v_double);
+        break;
+      case LTTV_TIME:
+        fprintf(fp, "%10lu.%09lu\n", value.v_time->tv_sec, 
+            value.v_time->tv_nsec);
+        break;
+      case LTTV_POINTER:
+        fprintf(fp, "POINTER\n");
+        break;
+      case LTTV_STRING:
+        fprintf(fp, "%s\n", *value.v_string);
+        break;
+      case LTTV_GOBJECT:
+        if(LTTV_IS_ATTRIBUTE(*(value.v_gobject))) {
+          fprintf(fp, "\n");
+          subtree = (LttvAttribute *)*(value.v_gobject);
+          saved_length = indent->len; 
+          g_string_append(indent, "  ");
+          print_tree(fp, indent, subtree);
+          g_string_truncate(indent, saved_length);
+        }
+        else fprintf(fp, "GOBJECT\n");
+        break;
+      case LTTV_NONE:
+        break;
+    }
+  }
+}
+
+
+static void
+print_stats(FILE *fp, LttvTracesetStats *tscs)
+{
+  int i, nb, saved_length;
+
+  LttvTraceset *ts;
+
+  LttvTraceStats *tcs;
+
+  GString *indent;
+
+  LttSystemDescription *desc;
+
+  if(tscs->stats == NULL) return;
+  indent = g_string_new("");
+  fprintf(fp, "Traceset statistics:\n\n");
+  print_tree(fp, indent, tscs->stats);
+
+  ts = tscs->parent.parent.ts;
+  nb = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb ; i++) {
+    tcs = (LttvTraceStats *)(LTTV_TRACESET_CONTEXT(tscs)->traces[i]);
+#if 0 //FIXME
+    desc = ltt_trace_system_description(tcs->parent.parent.t);
+    LttTime start_time = ltt_trace_system_description_trace_start_time(desc);
+    fprintf(fp, "Trace on system %s at time %lu.%09lu :\n", 
+           ltt_trace_system_description_node_name(desc), 
+           start_time.tv_sec,
+      start_time.tv_nsec);
+#endif //FIXME
+    saved_length = indent->len;
+    g_string_append(indent, "  ");
+    print_tree(fp, indent, tcs->stats);
+    g_string_truncate(indent, saved_length);
+  }
+  g_string_free(indent, TRUE);
+}
+
+
+/* Insert the hooks before and after each trace and tracefile, and for each
+   event. Print a global header. */
+
+static FILE *a_file;
+
+static GString *a_string;
+
+static gboolean write_traceset_header(void *hook_data, void *call_data)
+{
+  LttvTracesetContext *tc = (LttvTracesetContext *)call_data;
+
+  g_info("TextDump traceset header");
+
+  if(a_file_name == NULL) a_file = stdout;
+  else a_file = fopen(a_file_name, "w");
+
+  if(a_file == NULL) g_error("cannot open file %s", a_file_name);
+
+  /* Print the trace set header */
+  fprintf(a_file,"Trace set contains %d traces\n\n", 
+      lttv_traceset_number(tc->ts));
+
+  return FALSE;
+}
+
+
+static gboolean write_traceset_footer(void *hook_data, void *call_data)
+{
+  LttvTracesetContext *tc = (LttvTracesetContext *)call_data;
+
+  g_info("TextDump traceset footer");
+
+  fprintf(a_file,"End trace set\n\n");
+
+  if(LTTV_IS_TRACESET_STATS(tc)) {
+    lttv_stats_sum_traceset((LttvTracesetStats *)tc);
+    print_stats(a_file, (LttvTracesetStats *)tc);
+  }
+
+  if(a_file_name != NULL) fclose(a_file);
+
+  return FALSE;
+}
+
+
+static gboolean write_trace_header(void *hook_data, void *call_data)
+{
+  LttvTraceContext *tc = (LttvTraceContext *)call_data;
+#if 0 //FIXME
+  LttSystemDescription *system = ltt_trace_system_description(tc->t);
+
+  fprintf(a_file,"  Trace from %s in %s\n%s\n\n", 
+         ltt_trace_system_description_node_name(system), 
+         ltt_trace_system_description_domain_name(system), 
+         ltt_trace_system_description_description(system));
+#endif //0
+  return FALSE;
+}
+
+
+static int write_event_content(void *hook_data, void *call_data)
+{
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+  
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+
+  LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+
+  LttEvent *e;
+
+  LttvAttributeValue value_filter;
+
+  LttvFilter *filter;
+
+  guint cpu = ltt_tracefile_num(tfs->parent.tf);
+  LttvTraceState *ts = (LttvTraceState*)tfc->t_context;
+  LttvProcessState *process = ts->running_process[cpu];
+
+  e = ltt_tracefile_get_event(tfc->tf);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/lttv_filter",
+      LTTV_POINTER, &value_filter));
+  filter = (LttvFilter*)*(value_filter.v_pointer);
+
+  /*
+   * call to the filter if available
+   */
+  if(filter->head != NULL)
+    if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
+                               tfc->t_context->t,tfc))
+      return FALSE;
+  
+  lttv_event_to_string(e, a_string, TRUE, a_field_names, tfs);
+  g_string_append_printf(a_string,"\n");  
+
+  if(a_state) {
+    g_string_append_printf(a_string, " %s ",
+        g_quark_to_string(process->state->s));
+  }
+
+  fputs(a_string->str, a_file);
+  return FALSE;
+}
+
+
+static void init()
+{
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  g_info("Init textDump.c");
+
+  a_string = g_string_new("");
+
+  a_file_name = NULL;
+  lttv_option_add("output", 'o', 
+      "output file where the text is written", 
+      "file name", 
+      LTTV_OPT_STRING, &a_file_name, NULL, NULL);
+
+  a_field_names = FALSE;
+  lttv_option_add("field_names", 'l', 
+      "write the field names for each event", 
+      "", 
+      LTTV_OPT_NONE, &a_field_names, NULL, NULL);
+
+  a_state = FALSE;
+  lttv_option_add("process_state", 's', 
+      "write the pid and state for each event", 
+      "", 
+      LTTV_OPT_NONE, &a_state, NULL, NULL);
+
+  a_cpu_stats = FALSE;
+  lttv_option_add("cpu_stats", 'c', 
+      "write the per cpu statistics", 
+      "", 
+      LTTV_OPT_NONE, &a_cpu_stats, NULL, NULL);
+
+  a_process_stats = FALSE;
+  lttv_option_add("process_stats", 'p', 
+      "write the per process statistics", 
+      "", 
+      LTTV_OPT_NONE, &a_process_stats, NULL, NULL);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event",
+      LTTV_POINTER, &value));
+  g_assert((event_hook = *(value.v_pointer)) != NULL);
+  lttv_hooks_add(event_hook, write_event_content, NULL, LTTV_PRIO_DEFAULT);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before",
+      LTTV_POINTER, &value));
+  g_assert((before_trace = *(value.v_pointer)) != NULL);
+  lttv_hooks_add(before_trace, write_trace_header, NULL, LTTV_PRIO_DEFAULT);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before",
+      LTTV_POINTER, &value));
+  g_assert((before_traceset = *(value.v_pointer)) != NULL);
+  lttv_hooks_add(before_traceset, write_traceset_header, NULL,
+      LTTV_PRIO_DEFAULT);
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after",
+      LTTV_POINTER, &value));
+  g_assert((after_traceset = *(value.v_pointer)) != NULL);
+  lttv_hooks_add(after_traceset, write_traceset_footer, NULL,
+      LTTV_PRIO_DEFAULT);
+}
+
+static void destroy()
+{
+  g_info("Destroy textDump");
+
+  lttv_option_remove("output");
+
+  lttv_option_remove("field_names");
+
+  lttv_option_remove("process_state");
+
+  lttv_option_remove("cpu_stats");
+
+  lttv_option_remove("process_stats");
+
+  g_string_free(a_string, TRUE);
+
+  lttv_hooks_remove_data(event_hook, write_event_content, NULL);
+
+  lttv_hooks_remove_data(before_trace, write_trace_header, NULL);
+
+  lttv_hooks_remove_data(before_trace, write_traceset_header, NULL);
+
+  lttv_hooks_remove_data(before_trace, write_traceset_footer, NULL);
+}
+
+
+LTTV_MODULE("textDump", "Print events in a file", \
+           "Produce a detailed text printout of a trace", \
+           init, destroy, "stats", "batchAnalysis", "option", "print")
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/textFilter.c b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/lttv/modules/text/textFilter.c
new file mode 100644 (file)
index 0000000..7dcca63
--- /dev/null
@@ -0,0 +1,228 @@
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2005 Simon Bouvier-Zappa 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
+/*! \file lttv/modules/text/textFilter.c
+ *  \brief Textual prompt for user filtering expression.
+ *  
+ *  The text filter facility will prompt for user filter option 
+ *  and transmit them to the lttv core.  User can either specify 
+ *  a filtering string with the command line or/and specify a 
+ *  file containing filtering expressions.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lttv/lttv.h>
+#include <lttv/option.h>
+#include <lttv/module.h>
+#include <lttv/hook.h>
+#include <lttv/attribute.h>
+#include <lttv/iattribute.h>
+#include <lttv/stats.h>
+#include <lttv/filter.h>
+#include <ltt/ltt.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+#include <ltt/trace.h>
+#include <ltt/facility.h>
+#include <stdio.h>
+
+/* Insert the hooks before and after each trace and tracefile, and for each
+   event. Print a global header. */
+
+/*
+ *  YET TO BE ANSWERED !
+ *  - why does this module need dependency with batchAnalysis ?
+ */
+
+/*
+ *  TODO
+ *  - specify wich hook function will be used to call the core filter
+ */
+
+static char 
+  *a_file_name = NULL,
+  *a_string = NULL;
+
+static LttvHooks
+  *before_traceset,
+  *event_hook;
+
+/**
+ * filters the file input from user
+ * @param hook_data the hook data, unused
+ */
+void filter_analyze_file(void *hook_data) {
+
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  /*
+        *      User may specify filtering options through static file
+        *      and/or command line string.  From these sources, an 
+        *      option string is rebuilded and sent to the filter core
+        */
+  if(!g_file_test(a_file_name,G_FILE_TEST_EXISTS)) {
+    g_warning("file %s does not exist", a_file_name);
+    return;
+  }
+
+  char* a_file_content = NULL;
+
+  g_file_get_contents(a_file_name,&a_file_content,NULL,NULL);
+  
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/expression",
+      LTTV_POINTER, &value));
+
+  if(((GString*)*(value.v_pointer))->len != 0) g_string_append_c((GString*)*(value.v_pointer),'&');
+  g_string_append_c((GString*)*(value.v_pointer),'(');
+  g_string_append((GString*)*(value.v_pointer),a_file_content);
+  g_string_append_c((GString*)*(value.v_pointer),')');
+  
+}
+
+/**
+ * filters the string input from user
+ * @param hook_data the hook data, unused
+ */
+void filter_analyze_string(void *hook_data) {
+
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+  
+  /*
+        *      User may specify filtering options through static file
+        *      and/or command line string.  From these sources, an 
+        *      option string is rebuilded and sent to the filter core
+        */
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/expression",
+      LTTV_POINTER, &value));
+
+  if(((GString*)*(value.v_pointer))->len != 0) g_string_append_c((GString*)*(value.v_pointer),'&');
+  g_string_append_c((GString*)*(value.v_pointer),'(');
+  g_string_append((GString*)*(value.v_pointer),a_string);
+  g_string_append_c((GString*)*(value.v_pointer),')');
+
+}
+
+/**
+ * Output all filter commands on console 
+ * @param hook_data the hook data
+ */
+void filter_list_commands(void *hook_data) {
+
+  g_print("[field] [op] [value]\n\n");
+
+  g_print("*** Possible fields ***\n");
+  g_print("event.name (string)\n");
+  g_print("event.facility (string)\n");
+  g_print("event.category (string)\n");
+  g_print("event.time (double)\n");
+  g_print("event.tsc (integer)\n");
+  g_print("tracefile.name (string)\n");
+  g_print("trace.name (string)\n");
+  g_print("state.pid (integer)\n");
+  g_print("state.ppid (integer)\n");
+  g_print("state.creation_time (double)\n");
+  g_print("trace.insertion_time (double)\n");
+  g_print("trace.process_name (string)\n");
+  g_print("trace.execution_mode (string)\n");
+  g_print("trace.execution_submode (string)\n");
+  g_print("trace.process_status (string)\n");
+  g_print("trace.cpu (string)\n\n");
+  
+  g_print("*** Possible operators ***\n");
+  g_print("equal '='\n");
+  g_print("not equal '!='\n");
+  g_print("greater '>'\n");
+  g_print("greater or equal '>='\n");
+  g_print("lower '<'\n");
+  g_print("lower or equal '<='\n");
+  g_print("*** Possible values ***\n");
+  g_print("string, integer, double");
+}
+
+/**
+ *     initialize the new module
+ */
+static void init() {
+  
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/expression",
+      LTTV_POINTER, &value));
+  
+  *(value.v_pointer) = g_string_new("");
+
+  g_info("Init textFilter.c");
+  a_string = NULL;
+  lttv_option_add("expression", 'e', 
+      "filters a string issued by the user on the command line", 
+      "string", 
+      LTTV_OPT_STRING, &a_string, filter_analyze_string, NULL);
+  // add function to call for option
+  
+  a_file_name = NULL;
+  lttv_option_add("filename", 'f', 
+      "browse the filter options contained in specified file", 
+      "file name", 
+      LTTV_OPT_STRING, &a_file_name, filter_analyze_file, NULL);
+
+  lttv_option_add("list", 'l',
+      "list all possible filter commands for module",
+      "list commands",
+      LTTV_OPT_NONE, NULL, filter_list_commands, NULL);
+  
+}
+
+/**
+ *     Destroy the current module
+ */
+static void destroy() {
+  g_info("Destroy textFilter");
+
+  lttv_option_remove("expression");
+
+  lttv_option_remove("filename");
+
+  lttv_option_remove("list");
+
+  LttvAttributeValue value;
+
+  LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
+
+  g_assert(lttv_iattribute_find_by_path(attributes, "filter/expression",
+      LTTV_POINTER, &value));
+  g_string_free((GString*)*(value.v_pointer),TRUE);
+  
+}
+
+
+LTTV_MODULE("textFilter", "Filters traces", \
+           "Filter the trace following commands issued by user input", \
+           init, destroy, "option")
+
diff --git a/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/profile.sh b/ltt/trunk/LinuxTraceToolkitViewer-0.6.9/profile.sh
new file mode 100755 (executable)
index 0000000..0c0a3fc
--- /dev/null
@@ -0,0 +1,41 @@
+#! /bin/sh
+
+# Script to build three versions of ltt/lttv (optimized, optimized and profiled
+# and not optimized) and compare their performance for processing a trace.
+# The profiled version produces detailed per function timings.
+#
+# The script expects 2 arguments: the temporary directory where to install
+# the three versions and the directory containing the trace to process.
+
+v1=$1/ltt1
+v2=$1/ltt2
+v3=$1/ltt3
+tracedir=$2
+
+if [ -z "$1" -o -z "$tracedir" ]; then
+  echo "Usage: $0 tmpdir trace"
+  exit 1
+fi
+
+BuildTest () {
+  (make clean; ./autogen.sh --prefix=$1 --enable-lttvstatic CFLAGS="$2" LDFLAGS="$3"; make; make install) >& build.`basename $1`
+}
+
+RunTest () {
+  echo RunTest $1 $2
+  rm gmon.out
+  for version in $v1 $v2 $v3; do
+    /usr/bin/time $version/bin/lttv -m batchtest -t $tracedir $1 >& test.`basename $version`.$2
+  done
+  gprof $v2/bin/lttv >& test.profile.$2
+}
+
+BuildTest $v1 "-O2 -g" "-g"
+BuildTest $v2 "-pg -g -O2" "-pg -g"
+BuildTest $v3 "-g" "-g"
+
+RunTest --test1 countevents
+RunTest --test2 computestate
+RunTest --test4 computestats
+RunTest --test6 savestate
+RunTest "--test3 --test6 --test7 --seek-number 200" seekevents
This page took 0.896266 seconds and 4 git commands to generate.