Commit d03d508ebf29745d1a92dd3581793e8bacb12ccf
authorMichel Pollet <buserror@gmail.com>
Fri, 1 Jun 2012 22:17:00 +0000 (23:17 +0100)
committerMichel Pollet <buserror@gmail.com>
Fri, 1 Jun 2012 22:17:00 +0000 (23:17 +0100)
probably last update befire I spin it out

Signed-off-by: Michel Pollet <buserror@gmail.com>
85 files changed:
examples/board_reprap/Makefile
examples/board_reprap/gfx/BlurryCircle.png
examples/board_reprap/gfx/BlurryCircle16.png [new file with mode: 0644]
examples/board_reprap/gfx/BlurryCircle4.png [new file with mode: 0644]
examples/board_reprap/gfx/BlurryCircle8.png [new file with mode: 0644]
examples/board_reprap/gfx/Fxaa3_11.h [new file with mode: 0644]
examples/board_reprap/gfx/hb.png [new file with mode: 0644]
examples/board_reprap/gfx/postproc.fs [new file with mode: 0644]
examples/board_reprap/gfx/postproc.vs [new file with mode: 0644]
examples/board_reprap/marlin/Marlin.hex
examples/board_reprap/reprap_flash.bin [new file with mode: 0644]
examples/board_reprap/src/c3/README.md [deleted file]
examples/board_reprap/src/c3/c3.c [deleted file]
examples/board_reprap/src/c3/c3.h [deleted file]
examples/board_reprap/src/c3/c3algebra.c [deleted file]
examples/board_reprap/src/c3/c3algebra.h [deleted file]
examples/board_reprap/src/c3/c3arcball.c [deleted file]
examples/board_reprap/src/c3/c3arcball.h [deleted file]
examples/board_reprap/src/c3/c3cairo.c [deleted file]
examples/board_reprap/src/c3/c3cairo.h [deleted file]
examples/board_reprap/src/c3/c3camera.c [deleted file]
examples/board_reprap/src/c3/c3camera.h [deleted file]
examples/board_reprap/src/c3/c3context.c [deleted file]
examples/board_reprap/src/c3/c3context.h [deleted file]
examples/board_reprap/src/c3/c3driver.h [deleted file]
examples/board_reprap/src/c3/c3driver_context.h [deleted file]
examples/board_reprap/src/c3/c3driver_geometry.h [deleted file]
examples/board_reprap/src/c3/c3driver_object.h [deleted file]
examples/board_reprap/src/c3/c3geometry.c [deleted file]
examples/board_reprap/src/c3/c3geometry.h [deleted file]
examples/board_reprap/src/c3/c3object.c [deleted file]
examples/board_reprap/src/c3/c3object.h [deleted file]
examples/board_reprap/src/c3/c3pixels.c [deleted file]
examples/board_reprap/src/c3/c3pixels.h [deleted file]
examples/board_reprap/src/c3/c3quaternion.c [deleted file]
examples/board_reprap/src/c3/c3quaternion.h [deleted file]
examples/board_reprap/src/c3/c3stl.c [deleted file]
examples/board_reprap/src/c3/c3stl.h [deleted file]
examples/board_reprap/src/c3/c3texture.c [deleted file]
examples/board_reprap/src/c3/c3texture.h [deleted file]
examples/board_reprap/src/c3/c3transform.c [deleted file]
examples/board_reprap/src/c3/c3transform.h [deleted file]
examples/board_reprap/src/c3/c_array.h [deleted file]
examples/board_reprap/src/c3/c_utils.c [deleted file]
examples/board_reprap/src/c3/c_utils.h [deleted file]
examples/board_reprap/src/reprap_gl.c
examples/shared/libc3/Makefile [new file with mode: 0644]
examples/shared/libc3/README.md [new file with mode: 0644]
examples/shared/libc3/libc3.pc [new file with mode: 0644]
examples/shared/libc3/src/c3.c [new file with mode: 0644]
examples/shared/libc3/src/c3.h [new file with mode: 0644]
examples/shared/libc3/src/c3algebra.c [new file with mode: 0644]
examples/shared/libc3/src/c3algebra.h [new file with mode: 0644]
examples/shared/libc3/src/c3arcball.c [new file with mode: 0644]
examples/shared/libc3/src/c3arcball.h [new file with mode: 0644]
examples/shared/libc3/src/c3cairo.c [new file with mode: 0644]
examples/shared/libc3/src/c3cairo.h [new file with mode: 0644]
examples/shared/libc3/src/c3camera.c [new file with mode: 0644]
examples/shared/libc3/src/c3camera.h [new file with mode: 0644]
examples/shared/libc3/src/c3config.h [new file with mode: 0644]
examples/shared/libc3/src/c3context.c [new file with mode: 0644]
examples/shared/libc3/src/c3context.h [new file with mode: 0644]
examples/shared/libc3/src/c3driver.h [new file with mode: 0644]
examples/shared/libc3/src/c3driver_context.h [new file with mode: 0644]
examples/shared/libc3/src/c3driver_geometry.h [new file with mode: 0644]
examples/shared/libc3/src/c3driver_object.h [new file with mode: 0644]
examples/shared/libc3/src/c3geometry.c [new file with mode: 0644]
examples/shared/libc3/src/c3geometry.h [new file with mode: 0644]
examples/shared/libc3/src/c3lines.c [new file with mode: 0644]
examples/shared/libc3/src/c3lines.h [new file with mode: 0644]
examples/shared/libc3/src/c3object.c [new file with mode: 0644]
examples/shared/libc3/src/c3object.h [new file with mode: 0644]
examples/shared/libc3/src/c3pixels.c [new file with mode: 0644]
examples/shared/libc3/src/c3pixels.h [new file with mode: 0644]
examples/shared/libc3/src/c3quaternion.c [new file with mode: 0644]
examples/shared/libc3/src/c3quaternion.h [new file with mode: 0644]
examples/shared/libc3/src/c3stl.c [new file with mode: 0644]
examples/shared/libc3/src/c3stl.h [new file with mode: 0644]
examples/shared/libc3/src/c3texture.c [new file with mode: 0644]
examples/shared/libc3/src/c3texture.h [new file with mode: 0644]
examples/shared/libc3/src/c3transform.c [new file with mode: 0644]
examples/shared/libc3/src/c3transform.h [new file with mode: 0644]
examples/shared/libc3/src/c_array.h [new file with mode: 0644]
examples/shared/libc3/src/c_utils.c [new file with mode: 0644]
examples/shared/libc3/src/c_utils.h [new file with mode: 0644]

index d3c2cb4f5064008d7cffac2d249eaef7cfb7765e..50b4e3b90889ccd4b303cd1884918eb4ad229686 100644 (file)
@@ -21,15 +21,17 @@ firm_src = ${wildcard atmega*.c}
 firmware = ${firm_src:.c=.hex}
 simavr = ../../
 
+LIBC3  = ../shared/libc3
+
 IPATH = .
 IPATH += src
 IPATH += ../parts
 IPATH += ../shared
+IPATH += $(LIBC3)/src
 IPATH += ${simavr}/include
 IPATH += ${simavr}/simavr/sim
 
 VPATH = src
-VPATH += src/c3
 VPATH += ../parts
 VPATH += ../shared
 
@@ -42,9 +44,7 @@ include ../Makefile.opengl
 LDFLAGS += ${shell pkg-config --libs pangocairo}
 LDFLAGS += -lpthread -lutil -ldl
 LDFLAGS += -lm
-
-C3SRC  = ${wildcard src/c3/*.c}
-C3OBJ  = ${patsubst src/c3%,${OBJ}%,${C3SRC:.c=.o}}
+LDFLAGS += -rpath $(LIBC3)/${OBJ}/.libs -L$(LIBC3)/${OBJ}/.libs -lc3
 
 CPPFLAGS       += ${patsubst %,-I%,${subst :, ,${IPATH}}}
 
@@ -55,18 +55,19 @@ include ${simavr}/Makefile.common
 
 board = ${OBJ}/${target}.elf
 
-${board} : ${C3OBJ}
 ${board} : ${OBJ}/mongoose.o
 ${board} : ${OBJ}/button.o
 ${board} : ${OBJ}/uart_pty.o
 ${board} : ${OBJ}/thermistor.o
 ${board} : ${OBJ}/heatpot.o
 ${board} : ${OBJ}/stepper.o
-${board} : ${OBJ}/c_utils.o
 ${board} : ${OBJ}/${target}.o
 ${board} : ${OBJ}/${target}_gl.o
 
-${target}: ${board}
+build-libc3:
+       $(MAKE) -C $(LIBC3) CC="$(CC)" CFLAGS="$(CFLAGS)"
+
+${target}:  build-libc3 ${board}
        @echo $@ done
 
 clean: clean-${OBJ}
index 9490ccf6ddd0f5d0f45899aba9774f8a2af1f346..a8a316bed16d835b8aa72898adf5d07ac965ff13 100644 (file)
Binary files a/examples/board_reprap/gfx/BlurryCircle.png and b/examples/board_reprap/gfx/BlurryCircle.png differ
diff --git a/examples/board_reprap/gfx/BlurryCircle16.png b/examples/board_reprap/gfx/BlurryCircle16.png
new file mode 100644 (file)
index 0000000..d619bc1
Binary files /dev/null and b/examples/board_reprap/gfx/BlurryCircle16.png differ
diff --git a/examples/board_reprap/gfx/BlurryCircle4.png b/examples/board_reprap/gfx/BlurryCircle4.png
new file mode 100644 (file)
index 0000000..82b48d8
Binary files /dev/null and b/examples/board_reprap/gfx/BlurryCircle4.png differ
diff --git a/examples/board_reprap/gfx/BlurryCircle8.png b/examples/board_reprap/gfx/BlurryCircle8.png
new file mode 100644 (file)
index 0000000..64ff0a7
Binary files /dev/null and b/examples/board_reprap/gfx/BlurryCircle8.png differ
diff --git a/examples/board_reprap/gfx/Fxaa3_11.h b/examples/board_reprap/gfx/Fxaa3_11.h
new file mode 100644 (file)
index 0000000..a2abfec
--- /dev/null
@@ -0,0 +1,2047 @@
+/*============================================================================\r
+\r
+\r
+                    NVIDIA FXAA 3.11 by TIMOTHY LOTTES\r
+\r
+\r
+------------------------------------------------------------------------------\r
+COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.\r
+------------------------------------------------------------------------------\r
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED\r
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA\r
+OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR\r
+CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR\r
+LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,\r
+OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE\r
+THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
+DAMAGES.\r
+\r
+------------------------------------------------------------------------------\r
+                           INTEGRATION CHECKLIST\r
+------------------------------------------------------------------------------\r
+(1.)\r
+In the shader source, setup defines for the desired configuration.\r
+When providing multiple shaders (for different presets),\r
+simply setup the defines differently in multiple files.\r
+Example,\r
+\r
+  #define FXAA_PC 1\r
+  #define FXAA_HLSL_5 1\r
+  #define FXAA_QUALITY__PRESET 12\r
+\r
+Or,\r
+\r
+  #define FXAA_360 1\r
+  \r
+Or,\r
+\r
+  #define FXAA_PS3 1\r
+  \r
+Etc.\r
+\r
+(2.)\r
+Then include this file,\r
+\r
+  #include "Fxaa3_11.h"\r
+\r
+(3.)\r
+Then call the FXAA pixel shader from within your desired shader.\r
+Look at the FXAA Quality FxaaPixelShader() for docs on inputs.\r
+As for FXAA 3.11 all inputs for all shaders are the same \r
+to enable easy porting between platforms.\r
+\r
+  return FxaaPixelShader(...);\r
+\r
+(4.)\r
+Insure pass prior to FXAA outputs RGBL (see next section).\r
+Or use,\r
+\r
+  #define FXAA_GREEN_AS_LUMA 1\r
+\r
+(5.)\r
+Setup engine to provide the following constants\r
+which are used in the FxaaPixelShader() inputs,\r
+\r
+  FxaaFloat2 fxaaQualityRcpFrame,\r
+  FxaaFloat4 fxaaConsoleRcpFrameOpt,\r
+  FxaaFloat4 fxaaConsoleRcpFrameOpt2,\r
+  FxaaFloat4 fxaaConsole360RcpFrameOpt2,\r
+  FxaaFloat fxaaQualitySubpix,\r
+  FxaaFloat fxaaQualityEdgeThreshold,\r
+  FxaaFloat fxaaQualityEdgeThresholdMin,\r
+  FxaaFloat fxaaConsoleEdgeSharpness,\r
+  FxaaFloat fxaaConsoleEdgeThreshold,\r
+  FxaaFloat fxaaConsoleEdgeThresholdMin,\r
+  FxaaFloat4 fxaaConsole360ConstDir\r
+\r
+Look at the FXAA Quality FxaaPixelShader() for docs on inputs.\r
+\r
+(6.)\r
+Have FXAA vertex shader run as a full screen triangle,\r
+and output "pos" and "fxaaConsolePosPos" \r
+such that inputs in the pixel shader provide,\r
+\r
+  // {xy} = center of pixel\r
+  FxaaFloat2 pos,\r
+\r
+  // {xy__} = upper left of pixel\r
+  // {__zw} = lower right of pixel\r
+  FxaaFloat4 fxaaConsolePosPos,\r
+\r
+(7.)\r
+Insure the texture sampler(s) used by FXAA are set to bilinear filtering.\r
+\r
+\r
+------------------------------------------------------------------------------\r
+                    INTEGRATION - RGBL AND COLORSPACE\r
+------------------------------------------------------------------------------\r
+FXAA3 requires RGBL as input unless the following is set, \r
+\r
+  #define FXAA_GREEN_AS_LUMA 1\r
+\r
+In which case the engine uses green in place of luma,\r
+and requires RGB input is in a non-linear colorspace.\r
+\r
+RGB should be LDR (low dynamic range).\r
+Specifically do FXAA after tonemapping.\r
+\r
+RGB data as returned by a texture fetch can be non-linear,\r
+or linear when FXAA_GREEN_AS_LUMA is not set.\r
+Note an "sRGB format" texture counts as linear,\r
+because the result of a texture fetch is linear data.\r
+Regular "RGBA8" textures in the sRGB colorspace are non-linear.\r
+\r
+If FXAA_GREEN_AS_LUMA is not set,\r
+luma must be stored in the alpha channel prior to running FXAA.\r
+This luma should be in a perceptual space (could be gamma 2.0).\r
+Example pass before FXAA where output is gamma 2.0 encoded,\r
+\r
+  color.rgb = ToneMap(color.rgb); // linear color output\r
+  color.rgb = sqrt(color.rgb);    // gamma 2.0 color output\r
+  return color;\r
+\r
+To use FXAA,\r
+\r
+  color.rgb = ToneMap(color.rgb);  // linear color output\r
+  color.rgb = sqrt(color.rgb);     // gamma 2.0 color output\r
+  color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma\r
+  return color;\r
+\r
+Another example where output is linear encoded,\r
+say for instance writing to an sRGB formated render target,\r
+where the render target does the conversion back to sRGB after blending,\r
+\r
+  color.rgb = ToneMap(color.rgb); // linear color output\r
+  return color;\r
+\r
+To use FXAA,\r
+\r
+  color.rgb = ToneMap(color.rgb); // linear color output\r
+  color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma\r
+  return color;\r
+\r
+Getting luma correct is required for the algorithm to work correctly.\r
+\r
+\r
+------------------------------------------------------------------------------\r
+                          BEING LINEARLY CORRECT?\r
+------------------------------------------------------------------------------\r
+Applying FXAA to a framebuffer with linear RGB color will look worse.\r
+This is very counter intuitive, but happends to be true in this case.\r
+The reason is because dithering artifacts will be more visiable \r
+in a linear colorspace.\r
+\r
+\r
+------------------------------------------------------------------------------\r
+                             COMPLEX INTEGRATION\r
+------------------------------------------------------------------------------\r
+Q. What if the engine is blending into RGB before wanting to run FXAA?\r
+\r
+A. In the last opaque pass prior to FXAA,\r
+   have the pass write out luma into alpha.\r
+   Then blend into RGB only.\r
+   FXAA should be able to run ok\r
+   assuming the blending pass did not any add aliasing.\r
+   This should be the common case for particles and common blending passes.\r
+\r
+A. Or use FXAA_GREEN_AS_LUMA.\r
+\r
+============================================================================*/\r
+\r
+/*============================================================================\r
+\r
+                             INTEGRATION KNOBS\r
+\r
+============================================================================*/\r
+//\r
+// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE).\r
+// FXAA_360_OPT is a prototype for the new optimized 360 version.\r
+//\r
+// 1 = Use API.\r
+// 0 = Don't use API.\r
+//\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_PS3\r
+    #define FXAA_PS3 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_360\r
+    #define FXAA_360 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_360_OPT\r
+    #define FXAA_360_OPT 0\r
+#endif\r
+/*==========================================================================*/\r
+#ifndef FXAA_PC\r
+    //\r
+    // FXAA Quality\r
+    // The high quality PC algorithm.\r
+    //\r
+    #define FXAA_PC 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_PC_CONSOLE\r
+    //\r
+    // The console algorithm for PC is included\r
+    // for developers targeting really low spec machines.\r
+    // Likely better to just run FXAA_PC, and use a really low preset.\r
+    //\r
+    #define FXAA_PC_CONSOLE 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_GLSL_120\r
+    #define FXAA_GLSL_120 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_GLSL_130\r
+    #define FXAA_GLSL_130 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_HLSL_3\r
+    #define FXAA_HLSL_3 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_HLSL_4\r
+    #define FXAA_HLSL_4 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_HLSL_5\r
+    #define FXAA_HLSL_5 0\r
+#endif\r
+/*==========================================================================*/\r
+#ifndef FXAA_GREEN_AS_LUMA\r
+    //\r
+    // For those using non-linear color,\r
+    // and either not able to get luma in alpha, or not wanting to,\r
+    // this enables FXAA to run using green as a proxy for luma.\r
+    // So with this enabled, no need to pack luma in alpha.\r
+    //\r
+    // This will turn off AA on anything which lacks some amount of green.\r
+    // Pure red and blue or combination of only R and B, will get no AA.\r
+    //\r
+    // Might want to lower the settings for both,\r
+    //    fxaaConsoleEdgeThresholdMin\r
+    //    fxaaQualityEdgeThresholdMin\r
+    // In order to insure AA does not get turned off on colors \r
+    // which contain a minor amount of green.\r
+    //\r
+    // 1 = On.\r
+    // 0 = Off.\r
+    //\r
+    #define FXAA_GREEN_AS_LUMA 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_EARLY_EXIT\r
+    //\r
+    // Controls algorithm's early exit path.\r
+    // On PS3 turning this ON adds 2 cycles to the shader.\r
+    // On 360 turning this OFF adds 10ths of a millisecond to the shader.\r
+    // Turning this off on console will result in a more blurry image.\r
+    // So this defaults to on.\r
+    //\r
+    // 1 = On.\r
+    // 0 = Off.\r
+    //\r
+    #define FXAA_EARLY_EXIT 1\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_DISCARD\r
+    //\r
+    // Only valid for PC OpenGL currently.\r
+    // Probably will not work when FXAA_GREEN_AS_LUMA = 1.\r
+    //\r
+    // 1 = Use discard on pixels which don't need AA.\r
+    //     For APIs which enable concurrent TEX+ROP from same surface.\r
+    // 0 = Return unchanged color on pixels which don't need AA.\r
+    //\r
+    #define FXAA_DISCARD 0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_FAST_PIXEL_OFFSET\r
+    //\r
+    // Used for GLSL 120 only.\r
+    //\r
+    // 1 = GL API supports fast pixel offsets\r
+    // 0 = do not use fast pixel offsets\r
+    //\r
+    #ifdef GL_EXT_gpu_shader4\r
+        #define FXAA_FAST_PIXEL_OFFSET 1\r
+    #endif\r
+    #ifdef GL_NV_gpu_shader5\r
+        #define FXAA_FAST_PIXEL_OFFSET 1\r
+    #endif\r
+    #ifdef GL_ARB_gpu_shader5\r
+        #define FXAA_FAST_PIXEL_OFFSET 1\r
+    #endif\r
+    #ifndef FXAA_FAST_PIXEL_OFFSET\r
+        #define FXAA_FAST_PIXEL_OFFSET 0\r
+    #endif\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_GATHER4_ALPHA\r
+    //\r
+    // 1 = API supports gather4 on alpha channel.\r
+    // 0 = API does not support gather4 on alpha channel.\r
+    //\r
+    #if (FXAA_HLSL_5 == 1)\r
+        #define FXAA_GATHER4_ALPHA 1\r
+    #endif\r
+    #ifdef GL_ARB_gpu_shader5\r
+        #define FXAA_GATHER4_ALPHA 1\r
+    #endif\r
+    #ifdef GL_NV_gpu_shader5\r
+        #define FXAA_GATHER4_ALPHA 1\r
+    #endif\r
+    #ifndef FXAA_GATHER4_ALPHA\r
+        #define FXAA_GATHER4_ALPHA 0\r
+    #endif\r
+#endif\r
+\r
+/*============================================================================\r
+                      FXAA CONSOLE PS3 - TUNING KNOBS\r
+============================================================================*/\r
+#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS\r
+    //\r
+    // Consoles the sharpness of edges on PS3 only.\r
+    // Non-PS3 tuning is done with shader input.\r
+    //\r
+    // Due to the PS3 being ALU bound,\r
+    // there are only two safe values here: 4 and 8.\r
+    // These options use the shaders ability to a free *|/ by 2|4|8.\r
+    //\r
+    // 8.0 is sharper\r
+    // 4.0 is softer\r
+    // 2.0 is really soft (good for vector graphics inputs)\r
+    //\r
+    #if 1\r
+        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0\r
+    #endif\r
+    #if 0\r
+        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0\r
+    #endif\r
+    #if 0\r
+        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0\r
+    #endif\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD\r
+    //\r
+    // Only effects PS3.\r
+    // Non-PS3 tuning is done with shader input.\r
+    //\r
+    // The minimum amount of local contrast required to apply algorithm.\r
+    // The console setting has a different mapping than the quality setting.\r
+    //\r
+    // This only applies when FXAA_EARLY_EXIT is 1.\r
+    //\r
+    // Due to the PS3 being ALU bound,\r
+    // there are only two safe values here: 0.25 and 0.125.\r
+    // These options use the shaders ability to a free *|/ by 2|4|8.\r
+    //\r
+    // 0.125 leaves less aliasing, but is softer\r
+    // 0.25 leaves more aliasing, and is sharper\r
+    //\r
+    #if 1\r
+        #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125\r
+    #else\r
+        #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25\r
+    #endif\r
+#endif\r
+\r
+/*============================================================================\r
+                        FXAA QUALITY - TUNING KNOBS\r
+------------------------------------------------------------------------------\r
+NOTE the other tuning knobs are now in the shader function inputs!\r
+============================================================================*/\r
+#ifndef FXAA_QUALITY__PRESET\r
+    //\r
+    // Choose the quality preset.\r
+    // This needs to be compiled into the shader as it effects code.\r
+    // Best option to include multiple presets is to \r
+    // in each shader define the preset, then include this file.\r
+    // \r
+    // OPTIONS\r
+    // -----------------------------------------------------------------------\r
+    // 10 to 15 - default medium dither (10=fastest, 15=highest quality)\r
+    // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)\r
+    // 39       - no dither, very expensive \r
+    //\r
+    // NOTES\r
+    // -----------------------------------------------------------------------\r
+    // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)\r
+    // 13 = about same speed as FXAA 3.9 and better than 12\r
+    // 23 = closest to FXAA 3.9 visually and performance wise\r
+    //  _ = the lowest digit is directly related to performance\r
+    // _  = the highest digit is directly related to style\r
+    // \r
+    #define FXAA_QUALITY__PRESET 12\r
+#endif\r
+\r
+\r
+/*============================================================================\r
+\r
+                           FXAA QUALITY - PRESETS\r
+\r
+============================================================================*/\r
+\r
+/*============================================================================\r
+                     FXAA QUALITY - MEDIUM DITHER PRESETS\r
+============================================================================*/\r
+#if (FXAA_QUALITY__PRESET == 10)\r
+    #define FXAA_QUALITY__PS 3\r
+    #define FXAA_QUALITY__P0 1.5\r
+    #define FXAA_QUALITY__P1 3.0\r
+    #define FXAA_QUALITY__P2 12.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 11)\r
+    #define FXAA_QUALITY__PS 4\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 3.0\r
+    #define FXAA_QUALITY__P3 12.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 12)\r
+    #define FXAA_QUALITY__PS 5\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 4.0\r
+    #define FXAA_QUALITY__P4 12.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 13)\r
+    #define FXAA_QUALITY__PS 6\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 4.0\r
+    #define FXAA_QUALITY__P5 12.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 14)\r
+    #define FXAA_QUALITY__PS 7\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 4.0\r
+    #define FXAA_QUALITY__P6 12.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 15)\r
+    #define FXAA_QUALITY__PS 8\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 2.0\r
+    #define FXAA_QUALITY__P6 4.0\r
+    #define FXAA_QUALITY__P7 12.0\r
+#endif\r
+\r
+/*============================================================================\r
+                     FXAA QUALITY - LOW DITHER PRESETS\r
+============================================================================*/\r
+#if (FXAA_QUALITY__PRESET == 20)\r
+    #define FXAA_QUALITY__PS 3\r
+    #define FXAA_QUALITY__P0 1.5\r
+    #define FXAA_QUALITY__P1 2.0\r
+    #define FXAA_QUALITY__P2 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 21)\r
+    #define FXAA_QUALITY__PS 4\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 22)\r
+    #define FXAA_QUALITY__PS 5\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 23)\r
+    #define FXAA_QUALITY__PS 6\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 24)\r
+    #define FXAA_QUALITY__PS 7\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 3.0\r
+    #define FXAA_QUALITY__P6 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 25)\r
+    #define FXAA_QUALITY__PS 8\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 2.0\r
+    #define FXAA_QUALITY__P6 4.0\r
+    #define FXAA_QUALITY__P7 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 26)\r
+    #define FXAA_QUALITY__PS 9\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 2.0\r
+    #define FXAA_QUALITY__P6 2.0\r
+    #define FXAA_QUALITY__P7 4.0\r
+    #define FXAA_QUALITY__P8 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 27)\r
+    #define FXAA_QUALITY__PS 10\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 2.0\r
+    #define FXAA_QUALITY__P6 2.0\r
+    #define FXAA_QUALITY__P7 2.0\r
+    #define FXAA_QUALITY__P8 4.0\r
+    #define FXAA_QUALITY__P9 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 28)\r
+    #define FXAA_QUALITY__PS 11\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 2.0\r
+    #define FXAA_QUALITY__P6 2.0\r
+    #define FXAA_QUALITY__P7 2.0\r
+    #define FXAA_QUALITY__P8 2.0\r
+    #define FXAA_QUALITY__P9 4.0\r
+    #define FXAA_QUALITY__P10 8.0\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_QUALITY__PRESET == 29)\r
+    #define FXAA_QUALITY__PS 12\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.5\r
+    #define FXAA_QUALITY__P2 2.0\r
+    #define FXAA_QUALITY__P3 2.0\r
+    #define FXAA_QUALITY__P4 2.0\r
+    #define FXAA_QUALITY__P5 2.0\r
+    #define FXAA_QUALITY__P6 2.0\r
+    #define FXAA_QUALITY__P7 2.0\r
+    #define FXAA_QUALITY__P8 2.0\r
+    #define FXAA_QUALITY__P9 2.0\r
+    #define FXAA_QUALITY__P10 4.0\r
+    #define FXAA_QUALITY__P11 8.0\r
+#endif\r
+\r
+/*============================================================================\r
+                     FXAA QUALITY - EXTREME QUALITY\r
+============================================================================*/\r
+#if (FXAA_QUALITY__PRESET == 39)\r
+    #define FXAA_QUALITY__PS 12\r
+    #define FXAA_QUALITY__P0 1.0\r
+    #define FXAA_QUALITY__P1 1.0\r
+    #define FXAA_QUALITY__P2 1.0\r
+    #define FXAA_QUALITY__P3 1.0\r
+    #define FXAA_QUALITY__P4 1.0\r
+    #define FXAA_QUALITY__P5 1.5\r
+    #define FXAA_QUALITY__P6 2.0\r
+    #define FXAA_QUALITY__P7 2.0\r
+    #define FXAA_QUALITY__P8 2.0\r
+    #define FXAA_QUALITY__P9 2.0\r
+    #define FXAA_QUALITY__P10 4.0\r
+    #define FXAA_QUALITY__P11 8.0\r
+#endif\r
+\r
+\r
+\r
+/*============================================================================\r
+\r
+                                API PORTING\r
+\r
+============================================================================*/\r
+#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)\r
+    #define FxaaBool bool\r
+    #define FxaaDiscard discard\r
+    #define FxaaFloat float\r
+    #define FxaaFloat2 vec2\r
+    #define FxaaFloat3 vec3\r
+    #define FxaaFloat4 vec4\r
+    #define FxaaHalf float\r
+    #define FxaaHalf2 vec2\r
+    #define FxaaHalf3 vec3\r
+    #define FxaaHalf4 vec4\r
+    #define FxaaInt2 ivec2\r
+    #define FxaaSat(x) clamp(x, 0.0, 1.0)\r
+    #define FxaaTex sampler2D\r
+#else\r
+    #define FxaaBool bool\r
+    #define FxaaDiscard clip(-1)\r
+    #define FxaaFloat float\r
+    #define FxaaFloat2 float2\r
+    #define FxaaFloat3 float3\r
+    #define FxaaFloat4 float4\r
+    #define FxaaHalf half\r
+    #define FxaaHalf2 half2\r
+    #define FxaaHalf3 half3\r
+    #define FxaaHalf4 half4\r
+    #define FxaaSat(x) saturate(x)\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_GLSL_120 == 1)\r
+    // Requires,\r
+    //  #version 120\r
+    // And at least,\r
+    //  #extension GL_EXT_gpu_shader4 : enable\r
+    //  (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)\r
+    #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)\r
+    #if (FXAA_FAST_PIXEL_OFFSET == 1)\r
+        #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)\r
+    #else\r
+        #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)\r
+    #endif\r
+    #if (FXAA_GATHER4_ALPHA == 1)\r
+        // use #extension GL_ARB_gpu_shader5 : enable\r
+        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)\r
+        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)\r
+        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)\r
+        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)\r
+    #endif\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_GLSL_130 == 1)\r
+    // Requires "#version 130" or better\r
+    #define FxaaTexTop(t, p) textureLod(t, p, 0.0)\r
+    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)\r
+    #if (FXAA_GATHER4_ALPHA == 1)\r
+        // use #extension GL_ARB_gpu_shader5 : enable\r
+        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)\r
+        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)\r
+        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)\r
+        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)\r
+    #endif\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)\r
+    #define FxaaInt2 float2\r
+    #define FxaaTex sampler2D\r
+    #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))\r
+    #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_HLSL_4 == 1)\r
+    #define FxaaInt2 int2\r
+    struct FxaaTex { SamplerState smpl; Texture2D tex; };\r
+    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)\r
+    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)\r
+#endif\r
+/*--------------------------------------------------------------------------*/\r
+#if (FXAA_HLSL_5 == 1)\r
+    #define FxaaInt2 int2\r
+    struct FxaaTex { SamplerState smpl; Texture2D tex; };\r
+    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)\r
+    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)\r
+    #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)\r
+    #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)\r
+    #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)\r
+    #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)\r
+#endif\r
+\r
+\r
+/*============================================================================\r
+                   GREEN AS LUMA OPTION SUPPORT FUNCTION\r
+============================================================================*/\r
+#if (FXAA_GREEN_AS_LUMA == 0)\r
+    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }\r
+#else\r
+    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }\r
+#endif    \r
+\r
+\r
+\r
+\r
+/*============================================================================\r
+\r
+                             FXAA3 QUALITY - PC\r
+\r
+============================================================================*/\r
+#if (FXAA_PC == 1)\r
+/*--------------------------------------------------------------------------*/\r
+FxaaFloat4 FxaaPixelShader(\r
+    //\r
+    // Use noperspective interpolation here (turn off perspective interpolation).\r
+    // {xy} = center of pixel\r
+    FxaaFloat2 pos,\r
+    //\r
+    // Used only for FXAA Console, and not used on the 360 version.\r
+    // Use noperspective interpolation here (turn off perspective interpolation).\r
+    // {xy__} = upper left of pixel\r
+    // {__zw} = lower right of pixel\r
+    FxaaFloat4 fxaaConsolePosPos,\r
+    //\r
+    // Input color texture.\r
+    // {rgb_} = color in linear or perceptual color space\r
+    // if (FXAA_GREEN_AS_LUMA == 0)\r
+    //     {___a} = luma in perceptual color space (not linear)\r
+    FxaaTex tex,\r
+    //\r
+    // Only used on the optimized 360 version of FXAA Console.\r
+    // For everything but 360, just use the same input here as for "tex".\r
+    // For 360, same texture, just alias with a 2nd sampler.\r
+    // This sampler needs to have an exponent bias of -1.\r
+    FxaaTex fxaaConsole360TexExpBiasNegOne,\r
+    //\r
+    // Only used on the optimized 360 version of FXAA Console.\r
+    // For everything but 360, just use the same input here as for "tex".\r
+    // For 360, same texture, just alias with a 3nd sampler.\r
+    // This sampler needs to have an exponent bias of -2.\r
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,\r
+    //\r
+    // Only used on FXAA Quality.\r
+    // This must be from a constant/uniform.\r
+    // {x_} = 1.0/screenWidthInPixels\r
+    // {_y} = 1.0/screenHeightInPixels\r
+    FxaaFloat2 fxaaQualityRcpFrame,\r
+    //\r
+    // Only used on FXAA Console.\r
+    // This must be from a constant/uniform.\r
+    // This effects sub-pixel AA quality and inversely sharpness.\r
+    //   Where N ranges between,\r
+    //     N = 0.50 (default)\r
+    //     N = 0.33 (sharper)\r
+    // {x___} = -N/screenWidthInPixels  \r
+    // {_y__} = -N/screenHeightInPixels\r
+    // {__z_} =  N/screenWidthInPixels  \r
+    // {___w} =  N/screenHeightInPixels \r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,\r
+    //\r
+    // Only used on FXAA Console.\r
+    // Not used on 360, but used on PS3 and PC.\r
+    // This must be from a constant/uniform.\r
+    // {x___} = -2.0/screenWidthInPixels  \r
+    // {_y__} = -2.0/screenHeightInPixels\r
+    // {__z_} =  2.0/screenWidthInPixels  \r
+    // {___w} =  2.0/screenHeightInPixels \r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,\r
+    //\r
+    // Only used on FXAA Console.\r
+    // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.\r
+    // This must be from a constant/uniform.\r
+    // {x___} =  8.0/screenWidthInPixels  \r
+    // {_y__} =  8.0/screenHeightInPixels\r
+    // {__z_} = -4.0/screenWidthInPixels  \r
+    // {___w} = -4.0/screenHeightInPixels \r
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,\r
+    //\r
+    // Only used on FXAA Quality.\r
+    // This used to be the FXAA_QUALITY__SUBPIX define.\r
+    // It is here now to allow easier tuning.\r
+    // Choose the amount of sub-pixel aliasing removal.\r
+    // This can effect sharpness.\r
+    //   1.00 - upper limit (softer)\r
+    //   0.75 - default amount of filtering\r
+    //   0.50 - lower limit (sharper, less sub-pixel aliasing removal)\r
+    //   0.25 - almost off\r
+    //   0.00 - completely off\r
+    FxaaFloat fxaaQualitySubpix,\r
+    //\r
+    // Only used on FXAA Quality.\r
+    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.\r
+    // It is here now to allow easier tuning.\r
+    // The minimum amount of local contrast required to apply algorithm.\r
+    //   0.333 - too little (faster)\r
+    //   0.250 - low quality\r
+    //   0.166 - default\r
+    //   0.125 - high quality \r
+    //   0.063 - overkill (slower)\r
+    FxaaFloat fxaaQualityEdgeThreshold,\r
+    //\r
+    // Only used on FXAA Quality.\r
+    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.\r
+    // It is here now to allow easier tuning.\r
+    // Trims the algorithm from processing darks.\r
+    //   0.0833 - upper limit (default, the start of visible unfiltered edges)\r
+    //   0.0625 - high quality (faster)\r
+    //   0.0312 - visible limit (slower)\r
+    // Special notes when using FXAA_GREEN_AS_LUMA,\r
+    //   Likely want to set this to zero.\r
+    //   As colors that are mostly not-green\r
+    //   will appear very dark in the green channel!\r
+    //   Tune by looking at mostly non-green content,\r
+    //   then start at zero and increase until aliasing is a problem.\r
+    FxaaFloat fxaaQualityEdgeThresholdMin,\r
+    // \r
+    // Only used on FXAA Console.\r
+    // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.\r
+    // It is here now to allow easier tuning.\r
+    // This does not effect PS3, as this needs to be compiled in.\r
+    //   Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.\r
+    //   Due to the PS3 being ALU bound,\r
+    //   there are only three safe values here: 2 and 4 and 8.\r
+    //   These options use the shaders ability to a free *|/ by 2|4|8.\r
+    // For all other platforms can be a non-power of two.\r
+    //   8.0 is sharper (default!!!)\r
+    //   4.0 is softer\r
+    //   2.0 is really soft (good only for vector graphics inputs)\r
+    FxaaFloat fxaaConsoleEdgeSharpness,\r
+    //\r
+    // Only used on FXAA Console.\r
+    // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define.\r
+    // It is here now to allow easier tuning.\r
+    // This does not effect PS3, as this needs to be compiled in.\r
+    //   Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3.\r
+    //   Due to the PS3 being ALU bound,\r
+    //   there are only two safe values here: 1/4 and 1/8.\r
+    //   These options use the shaders ability to a free *|/ by 2|4|8.\r
+    // The console setting has a different mapping than the quality setting.\r
+    // Other platforms can use other values.\r
+    //   0.125 leaves less aliasing, but is softer (default!!!)\r
+    //   0.25 leaves more aliasing, and is sharper\r
+    FxaaFloat fxaaConsoleEdgeThreshold,\r
+    //\r
+    // Only used on FXAA Console.\r
+    // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define.\r
+    // It is here now to allow easier tuning.\r
+    // Trims the algorithm from processing darks.\r
+    // The console setting has a different mapping than the quality setting.\r
+    // This only applies when FXAA_EARLY_EXIT is 1.\r
+    // This does not apply to PS3, \r
+    // PS3 was simplified to avoid more shader instructions.\r
+    //   0.06 - faster but more aliasing in darks\r
+    //   0.05 - default\r
+    //   0.04 - slower and less aliasing in darks\r
+    // Special notes when using FXAA_GREEN_AS_LUMA,\r
+    //   Likely want to set this to zero.\r
+    //   As colors that are mostly not-green\r
+    //   will appear very dark in the green channel!\r
+    //   Tune by looking at mostly non-green content,\r
+    //   then start at zero and increase until aliasing is a problem.\r
+    FxaaFloat fxaaConsoleEdgeThresholdMin,\r
+    //    \r
+    // Extra constants for 360 FXAA Console only.\r
+    // Use zeros or anything else for other platforms.\r
+    // These must be in physical constant registers and NOT immedates.\r
+    // Immedates will result in compiler un-optimizing.\r
+    // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)\r
+    FxaaFloat4 fxaaConsole360ConstDir\r
+) {\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat2 posM;\r
+    posM.x = pos.x;\r
+    posM.y = pos.y;\r
+    #if (FXAA_GATHER4_ALPHA == 1)\r
+        #if (FXAA_DISCARD == 0)\r
+            FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);\r
+            #if (FXAA_GREEN_AS_LUMA == 0)\r
+                #define lumaM rgbyM.w\r
+            #else\r
+                #define lumaM rgbyM.y\r
+            #endif\r
+        #endif\r
+        #if (FXAA_GREEN_AS_LUMA == 0)\r
+            FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);\r
+            FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));\r
+        #else\r
+            FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);\r
+            FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));\r
+        #endif\r
+        #if (FXAA_DISCARD == 1)\r
+            #define lumaM luma4A.w\r
+        #endif\r
+        #define lumaE luma4A.z\r
+        #define lumaS luma4A.x\r
+        #define lumaSE luma4A.y\r
+        #define lumaNW luma4B.w\r
+        #define lumaN luma4B.z\r
+        #define lumaW luma4B.x\r
+    #else\r
+        FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);\r
+        #if (FXAA_GREEN_AS_LUMA == 0)\r
+            #define lumaM rgbyM.w\r
+        #else\r
+            #define lumaM rgbyM.y\r
+        #endif\r
+        FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat maxSM = max(lumaS, lumaM);\r
+    FxaaFloat minSM = min(lumaS, lumaM);\r
+    FxaaFloat maxESM = max(lumaE, maxSM);\r
+    FxaaFloat minESM = min(lumaE, minSM);\r
+    FxaaFloat maxWN = max(lumaN, lumaW);\r
+    FxaaFloat minWN = min(lumaN, lumaW);\r
+    FxaaFloat rangeMax = max(maxWN, maxESM);\r
+    FxaaFloat rangeMin = min(minWN, minESM);\r
+    FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;\r
+    FxaaFloat range = rangeMax - rangeMin;\r
+    FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);\r
+    FxaaBool earlyExit = range < rangeMaxClamped;\r
+/*--------------------------------------------------------------------------*/\r
+    if(earlyExit)\r
+        #if (FXAA_DISCARD == 1)\r
+            FxaaDiscard;\r
+        #else\r
+            return rgbyM;\r
+        #endif\r
+/*--------------------------------------------------------------------------*/\r
+    #if (FXAA_GATHER4_ALPHA == 0)\r
+        FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));\r
+    #else\r
+        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));\r
+        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaNS = lumaN + lumaS;\r
+    FxaaFloat lumaWE = lumaW + lumaE;\r
+    FxaaFloat subpixRcpRange = 1.0/range;\r
+    FxaaFloat subpixNSWE = lumaNS + lumaWE;\r
+    FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;\r
+    FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaNESE = lumaNE + lumaSE;\r
+    FxaaFloat lumaNWNE = lumaNW + lumaNE;\r
+    FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;\r
+    FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaNWSW = lumaNW + lumaSW;\r
+    FxaaFloat lumaSWSE = lumaSW + lumaSE;\r
+    FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);\r
+    FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);\r
+    FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;\r
+    FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;\r
+    FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;\r
+    FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;\r
+    FxaaFloat lengthSign = fxaaQualityRcpFrame.x;\r
+    FxaaBool horzSpan = edgeHorz >= edgeVert;\r
+    FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;\r
+/*--------------------------------------------------------------------------*/\r
+    if(!horzSpan) lumaN = lumaW;\r
+    if(!horzSpan) lumaS = lumaE;\r
+    if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;\r
+    FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat gradientN = lumaN - lumaM;\r
+    FxaaFloat gradientS = lumaS - lumaM;\r
+    FxaaFloat lumaNN = lumaN + lumaM;\r
+    FxaaFloat lumaSS = lumaS + lumaM;\r
+    FxaaBool pairN = abs(gradientN) >= abs(gradientS);\r
+    FxaaFloat gradient = max(abs(gradientN), abs(gradientS));\r
+    if(pairN) lengthSign = -lengthSign;\r
+    FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat2 posB;\r
+    posB.x = posM.x;\r
+    posB.y = posM.y;\r
+    FxaaFloat2 offNP;\r
+    offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;\r
+    offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;\r
+    if(!horzSpan) posB.x += lengthSign * 0.5;\r
+    if( horzSpan) posB.y += lengthSign * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat2 posN;\r
+    posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;\r
+    posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;\r
+    FxaaFloat2 posP;\r
+    posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;\r
+    posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;\r
+    FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;\r
+    FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));\r
+    FxaaFloat subpixE = subpixC * subpixC;\r
+    FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));\r
+/*--------------------------------------------------------------------------*/\r
+    if(!pairN) lumaNN = lumaSS;\r
+    FxaaFloat gradientScaled = gradient * 1.0/4.0;\r
+    FxaaFloat lumaMM = lumaM - lumaNN * 0.5;\r
+    FxaaFloat subpixF = subpixD * subpixE;\r
+    FxaaBool lumaMLTZero = lumaMM < 0.0;\r
+/*--------------------------------------------------------------------------*/\r
+    lumaEndN -= lumaNN * 0.5;\r
+    lumaEndP -= lumaNN * 0.5;\r
+    FxaaBool doneN = abs(lumaEndN) >= gradientScaled;\r
+    FxaaBool doneP = abs(lumaEndP) >= gradientScaled;\r
+    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;\r
+    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;\r
+    FxaaBool doneNP = (!doneN) || (!doneP);\r
+    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;\r
+    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;\r
+/*--------------------------------------------------------------------------*/\r
+    if(doneNP) {\r
+        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+        doneN = abs(lumaEndN) >= gradientScaled;\r
+        doneP = abs(lumaEndP) >= gradientScaled;\r
+        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;\r
+        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;\r
+        doneNP = (!doneN) || (!doneP);\r
+        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;\r
+        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;\r
+/*--------------------------------------------------------------------------*/\r
+        #if (FXAA_QUALITY__PS > 3)\r
+        if(doneNP) {\r
+            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+            doneN = abs(lumaEndN) >= gradientScaled;\r
+            doneP = abs(lumaEndP) >= gradientScaled;\r
+            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;\r
+            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;\r
+            doneNP = (!doneN) || (!doneP);\r
+            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;\r
+            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;\r
+/*--------------------------------------------------------------------------*/\r
+            #if (FXAA_QUALITY__PS > 4)\r
+            if(doneNP) {\r
+                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                doneN = abs(lumaEndN) >= gradientScaled;\r
+                doneP = abs(lumaEndP) >= gradientScaled;\r
+                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;\r
+                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;\r
+                doneNP = (!doneN) || (!doneP);\r
+                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;\r
+                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;\r
+/*--------------------------------------------------------------------------*/\r
+                #if (FXAA_QUALITY__PS > 5)\r
+                if(doneNP) {\r
+                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                    doneN = abs(lumaEndN) >= gradientScaled;\r
+                    doneP = abs(lumaEndP) >= gradientScaled;\r
+                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;\r
+                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;\r
+                    doneNP = (!doneN) || (!doneP);\r
+                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;\r
+                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;\r
+/*--------------------------------------------------------------------------*/\r
+                    #if (FXAA_QUALITY__PS > 6)\r
+                    if(doneNP) {\r
+                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                        doneN = abs(lumaEndN) >= gradientScaled;\r
+                        doneP = abs(lumaEndP) >= gradientScaled;\r
+                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;\r
+                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;\r
+                        doneNP = (!doneN) || (!doneP);\r
+                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;\r
+                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;\r
+/*--------------------------------------------------------------------------*/\r
+                        #if (FXAA_QUALITY__PS > 7)\r
+                        if(doneNP) {\r
+                            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                            doneN = abs(lumaEndN) >= gradientScaled;\r
+                            doneP = abs(lumaEndP) >= gradientScaled;\r
+                            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;\r
+                            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;\r
+                            doneNP = (!doneN) || (!doneP);\r
+                            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;\r
+                            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;\r
+/*--------------------------------------------------------------------------*/\r
+    #if (FXAA_QUALITY__PS > 8)\r
+    if(doneNP) {\r
+        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+        doneN = abs(lumaEndN) >= gradientScaled;\r
+        doneP = abs(lumaEndP) >= gradientScaled;\r
+        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;\r
+        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;\r
+        doneNP = (!doneN) || (!doneP);\r
+        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;\r
+        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;\r
+/*--------------------------------------------------------------------------*/\r
+        #if (FXAA_QUALITY__PS > 9)\r
+        if(doneNP) {\r
+            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+            doneN = abs(lumaEndN) >= gradientScaled;\r
+            doneP = abs(lumaEndP) >= gradientScaled;\r
+            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;\r
+            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;\r
+            doneNP = (!doneN) || (!doneP);\r
+            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;\r
+            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;\r
+/*--------------------------------------------------------------------------*/\r
+            #if (FXAA_QUALITY__PS > 10)\r
+            if(doneNP) {\r
+                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                doneN = abs(lumaEndN) >= gradientScaled;\r
+                doneP = abs(lumaEndP) >= gradientScaled;\r
+                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;\r
+                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;\r
+                doneNP = (!doneN) || (!doneP);\r
+                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;\r
+                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;\r
+/*--------------------------------------------------------------------------*/\r
+                #if (FXAA_QUALITY__PS > 11)\r
+                if(doneNP) {\r
+                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                    doneN = abs(lumaEndN) >= gradientScaled;\r
+                    doneP = abs(lumaEndP) >= gradientScaled;\r
+                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;\r
+                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;\r
+                    doneNP = (!doneN) || (!doneP);\r
+                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;\r
+                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;\r
+/*--------------------------------------------------------------------------*/\r
+                    #if (FXAA_QUALITY__PS > 12)\r
+                    if(doneNP) {\r
+                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\r
+                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\r
+                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\r
+                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\r
+                        doneN = abs(lumaEndN) >= gradientScaled;\r
+                        doneP = abs(lumaEndP) >= gradientScaled;\r
+                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;\r
+                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;\r
+                        doneNP = (!doneN) || (!doneP);\r
+                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;\r
+                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;\r
+/*--------------------------------------------------------------------------*/\r
+                    }\r
+                    #endif\r
+/*--------------------------------------------------------------------------*/\r
+                }\r
+                #endif\r
+/*--------------------------------------------------------------------------*/\r
+            }\r
+            #endif\r
+/*--------------------------------------------------------------------------*/\r
+        }\r
+        #endif\r
+/*--------------------------------------------------------------------------*/\r
+    }\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+                        }\r
+                        #endif\r
+/*--------------------------------------------------------------------------*/\r
+                    }\r
+                    #endif\r
+/*--------------------------------------------------------------------------*/\r
+                }\r
+                #endif\r
+/*--------------------------------------------------------------------------*/\r
+            }\r
+            #endif\r
+/*--------------------------------------------------------------------------*/\r
+        }\r
+        #endif\r
+/*--------------------------------------------------------------------------*/\r
+    }\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat dstN = posM.x - posN.x;\r
+    FxaaFloat dstP = posP.x - posM.x;\r
+    if(!horzSpan) dstN = posM.y - posN.y;\r
+    if(!horzSpan) dstP = posP.y - posM.y;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;\r
+    FxaaFloat spanLength = (dstP + dstN);\r
+    FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;\r
+    FxaaFloat spanLengthRcp = 1.0/spanLength;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaBool directionN = dstN < dstP;\r
+    FxaaFloat dst = min(dstN, dstP);\r
+    FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;\r
+    FxaaFloat subpixG = subpixF * subpixF;\r
+    FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;\r
+    FxaaFloat subpixH = subpixG * fxaaQualitySubpix;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;\r
+    FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);\r
+    if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;\r
+    if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;\r
+    #if (FXAA_DISCARD == 1)\r
+        return FxaaTexTop(tex, posM);\r
+    #else\r
+        return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);\r
+    #endif\r
+}\r
+/*==========================================================================*/\r
+#endif\r
+\r
+\r
+\r
+\r
+/*============================================================================\r
+\r
+                         FXAA3 CONSOLE - PC VERSION\r
+                         \r
+------------------------------------------------------------------------------\r
+Instead of using this on PC, I'd suggest just using FXAA Quality with\r
+    #define FXAA_QUALITY__PRESET 10\r
+Or \r
+    #define FXAA_QUALITY__PRESET 20\r
+Either are higher qualilty and almost as fast as this on modern PC GPUs.\r
+============================================================================*/\r
+#if (FXAA_PC_CONSOLE == 1)\r
+/*--------------------------------------------------------------------------*/\r
+FxaaFloat4 FxaaPixelShader(\r
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!\r
+    FxaaFloat2 pos,\r
+    FxaaFloat4 fxaaConsolePosPos,\r
+    FxaaTex tex,\r
+    FxaaTex fxaaConsole360TexExpBiasNegOne,\r
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,\r
+    FxaaFloat2 fxaaQualityRcpFrame,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,\r
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,\r
+    FxaaFloat fxaaQualitySubpix,\r
+    FxaaFloat fxaaQualityEdgeThreshold,\r
+    FxaaFloat fxaaQualityEdgeThresholdMin,\r
+    FxaaFloat fxaaConsoleEdgeSharpness,\r
+    FxaaFloat fxaaConsoleEdgeThreshold,\r
+    FxaaFloat fxaaConsoleEdgeThresholdMin,\r
+    FxaaFloat4 fxaaConsole360ConstDir\r
+) {\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));\r
+    FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));\r
+    FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));\r
+    FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        FxaaFloat lumaM = rgbyM.w;\r
+    #else\r
+        FxaaFloat lumaM = rgbyM.y;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);\r
+    lumaNe += 1.0/384.0;\r
+    FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);\r
+    FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);\r
+    FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat lumaMinM = min(lumaMin, lumaM);\r
+    FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);\r
+    FxaaFloat lumaMaxM = max(lumaMax, lumaM);\r
+    FxaaFloat dirSwMinusNe = lumaSw - lumaNe;\r
+    FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;\r
+    FxaaFloat dirSeMinusNw = lumaSe - lumaNw;\r
+    if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat2 dir;\r
+    dir.x = dirSwMinusNe + dirSeMinusNw;\r
+    dir.y = dirSwMinusNe - dirSeMinusNw;\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat2 dir1 = normalize(dir.xy);\r
+    FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);\r
+    FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;\r
+    FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);\r
+    FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);\r
+/*--------------------------------------------------------------------------*/\r
+    FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;\r
+    FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);\r
+/*--------------------------------------------------------------------------*/\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);\r
+    #else\r
+        FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);\r
+    #endif\r
+    if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;\r
+    return rgbyB; }\r
+/*==========================================================================*/\r
+#endif\r
+\r
+\r
+\r
+/*============================================================================\r
+\r
+                      FXAA3 CONSOLE - 360 PIXEL SHADER \r
+\r
+------------------------------------------------------------------------------\r
+This optimized version thanks to suggestions from Andy Luedke.\r
+Should be fully tex bound in all cases.\r
+As of the FXAA 3.11 release, I have still not tested this code,\r
+however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10.\r
+And note this is replacing the old unoptimized version.\r
+If it does not work, please let me know so I can fix it.\r
+============================================================================*/\r
+#if (FXAA_360 == 1)\r
+/*--------------------------------------------------------------------------*/\r
+[reduceTempRegUsage(4)]\r
+float4 FxaaPixelShader(\r
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!\r
+    FxaaFloat2 pos,\r
+    FxaaFloat4 fxaaConsolePosPos,\r
+    FxaaTex tex,\r
+    FxaaTex fxaaConsole360TexExpBiasNegOne,\r
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,\r
+    FxaaFloat2 fxaaQualityRcpFrame,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,\r
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,\r
+    FxaaFloat fxaaQualitySubpix,\r
+    FxaaFloat fxaaQualityEdgeThreshold,\r
+    FxaaFloat fxaaQualityEdgeThresholdMin,\r
+    FxaaFloat fxaaConsoleEdgeSharpness,\r
+    FxaaFloat fxaaConsoleEdgeThreshold,\r
+    FxaaFloat fxaaConsoleEdgeThresholdMin,\r
+    FxaaFloat4 fxaaConsole360ConstDir\r
+) {\r
+/*--------------------------------------------------------------------------*/\r
+    float4 lumaNwNeSwSe;\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        asm { \r
+            tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false\r
+            tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX =  0.5, OffsetY = -0.5, UseComputedLOD=false\r
+            tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY =  0.5, UseComputedLOD=false\r
+            tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX =  0.5, OffsetY =  0.5, UseComputedLOD=false\r
+        };\r
+    #else\r
+        asm { \r
+            tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false\r
+            tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX =  0.5, OffsetY = -0.5, UseComputedLOD=false\r
+            tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY =  0.5, UseComputedLOD=false\r
+            tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX =  0.5, OffsetY =  0.5, UseComputedLOD=false\r
+        };\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+    lumaNwNeSwSe.y += 1.0/384.0;\r
+    float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);\r
+    float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);\r
+    float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);\r
+    float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);\r
+/*--------------------------------------------------------------------------*/\r
+    float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        float lumaMinM = min(lumaMin, rgbyM.w);\r
+        float lumaMaxM = max(lumaMax, rgbyM.w);\r
+    #else\r
+        float lumaMinM = min(lumaMin, rgbyM.y);\r
+        float lumaMaxM = max(lumaMax, rgbyM.y);\r
+    #endif        \r
+    if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;\r
+/*--------------------------------------------------------------------------*/\r
+    float2 dir;\r
+    dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);\r
+    dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);\r
+    dir = normalize(dir);\r
+/*--------------------------------------------------------------------------*/\r
+    float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;\r
+/*--------------------------------------------------------------------------*/\r
+    float4 dir2;\r
+    float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;\r
+    dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);\r
+    dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;\r
+/*--------------------------------------------------------------------------*/\r
+    float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));\r
+    float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));\r
+    float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));\r
+    float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));\r
+/*--------------------------------------------------------------------------*/\r
+    float4 rgbyA = rgbyN1 + rgbyP1;\r
+    float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+    float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; \r
+    rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; \r
+    return rgbyR; }\r
+/*==========================================================================*/\r
+#endif\r
+\r
+\r
+\r
+/*============================================================================\r
+\r
+         FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT)\r
+\r
+==============================================================================\r
+The code below does not exactly match the assembly.\r
+I have a feeling that 12 cycles is possible, but was not able to get there.\r
+Might have to increase register count to get full performance.\r
+Note this shader does not use perspective interpolation.\r
+\r
+Use the following cgc options,\r
+\r
+  --fenable-bx2 --fastmath --fastprecision --nofloatbindings\r
+\r
+------------------------------------------------------------------------------\r
+                             NVSHADERPERF OUTPUT\r
+------------------------------------------------------------------------------\r
+For reference and to aid in debug, output of NVShaderPerf should match this,\r
+\r
+Shader to schedule:\r
+  0: texpkb h0.w(TRUE), v5.zyxx, #0\r
+  2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x\r
+  4: texpkb h0.w(TRUE), v5.xwxx, #0\r
+  6: addh h0.z(TRUE), -h2, h0.w\r
+  7: texpkb h1.w(TRUE), v5, #0\r
+  9: addh h0.x(TRUE), h0.z, -h1.w\r
+ 10: addh h3.w(TRUE), h0.z, h1\r
+ 11: texpkb h2.w(TRUE), v5.zwzz, #0\r
+ 13: addh h0.z(TRUE), h3.w, -h2.w\r
+ 14: addh h0.x(TRUE), h2.w, h0\r
+ 15: nrmh h1.xz(TRUE), h0_n\r
+ 16: minh_m8 h0.x(TRUE), |h1|, |h1.z|\r
+ 17: maxh h4.w(TRUE), h0, h1\r
+ 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n\r
+ 19: movr r1.zw(TRUE), v4.xxxy\r
+ 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww\r
+ 22: minh h5.w(TRUE), h0, h1\r
+ 23: texpkb h0(TRUE), r2.xzxx, #0\r
+ 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1\r
+ 27: maxh h4.x(TRUE), h2.z, h2.w\r
+ 28: texpkb h1(TRUE), r0.zwzz, #0\r
+ 30: addh_d2 h1(TRUE), h0, h1\r
+ 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz\r
+ 33: texpkb h0(TRUE), r0, #0\r
+ 35: minh h4.z(TRUE), h2, h2.w\r
+ 36: fenct TRUE\r
+ 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz\r
+ 39: texpkb h2(TRUE), r1, #0\r
+ 41: addh_d2 h0(TRUE), h0, h2\r
+ 42: maxh h2.w(TRUE), h4, h4.x\r
+ 43: minh h2.x(TRUE), h5.w, h4.z\r
+ 44: addh_d2 h0(TRUE), h0, h1\r
+ 45: slth h2.x(TRUE), h0.w, h2\r
+ 46: sgth h2.w(TRUE), h0, h2\r
+ 47: movh h0(TRUE), h0\r
+ 48: addx.c0 rc(TRUE), h2, h2.w\r
+ 49: movh h0(c0.NE.x), h1\r
+\r
+IPU0 ------ Simplified schedule: --------\r
+Pass |  Unit  |  uOp |  PC:  Op\r
+-----+--------+------+-------------------------\r
+   1 | SCT0/1 |  mov |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;\r
+     |    TEX |  txl |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;\r
+     |   SCB1 |  add |   2:  ADDh h2.z, h0.--w-, const.--x-;\r
+     |        |      |\r
+   2 | SCT0/1 |  mov |   4:  TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;\r
+     |    TEX |  txl |   4:  TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;\r
+     |   SCB1 |  add |   6:  ADDh h0.z,-h2, h0.--w-;\r
+     |        |      |\r
+   3 | SCT0/1 |  mov |   7:  TXLr h1.w, g[TEX1], const.xxxx, TEX0;\r
+     |    TEX |  txl |   7:  TXLr h1.w, g[TEX1], const.xxxx, TEX0;\r
+     |   SCB0 |  add |   9:  ADDh h0.x, h0.z---,-h1.w---;\r
+     |   SCB1 |  add |  10:  ADDh h3.w, h0.---z, h1;\r
+     |        |      |\r
+   4 | SCT0/1 |  mov |  11:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;\r
+     |    TEX |  txl |  11:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;\r
+     |   SCB0 |  add |  14:  ADDh h0.x, h2.w---, h0;\r
+     |   SCB1 |  add |  13:  ADDh h0.z, h3.--w-,-h2.--w-;\r
+     |        |      |\r
+   5 |   SCT1 |  mov |  15:  NRMh h1.xz, h0;\r
+     |    SRB |  nrm |  15:  NRMh h1.xz, h0;\r
+     |   SCB0 |  min |  16:  MINh*8 h0.x, |h1|, |h1.z---|;\r
+     |   SCB1 |  max |  17:  MAXh h4.w, h0, h1;\r
+     |        |      |\r
+   6 |   SCT0 |  div |  18:  DIVx h2.xy, h1.xz--, h0;\r
+     |   SCT1 |  mov |  19:  MOVr r1.zw, g[TEX0].--xy;\r
+     |   SCB0 |  mad |  20:  MADr r2.xz,-h1, const.z-w-, r1.z-w-;\r
+     |   SCB1 |  min |  22:  MINh h5.w, h0, h1;\r
+     |        |      |\r
+   7 | SCT0/1 |  mov |  23:  TXLr h0, r2.xzxx, const.xxxx, TEX0;\r
+     |    TEX |  txl |  23:  TXLr h0, r2.xzxx, const.xxxx, TEX0;\r
+     |   SCB0 |  max |  27:  MAXh h4.x, h2.z---, h2.w---;\r
+     |   SCB1 |  mad |  25:  MADr r0.zw, h1.--xz, const, r1;\r
+     |        |      |\r
+   8 | SCT0/1 |  mov |  28:  TXLr h1, r0.zwzz, const.xxxx, TEX0;\r
+     |    TEX |  txl |  28:  TXLr h1, r0.zwzz, const.xxxx, TEX0;\r
+     | SCB0/1 |  add |  30:  ADDh/2 h1, h0, h1;\r
+     |        |      |\r
+   9 |   SCT0 |  mad |  31:  MADr r0.xy,-h2, const.xy--, r1.zw--;\r
+     |   SCT1 |  mov |  33:  TXLr h0, r0, const.zzzz, TEX0;\r
+     |    TEX |  txl |  33:  TXLr h0, r0, const.zzzz, TEX0;\r
+     |   SCB1 |  min |  35:  MINh h4.z, h2, h2.--w-;\r
+     |        |      |\r
+  10 |   SCT0 |  mad |  37:  MADr r1.xy, h2, const.xy--, r1.zw--;\r
+     |   SCT1 |  mov |  39:  TXLr h2, r1, const.zzzz, TEX0;\r
+     |    TEX |  txl |  39:  TXLr h2, r1, const.zzzz, TEX0;\r
+     | SCB0/1 |  add |  41:  ADDh/2 h0, h0, h2;\r
+     |        |      |\r
+  11 |   SCT0 |  min |  43:  MINh h2.x, h5.w---, h4.z---;\r
+     |   SCT1 |  max |  42:  MAXh h2.w, h4, h4.---x;\r
+     | SCB0/1 |  add |  44:  ADDh/2 h0, h0, h1;\r
+     |        |      |\r
+  12 |   SCT0 |  set |  45:  SLTh h2.x, h0.w---, h2;\r
+     |   SCT1 |  set |  46:  SGTh h2.w, h0, h2;\r
+     | SCB0/1 |  mul |  47:  MOVh h0, h0;\r
+     |        |      |\r
+  13 |   SCT0 |  mad |  48:  ADDxc0_s rc, h2, h2.w---;\r
+     | SCB0/1 |  mul |  49:  MOVh h0(NE0.xxxx), h1;\r
\r
+Pass   SCT  TEX  SCB\r
+  1:   0% 100%  25%\r
+  2:   0% 100%  25%\r
+  3:   0% 100%  50%\r
+  4:   0% 100%  50%\r
+  5:   0%   0%  50%\r
+  6: 100%   0%  75%\r
+  7:   0% 100%  75%\r
+  8:   0% 100% 100%\r
+  9:   0% 100%  25%\r
+ 10:   0% 100% 100%\r
+ 11:  50%   0% 100%\r
+ 12:  50%   0% 100%\r
+ 13:  25%   0% 100%\r
+\r
+MEAN:  17%  61%  67%\r
+\r
+Pass   SCT0  SCT1   TEX  SCB0  SCB1\r
+  1:    0%    0%  100%    0%  100%\r
+  2:    0%    0%  100%    0%  100%\r
+  3:    0%    0%  100%  100%  100%\r
+  4:    0%    0%  100%  100%  100%\r
+  5:    0%    0%    0%  100%  100%\r
+  6:  100%  100%    0%  100%  100%\r
+  7:    0%    0%  100%  100%  100%\r
+  8:    0%    0%  100%  100%  100%\r
+  9:    0%    0%  100%    0%  100%\r
+ 10:    0%    0%  100%  100%  100%\r
+ 11:  100%  100%    0%  100%  100%\r
+ 12:  100%  100%    0%  100%  100%\r
+ 13:  100%    0%    0%  100%  100%\r
+\r
+MEAN:   30%   23%   61%   76%  100%\r
+Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5\r
+Results 13 cycles, 3 r regs, 923,076,923 pixels/s\r
+============================================================================*/\r
+#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0)\r
+/*--------------------------------------------------------------------------*/\r
+#pragma regcount 7\r
+#pragma disablepc all\r
+#pragma option O3\r
+#pragma option OutColorPrec=fp16\r
+#pragma texformat default RGBA8\r
+/*==========================================================================*/\r
+half4 FxaaPixelShader(\r
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!\r
+    FxaaFloat2 pos,\r
+    FxaaFloat4 fxaaConsolePosPos,\r
+    FxaaTex tex,\r
+    FxaaTex fxaaConsole360TexExpBiasNegOne,\r
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,\r
+    FxaaFloat2 fxaaQualityRcpFrame,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,\r
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,\r
+    FxaaFloat fxaaQualitySubpix,\r
+    FxaaFloat fxaaQualityEdgeThreshold,\r
+    FxaaFloat fxaaQualityEdgeThresholdMin,\r
+    FxaaFloat fxaaConsoleEdgeSharpness,\r
+    FxaaFloat fxaaConsoleEdgeThreshold,\r
+    FxaaFloat fxaaConsoleEdgeThresholdMin,\r
+    FxaaFloat4 fxaaConsole360ConstDir\r
+) {\r
+/*--------------------------------------------------------------------------*/\r
+// (1)\r
+    half4 dir;\r
+    half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        lumaNe.w += half(1.0/512.0);\r
+        dir.x = -lumaNe.w;\r
+        dir.z = -lumaNe.w;\r
+    #else\r
+        lumaNe.y += half(1.0/512.0);\r
+        dir.x = -lumaNe.y;\r
+        dir.z = -lumaNe.y;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (2)\r
+    half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        dir.x += lumaSw.w;\r
+        dir.z += lumaSw.w;\r
+    #else\r
+        dir.x += lumaSw.y;\r
+        dir.z += lumaSw.y;\r
+    #endif        \r
+/*--------------------------------------------------------------------------*/\r
+// (3)\r
+    half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        dir.x -= lumaNw.w;\r
+        dir.z += lumaNw.w;\r
+    #else\r
+        dir.x -= lumaNw.y;\r
+        dir.z += lumaNw.y;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (4)\r
+    half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        dir.x += lumaSe.w;\r
+        dir.z -= lumaSe.w;\r
+    #else\r
+        dir.x += lumaSe.y;\r
+        dir.z -= lumaSe.y;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (5)\r
+    half4 dir1_pos;\r
+    dir1_pos.xy = normalize(dir.xyz).xz;\r
+    half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);\r
+/*--------------------------------------------------------------------------*/\r
+// (6)\r
+    half4 dir2_pos;\r
+    dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));\r
+    dir1_pos.zw = pos.xy;\r
+    dir2_pos.zw = pos.xy;\r
+    half4 temp1N;\r
+    temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;\r
+/*--------------------------------------------------------------------------*/\r
+// (7)\r
+    temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));\r
+    half4 rgby1;\r
+    rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;\r
+/*--------------------------------------------------------------------------*/\r
+// (8)\r
+    rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));\r
+    rgby1 = (temp1N + rgby1) * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+// (9)\r
+    half4 temp2N;\r
+    temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;\r
+    temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));\r
+/*--------------------------------------------------------------------------*/\r
+// (10)\r
+    half4 rgby2;\r
+    rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;\r
+    rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));\r
+    rgby2 = (temp2N + rgby2) * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+// (11)\r
+    // compilier moves these scalar ops up to other cycles\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));\r
+        half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));\r
+    #else\r
+        half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y));\r
+        half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y));\r
+    #endif        \r
+    rgby2 = (rgby2 + rgby1) * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+// (12)\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        bool twoTapLt = rgby2.w < lumaMin;\r
+        bool twoTapGt = rgby2.w > lumaMax;\r
+    #else\r
+        bool twoTapLt = rgby2.y < lumaMin;\r
+        bool twoTapGt = rgby2.y > lumaMax;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (13)\r
+    if(twoTapLt || twoTapGt) rgby2 = rgby1;\r
+/*--------------------------------------------------------------------------*/\r
+    return rgby2; }\r
+/*==========================================================================*/\r
+#endif\r
+\r
+\r
+\r
+/*============================================================================\r
+\r
+       FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT)\r
+\r
+==============================================================================\r
+The code mostly matches the assembly.\r
+I have a feeling that 14 cycles is possible, but was not able to get there.\r
+Might have to increase register count to get full performance.\r
+Note this shader does not use perspective interpolation.\r
+\r
+Use the following cgc options,\r
+\r
+ --fenable-bx2 --fastmath --fastprecision --nofloatbindings\r
+\r
+Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks).\r
+Will look at fixing this for FXAA 3.12.\r
+------------------------------------------------------------------------------\r
+                             NVSHADERPERF OUTPUT\r
+------------------------------------------------------------------------------\r
+For reference and to aid in debug, output of NVShaderPerf should match this,\r
+\r
+Shader to schedule:\r
+  0: texpkb h0.w(TRUE), v5.zyxx, #0\r
+  2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x\r
+  4: texpkb h1.w(TRUE), v5.xwxx, #0\r
+  6: addh h0.x(TRUE), h1.w, -h2.y\r
+  7: texpkb h2.w(TRUE), v5.zwzz, #0\r
+  9: minh h4.w(TRUE), h2.y, h2\r
+ 10: maxh h5.x(TRUE), h2.y, h2.w\r
+ 11: texpkb h0.w(TRUE), v5, #0\r
+ 13: addh h3.w(TRUE), -h0, h0.x\r
+ 14: addh h0.x(TRUE), h0.w, h0\r
+ 15: addh h0.z(TRUE), -h2.w, h0.x\r
+ 16: addh h0.x(TRUE), h2.w, h3.w\r
+ 17: minh h5.y(TRUE), h0.w, h1.w\r
+ 18: nrmh h2.xz(TRUE), h0_n\r
+ 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z|\r
+ 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w\r
+ 21: movr r1.zw(TRUE), v4.xxxy\r
+ 22: maxh h2.w(TRUE), h0, h1\r
+ 23: fenct TRUE\r
+ 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz\r
+ 26: texpkb h0(TRUE), r0, #0\r
+ 28: maxh h5.x(TRUE), h2.w, h5\r
+ 29: minh h5.w(TRUE), h5.y, h4\r
+ 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz\r
+ 32: texpkb h2(TRUE), r1, #0\r
+ 34: addh_d2 h2(TRUE), h0, h2\r
+ 35: texpkb h1(TRUE), v4, #0\r
+ 37: maxh h5.y(TRUE), h5.x, h1.w\r
+ 38: minh h4.w(TRUE), h1, h5\r
+ 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz\r
+ 41: texpkb h0(TRUE), r0, #0\r
+ 43: addh_m8 h5.z(TRUE), h5.y, -h4.w\r
+ 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz\r
+ 46: texpkb h3(TRUE), r2, #0\r
+ 48: addh_d2 h0(TRUE), h0, h3\r
+ 49: addh_d2 h3(TRUE), h0, h2\r
+ 50: movh h0(TRUE), h3\r
+ 51: slth h3.x(TRUE), h3.w, h5.w\r
+ 52: sgth h3.w(TRUE), h3, h5.x\r
+ 53: addx.c0 rc(TRUE), h3.x, h3\r
+ 54: slth.c0 rc(TRUE), h5.z, h5\r
+ 55: movh h0(c0.NE.w), h2\r
+ 56: movh h0(c0.NE.x), h1\r
+\r
+IPU0 ------ Simplified schedule: --------\r
+Pass |  Unit  |  uOp |  PC:  Op\r
+-----+--------+------+-------------------------\r
+   1 | SCT0/1 |  mov |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;\r
+     |    TEX |  txl |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;\r
+     |   SCB0 |  add |   2:  ADDh h2.y, h0.-w--, const.-x--;\r
+     |        |      |\r
+   2 | SCT0/1 |  mov |   4:  TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;\r
+     |    TEX |  txl |   4:  TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;\r
+     |   SCB0 |  add |   6:  ADDh h0.x, h1.w---,-h2.y---;\r
+     |        |      |\r
+   3 | SCT0/1 |  mov |   7:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;\r
+     |    TEX |  txl |   7:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;\r
+     |   SCB0 |  max |  10:  MAXh h5.x, h2.y---, h2.w---;\r
+     |   SCB1 |  min |   9:  MINh h4.w, h2.---y, h2;\r
+     |        |      |\r
+   4 | SCT0/1 |  mov |  11:  TXLr h0.w, g[TEX1], const.xxxx, TEX0;\r
+     |    TEX |  txl |  11:  TXLr h0.w, g[TEX1], const.xxxx, TEX0;\r
+     |   SCB0 |  add |  14:  ADDh h0.x, h0.w---, h0;\r
+     |   SCB1 |  add |  13:  ADDh h3.w,-h0, h0.---x;\r
+     |        |      |\r
+   5 |   SCT0 |  mad |  16:  ADDh h0.x, h2.w---, h3.w---;\r
+     |   SCT1 |  mad |  15:  ADDh h0.z,-h2.--w-, h0.--x-;\r
+     |   SCB0 |  min |  17:  MINh h5.y, h0.-w--, h1.-w--;\r
+     |        |      |\r
+   6 |   SCT1 |  mov |  18:  NRMh h2.xz, h0;\r
+     |    SRB |  nrm |  18:  NRMh h2.xz, h0;\r
+     |   SCB1 |  min |  19:  MINh*8 h2.w, |h2.---x|, |h2.---z|;\r
+     |        |      |\r
+   7 |   SCT0 |  div |  20:  DIVx h4.xy, h2.xz--, h2.ww--;\r
+     |   SCT1 |  mov |  21:  MOVr r1.zw, g[TEX0].--xy;\r
+     |   SCB1 |  max |  22:  MAXh h2.w, h0, h1;\r
+     |        |      |\r
+   8 |   SCT0 |  mad |  24:  MADr r0.xy,-h2.xz--, const.zw--, r1.zw--;\r
+     |   SCT1 |  mov |  26:  TXLr h0, r0, const.xxxx, TEX0;\r
+     |    TEX |  txl |  26:  TXLr h0, r0, const.xxxx, TEX0;\r
+     |   SCB0 |  max |  28:  MAXh h5.x, h2.w---, h5;\r
+     |   SCB1 |  min |  29:  MINh h5.w, h5.---y, h4;\r
+     |        |      |\r
+   9 |   SCT0 |  mad |  30:  MADr r1.xy, h2.xz--, const.zw--, r1.zw--;\r
+     |   SCT1 |  mov |  32:  TXLr h2, r1, const.xxxx, TEX0;\r
+     |    TEX |  txl |  32:  TXLr h2, r1, const.xxxx, TEX0;\r
+     | SCB0/1 |  add |  34:  ADDh/2 h2, h0, h2;\r
+     |        |      |\r
+  10 | SCT0/1 |  mov |  35:  TXLr h1, g[TEX0], const.xxxx, TEX0;\r
+     |    TEX |  txl |  35:  TXLr h1, g[TEX0], const.xxxx, TEX0;\r
+     |   SCB0 |  max |  37:  MAXh h5.y, h5.-x--, h1.-w--;\r
+     |   SCB1 |  min |  38:  MINh h4.w, h1, h5;\r
+     |        |      |\r
+  11 |   SCT0 |  mad |  39:  MADr r0.xy,-h4, const.xy--, r1.zw--;\r
+     |   SCT1 |  mov |  41:  TXLr h0, r0, const.zzzz, TEX0;\r
+     |    TEX |  txl |  41:  TXLr h0, r0, const.zzzz, TEX0;\r
+     |   SCB0 |  mad |  44:  MADr r2.xy, h4, const.xy--, r1.zw--;\r
+     |   SCB1 |  add |  43:  ADDh*8 h5.z, h5.--y-,-h4.--w-;\r
+     |        |      |\r
+  12 | SCT0/1 |  mov |  46:  TXLr h3, r2, const.xxxx, TEX0;\r
+     |    TEX |  txl |  46:  TXLr h3, r2, const.xxxx, TEX0;\r
+     | SCB0/1 |  add |  48:  ADDh/2 h0, h0, h3;\r
+     |        |      |\r
+  13 | SCT0/1 |  mad |  49:  ADDh/2 h3, h0, h2;\r
+     | SCB0/1 |  mul |  50:  MOVh h0, h3;\r
+     |        |      |\r
+  14 |   SCT0 |  set |  51:  SLTh h3.x, h3.w---, h5.w---;\r
+     |   SCT1 |  set |  52:  SGTh h3.w, h3, h5.---x;\r
+     |   SCB0 |  set |  54:  SLThc0 rc, h5.z---, h5;\r
+     |   SCB1 |  add |  53:  ADDxc0_s rc, h3.---x, h3;\r
+     |        |      |\r
+  15 | SCT0/1 |  mul |  55:  MOVh h0(NE0.wwww), h2;\r
+     | SCB0/1 |  mul |  56:  MOVh h0(NE0.xxxx), h1;\r
\r
+Pass   SCT  TEX  SCB\r
+  1:   0% 100%  25%\r
+  2:   0% 100%  25%\r
+  3:   0% 100%  50%\r
+  4:   0% 100%  50%\r
+  5:  50%   0%  25%\r
+  6:   0%   0%  25%\r
+  7: 100%   0%  25%\r
+  8:   0% 100%  50%\r
+  9:   0% 100% 100%\r
+ 10:   0% 100%  50%\r
+ 11:   0% 100%  75%\r
+ 12:   0% 100% 100%\r
+ 13: 100%   0% 100%\r
+ 14:  50%   0%  50%\r
+ 15: 100%   0% 100%\r
+\r
+MEAN:  26%  60%  56%\r
+\r
+Pass   SCT0  SCT1   TEX  SCB0  SCB1\r
+  1:    0%    0%  100%  100%    0%\r
+  2:    0%    0%  100%  100%    0%\r
+  3:    0%    0%  100%  100%  100%\r
+  4:    0%    0%  100%  100%  100%\r
+  5:  100%  100%    0%  100%    0%\r
+  6:    0%    0%    0%    0%  100%\r
+  7:  100%  100%    0%    0%  100%\r
+  8:    0%    0%  100%  100%  100%\r
+  9:    0%    0%  100%  100%  100%\r
+ 10:    0%    0%  100%  100%  100%\r
+ 11:    0%    0%  100%  100%  100%\r
+ 12:    0%    0%  100%  100%  100%\r
+ 13:  100%  100%    0%  100%  100%\r
+ 14:  100%  100%    0%  100%  100%\r
+ 15:  100%  100%    0%  100%  100%\r
+\r
+MEAN:   33%   33%   60%   86%   80%\r
+Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5\r
+Results 15 cycles, 3 r regs, 800,000,000 pixels/s\r
+============================================================================*/\r
+#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1)\r
+/*--------------------------------------------------------------------------*/\r
+#pragma regcount 7\r
+#pragma disablepc all\r
+#pragma option O2\r
+#pragma option OutColorPrec=fp16\r
+#pragma texformat default RGBA8\r
+/*==========================================================================*/\r
+half4 FxaaPixelShader(\r
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!\r
+    FxaaFloat2 pos,\r
+    FxaaFloat4 fxaaConsolePosPos,\r
+    FxaaTex tex,\r
+    FxaaTex fxaaConsole360TexExpBiasNegOne,\r
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,\r
+    FxaaFloat2 fxaaQualityRcpFrame,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,\r
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,\r
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,\r
+    FxaaFloat fxaaQualitySubpix,\r
+    FxaaFloat fxaaQualityEdgeThreshold,\r
+    FxaaFloat fxaaQualityEdgeThresholdMin,\r
+    FxaaFloat fxaaConsoleEdgeSharpness,\r
+    FxaaFloat fxaaConsoleEdgeThreshold,\r
+    FxaaFloat fxaaConsoleEdgeThresholdMin,\r
+    FxaaFloat4 fxaaConsole360ConstDir\r
+) {\r
+/*--------------------------------------------------------------------------*/\r
+// (1)\r
+    half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half lumaNe = rgbyNe.w + half(1.0/512.0);\r
+    #else\r
+        half lumaNe = rgbyNe.y + half(1.0/512.0);\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (2)\r
+    half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half lumaSwNegNe = lumaSw.w - lumaNe;\r
+    #else\r
+        half lumaSwNegNe = lumaSw.y - lumaNe;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (3)\r
+    half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half lumaMaxNwSw = max(lumaNw.w, lumaSw.w);\r
+        half lumaMinNwSw = min(lumaNw.w, lumaSw.w);\r
+    #else\r
+        half lumaMaxNwSw = max(lumaNw.y, lumaSw.y);\r
+        half lumaMinNwSw = min(lumaNw.y, lumaSw.y);\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (4)\r
+    half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half dirZ =  lumaNw.w + lumaSwNegNe;\r
+        half dirX = -lumaNw.w + lumaSwNegNe;\r
+    #else\r
+        half dirZ =  lumaNw.y + lumaSwNegNe;\r
+        half dirX = -lumaNw.y + lumaSwNegNe;\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (5)\r
+    half3 dir;\r
+    dir.y = 0.0;\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        dir.x =  lumaSe.w + dirX;\r
+        dir.z = -lumaSe.w + dirZ;\r
+        half lumaMinNeSe = min(lumaNe, lumaSe.w);\r
+    #else\r
+        dir.x =  lumaSe.y + dirX;\r
+        dir.z = -lumaSe.y + dirZ;\r
+        half lumaMinNeSe = min(lumaNe, lumaSe.y);\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (6)\r
+    half4 dir1_pos;\r
+    dir1_pos.xy = normalize(dir).xz;\r
+    half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);\r
+/*--------------------------------------------------------------------------*/\r
+// (7)\r
+    half4 dir2_pos;\r
+    dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0));\r
+    dir1_pos.zw = pos.xy;\r
+    dir2_pos.zw = pos.xy;\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half lumaMaxNeSe = max(lumaNe, lumaSe.w);\r
+    #else\r
+        half lumaMaxNeSe = max(lumaNe, lumaSe.y);\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (8)\r
+    half4 temp1N;\r
+    temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;\r
+    temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));\r
+    half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe);\r
+    half lumaMin = min(lumaMinNwSw, lumaMinNeSe);\r
+/*--------------------------------------------------------------------------*/\r
+// (9)\r
+    half4 rgby1;\r
+    rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;\r
+    rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));\r
+    rgby1 = (temp1N + rgby1) * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+// (10)\r
+    half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0));\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        half lumaMaxM = max(lumaMax, rgbyM.w);\r
+        half lumaMinM = min(lumaMin, rgbyM.w);\r
+    #else\r
+        half lumaMaxM = max(lumaMax, rgbyM.y);\r
+        half lumaMinM = min(lumaMin, rgbyM.y);\r
+    #endif\r
+/*--------------------------------------------------------------------------*/\r
+// (11)\r
+    half4 temp2N;\r
+    temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;\r
+    temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));\r
+    half4 rgby2;\r
+    rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;\r
+    half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD;\r
+/*--------------------------------------------------------------------------*/\r
+// (12)\r
+    rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));\r
+    rgby2 = (temp2N + rgby2) * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+// (13)\r
+    rgby2 = (rgby2 + rgby1) * 0.5;\r
+/*--------------------------------------------------------------------------*/\r
+// (14)\r
+    #if (FXAA_GREEN_AS_LUMA == 0)\r
+        bool twoTapLt = rgby2.w < lumaMin;\r
+        bool twoTapGt = rgby2.w > lumaMax;\r
+    #else\r
+        bool twoTapLt = rgby2.y < lumaMin;\r
+        bool twoTapGt = rgby2.y > lumaMax;\r
+    #endif\r
+    bool earlyExit = lumaRangeM < lumaMax;\r
+    bool twoTap = twoTapLt || twoTapGt;\r
+/*--------------------------------------------------------------------------*/\r
+// (15)\r
+    if(twoTap) rgby2 = rgby1;\r
+    if(earlyExit) rgby2 = rgbyM;\r
+/*--------------------------------------------------------------------------*/\r
+    return rgby2; }\r
+/*==========================================================================*/\r
+#endif\r
diff --git a/examples/board_reprap/gfx/hb.png b/examples/board_reprap/gfx/hb.png
new file mode 100644 (file)
index 0000000..3ca05c7
Binary files /dev/null and b/examples/board_reprap/gfx/hb.png differ
diff --git a/examples/board_reprap/gfx/postproc.fs b/examples/board_reprap/gfx/postproc.fs
new file mode 100644 (file)
index 0000000..49de3fd
--- /dev/null
@@ -0,0 +1,87 @@
+#version 120
+
+// References:
+// http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/
+// http://jmonkeyengine.googlecode.com/svn-history/r9095/trunk/engine/src/core-data/Common/MatDefs/Post/
+
+#extension GL_EXT_gpu_shader4 : enable
+
+uniform sampler2D m_Texture;
+uniform vec2 g_Resolution = vec2(800,600);
+
+//uniform float m_VxOffset;
+uniform float m_SpanMax = 8.0;
+uniform float m_ReduceMul = (1.0/8.0);
+
+varying vec2 texCoord;
+varying vec4 posPos;
+
+#define FxaaTex(t, p) texture2D(t, p)
+
+    #define OffsetVec(a, b) ivec2(a, b)
+    #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
+
+vec3 FxaaPixelShader(
+  vec4 posPos,   // Output of FxaaVertexShader interpolated across screen.
+  sampler2D tex, // Input texture.
+  vec2 rcpFrame) // Constant {1.0/frameWidth, 1.0/frameHeight}.
+{
+
+    #define FXAA_REDUCE_MIN   (1.0/128.0)
+    //#define FXAA_REDUCE_MUL   (1.0/8.0)
+    //#define FXAA_SPAN_MAX     8.0
+
+    vec3 rgbNW = FxaaTex(tex, posPos.zw).xyz;
+    vec3 rgbNE = FxaaTexOff(tex, posPos.zw, OffsetVec(1,0), rcpFrame.xy).xyz;
+    vec3 rgbSW = FxaaTexOff(tex, posPos.zw, OffsetVec(0,1), rcpFrame.xy).xyz;
+    vec3 rgbSE = FxaaTexOff(tex, posPos.zw, OffsetVec(1,1), rcpFrame.xy).xyz;
+
+    vec3 rgbM  = FxaaTex(tex, posPos.xy).xyz;
+
+    vec3 luma = vec3(0.299, 0.587, 0.114);
+    float lumaNW = dot(rgbNW, luma);
+    float lumaNE = dot(rgbNE, luma);
+    float lumaSW = dot(rgbSW, luma);
+    float lumaSE = dot(rgbSE, luma);
+    float lumaM  = dot(rgbM,  luma);
+
+    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
+    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
+
+    vec2 dir;
+    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
+    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
+
+    float dirReduce = max(
+        (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * m_ReduceMul),
+        FXAA_REDUCE_MIN);
+    float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
+    dir = min(vec2( m_SpanMax,  m_SpanMax),
+          max(vec2(-m_SpanMax, -m_SpanMax),
+          dir * rcpDirMin)) * rcpFrame.xy;
+
+    vec3 rgbA = (1.0/2.0) * (
+        FxaaTex(tex, posPos.xy + dir * vec2(1.0/3.0 - 0.5)).xyz +
+        FxaaTex(tex, posPos.xy + dir * vec2(2.0/3.0 - 0.5)).xyz);
+    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
+        FxaaTex(tex, posPos.xy + dir * vec2(0.0/3.0 - 0.5)).xyz +
+        FxaaTex(tex, posPos.xy + dir * vec2(3.0/3.0 - 0.5)).xyz);
+
+    float lumaB = dot(rgbB, luma);
+
+    if ((lumaB < lumaMin) || (lumaB > lumaMax))
+    {
+        return rgbA;
+    }
+    else
+    {
+        return rgbB; 
+    }
+}
+
+void main()
+{
+    vec2 rcpFrame = vec2(1.0) / g_Resolution;
+    gl_FragColor = vec4(FxaaPixelShader(posPos, m_Texture, rcpFrame), 1.0);
+//     gl_FragColor.g *= 2;
+}
diff --git a/examples/board_reprap/gfx/postproc.vs b/examples/board_reprap/gfx/postproc.vs
new file mode 100644 (file)
index 0000000..1031ee1
--- /dev/null
@@ -0,0 +1,16 @@
+#version 120
+//uniform mat4 g_WorldViewProjectionMatrix;
+uniform vec2 g_Resolution = vec2(800,600);
+uniform float m_SubPixelShift = 1.0 / 4.0;
+
+varying vec2 texCoord;
+varying vec4 posPos;
+
+void main() {
+       gl_Position = ftransform();
+       gl_TexCoord[0] = gl_MultiTexCoord0;
+       texCoord = gl_MultiTexCoord0.xy;
+    vec2 rcpFrame = vec2(1.0) / g_Resolution;
+    posPos.xy = texCoord;
+    posPos.zw = texCoord - (rcpFrame * vec2(0.5 + m_SubPixelShift));
+}
index 9ec87c2575396f6bb0ec9a9fb43ca8a78ccc75d3..4eb3b1c9c525dca01ae157258b7bf989379e62c8 100644 (file)
-:10000000EFC700000C9418080C9418080C941808FA\r
-:100010000C9418080C9418080C9418080C941808E0\r
-:100020000C9418080C9418080C9418080C941808D0\r
-:10003000FFC700000C94DD3AFBC70000F9C70000C1\r
-:10004000F7C700000C94FA4C0C949D20F1C70000F7\r
-:100050000C945A22EDC70000EBC70000E9C700006E\r
-:10006000E7C70000E5C70000E3C70000E1C70000E4\r
+:10000000FCC700000C941A080C941A080C941A08E7\r
+:100010000C941A080C941A080C941A080C941A08D8\r
+:100020000C941A080C941A080C941A080C941A08C8\r
+:100030000C941A080C947F39FDC70000FBC7000020\r
+:10004000F9C700000C949A490C943321F3C70000BF\r
+:100050000C94E122EFC70000EDC70000EBC70000E1\r
+:10006000E9C70000E7C70000E5C70000E3C70000DC\r
 :10007000084AD73B3BCE016E84BCBFFDC12F3D6C0F\r
 :1000800074319ABD56833DDA3D00C77F11BED9E475\r
 :10009000BB4C3E916BAAAABE000000803F05A84C55\r
 :1000A000CDB2D44EB93836A9020C50B99186880821\r
-:1000B0003CA6AAAA2ABE000000803F4572726F7259\r
-:1000C0003A005072696E7465722073746F70706557\r
-:1000D000642064657520746F206572726F72732E70\r
-:1000E0002046697820746865206572726F7220619D\r
-:1000F0006E6420757365204D39393920746F207214\r
-:10010000657374617274212E202854656D70657258\r
-:1001100061747572652069732072657365742E2031\r
-:10012000536574206974206265666F72652072651C\r
-:100130007374617274696E6729005072696E7465B8\r
-:10014000722068616C7465642E206B696C6C282960\r
-:100150002063616C6C6564202121006F6B00526527\r
-:1001600073656E643A006563686F3A002200556EED\r
-:100170006B6E6F776E20636F6D6D616E643A2200F7\r
-:100180007A5F6D696E3A00795F6D696E3A00785FEB\r
-:100190006D696E3A005A3A00593A0020436F756E05\r
-:1001A0007420583A00453A005A3A00593A00583AF1\r
-:1001B000004649524D574152455F4E414D453A4DDB\r
-:1001C00061726C696E2056313B20537072696E7497\r
-:1001D00065722F6772626C206D617368757020663E\r
-:1001E0006F722067656E36204649524D5741524521\r
-:1001F0005F55524C3A687474703A2F2F7777772E88\r
-:100200006D656E64656C2D70617274732E636F6DB5\r
-:100210002050524F544F434F4C5F56455253494F15\r
-:100220004E3A312E30204D414348494E455F545996\r
-:1002300050453A4D656E64656C204558545255449E\r
-:1002400045525F434F554E543A310A0020423A001E\r
-:1002500020453A00543A0020573A0020453A0054CD\r
-:100260003A0020403A0020423A006F6B20543A0096\r
-:100270005072696E7465722073746F70706564205B\r
-:1002800064657520746F206572726F72732E2046DC\r
-:10029000697820746865206572726F7220616E647F\r
-:1002A00020757365204D39393920746F207265735C\r
-:1002B00074617274212E202854656D7065726174AA\r
-:1002C0007572652069732072657365742E2053659D\r
-:1002D00074206974206265666F726520726573743C\r
-:1002E000617274696E6729006F6B004E6F204C69F4\r
-:1002F0006E65204E756D6265722077697468206343\r
-:100300006865636B73756D2C204C617374204C6948\r
-:100310006E653A004E6F20436865636B73756D20A0\r
-:1003200077697468206C696E65206E756D626572A0\r
-:100330002C204C617374204C696E653A00636865CB\r
-:10034000636B73756D206D69736D617463682C20C8\r
-:100350004C617374204C696E653A004C696E65207F\r
-:100360004E756D626572206973206E6F74204C61EA\r
-:100370007374204C696E65204E756D6265722B3109\r
-:100380002C204C617374204C696E653A002020501B\r
-:100390006C616E6E657242756666657242797465EF\r
-:1003A000733A20002046726565204D656D6F727945\r
-:1003B0003A20006572696B00207C20417574686F7B\r
-:1003C000723A2000323031322D30322D3235002059\r
-:1003D0004C61737420557064617465643A20003117\r
-:1003E0002E302E3020524332004D61726C696E3ACD\r
-:1003F000200020536F6674776172652052657365C3\r
-:100400007400205761746368646F67205265736578\r
-:1004100074002042726F776E206F7574205265737E\r
-:100420006574002045787465726E616C2052657346\r
-:10043000657400506F7765725570007374617274E3\r
-:10044000002200656E717565696E67202200656324\r
-:10045000686F3A0020746F6F206C6F6E672065784C\r
-:1004600074727573696F6E2070726576656E7465EF\r
-:10047000640020636F6C6420657874727573696FB3\r
-:100480006E2070726576656E7465640024F427D3FF\r
-:10049000FD204D0FB0119A05160CE9022D09C80177\r
-:1004A000650733013206DE005405A700AD04830062\r
-:1004B0002A046900C10356006B03480023033D0072\r
-:1004C000E6023500B1022D00840228005C02230000\r
-:1004D0003902200019021C00FD011900E401170077\r
-:1004E000CD011500B8011300A50111009401100001\r
-:1004F00084010F0075010E0067010D005A010C0008\r
-:100500004E010B0043010A0039010A002F010900C6\r
-:10051000260109001D010800150107000E01080051\r
-:1005200006010700FF000600F9000600F3000600C0\r
-:10053000ED000600E7000500E2000500DD00050013\r
-:10054000D8000500D3000400CF000500CA00040055\r
-:10055000C6000400C2000400BE000300BB0004008B\r
-:10056000B7000300B4000300B1000400AD000300B5\r
-:10057000AA000300A7000200A5000300A2000300D8\r
-:100580009F0002009D0003009A00020098000300F3\r
-:100590009500020093000200910002008F0002000B\r
-:1005A0008D0002008B00020089000200870002001B\r
-:1005B000850002008300020081000100800002002B\r
-:1005C0007E0002007C0001007B0002007900010037\r
-:1005D000780002007600010075000100740002003E\r
-:1005E0007200010071000100700002006E00010045\r
-:1005F0006D0001006C0001006B0002006900010049\r
-:10060000680001006700010066000100650001004C\r
-:10061000640001006300010062000100610001004C\r
-:10062000600001005F0001005E0001005D0001004C\r
-:100630005C0001005B0000005B0001005A0001004B\r
-:100640005900010058000100570000005700010048\r
-:100650005600010055000100540000005400010044\r
-:100660005300010052000100510000005100010040\r
-:10067000500001004F0000004F0001004E0000003C\r
-:100680004E0001004D0001004C0000004C00010034\r
-:100690004B0000004B0001004A000100490000002F\r
-:1006A0004900010048000000480001004700000028\r
-:1006B0004700010046000000460001004500000020\r
-:1006C0004500010044000000440001004300000018\r
-:1006D0004300010042000000420001004100000010\r
-:1006E0004100000041000100400000004000010006\r
-:1006F0003F0000003F0001003E0000003E000000FF\r
-:100700003E0001003D0000003D0001003C000000F3\r
-:100710003C0000003C0001003B0000003B000000EA\r
-:100720003B0001003A0000003A0000003A000100DE\r
-:1007300039000000390000003900010038000000D5\r
-:1007400038000000380001003700000037000000CA\r
-:1007500037000100360000003600000036000100BE\r
-:1007600035000000350000003500000035000100B4\r
-:1007700034000000340000003400010033000000A9\r
-:10078000330000003300000033000100320000009D\r
-:100790003200000032000000320001003100000091\r
-:1007A0003100000031000000310001003000000085\r
-:1007B0003000000030000000300001002F00000079\r
-:1007C0002F0000002F0000002F0001002E0000006D\r
-:1007D0002E0000002E0000002E0000002E00010060\r
-:1007E0002D0000002D0000002D0000002D00010054\r
-:1007F0002C0000002C0000002C0000002C00000049\r
-:100800002C0001002B0000002B0000002B0000003A\r
-:100810002B0000002B0001002A0000002A0000002D\r
-:100820002A0000002A0000002A0000002A0001001F\r
-:100830002900000029000000290000002900000014\r
-:100840002900000029000100280000002800000005\r
-:1008500028000000280000002800010027000000F8\r
-:1008600027000000270000002700000027000000EC\r
-:1008700027000000270001002600000026000000DD\r
-:1008800026000000260000002600000024F4B12805\r
-:1008900073CB111D62AECC159698F410A287900D03\r
-:1008A000127A190BF96E4009B965D307E65DB506F2\r
-:1008B0003157D005615116054B4C7D04CE47FD03E1\r
-:1008C000D14392033F403603093DE902203AA40296\r
-:1008D0007C376A0212353602DC320802D430E1017C\r
-:1008E000F32EBD01362D9E01982B8101172A670139\r
-:1008F000B028500160273B0125262801FD24160160\r
-:10090000E7230701E022F800E821EB00FD20DE00EC\r
-:100910001F20D3004C1FC800841EBF00C51DB5009A\r
-:10092000101DAD00631CA500BE1B9E00201B970080\r
-:10093000891A9100F8198A006E198500E9187F005C\r
-:100940006A187B00EF1776007917710008176D00A1\r
-:100950009B166A0031166500CC1562006A155F00AF\r
-:100960000B155B00B01458005814560002145200C6\r
-:10097000B013500060134E0012134B00C712490011\r
-:100980007E12460038124500F3114300B0114000BA\r
-:1009900070113F0031113D00F4103C00B8103A00D6\r
-:1009A0007E103800461037000F103500DA0F340083\r
-:1009B000A60F3300730F3100420F3000120F3000CA\r
-:1009C000E20E2D00B50E2D00880E2C005C0E2B00C3\r
-:1009D000310E2A00070E2800DF0D2800B70D270072\r
-:1009E000900D26006A0D2600440D2400200D2400E1\r
-:1009F000FC0C2300D90C2200B70C2200950C21001E\r
-:100A0000740C2000540C1F00350C1F00160C1F0026\r
-:100A1000F70B1E00D90B1D00BC0B1C00A00B1C000B\r
-:100A2000840B1C00680B1B004D0B1B00320B1A00C3\r
-:100A3000180B1900FF0A1900E60A1900CD0A180060\r
-:100A4000B50A18009D0A1800850A17006E0A1600DC\r
-:100A5000580A1600420A16002C0A1600160A15003B\r
-:100A6000010A1500EC091400D8091400C409140087\r
-:100A7000B00914009C0913008909130076091300BA\r
-:100A800063091200510912003F0912002D091100DB\r
-:100A90001C0912000A091100F9081000E9081100E8\r
-:100AA000D8081000C8081000B8081000A8081000E6\r
-:100AB00098080F0089080F007A080F006B080F00D4\r
-:100AC0005C080F004D080E003F080E0031080E00B4\r
-:100AD00023080E0015080E0007080D00FA070D0088\r
-:100AE000ED070D00E0070D00D3070D00C6070D0050\r
-:100AF000B9070C00AD070C00A1070D0094070B000F\r
-:100B000089070C007D070C0071070C0065070B00BE\r
-:100B10005A070B004F070B0044070B0039070B0067\r
-:100B20002E070B0023070B0018070A000E070B0007\r
-:100B300003070A00F9060A00EF060A00E5060A00A4\r
-:100B4000DB060A00D1060900C8060A00BE06090035\r
-:100B5000B5060A00AB060900A206090099060900BD\r
-:100B600090060900870609007E060900750609003F\r
-:100B70006C060800640609005B06080053060900BD\r
-:100B80004A060800420608003A0608003206080035\r
-:100B90002A060800220608001A06080012060700A6\r
-:100BA0000B06080003060800FB050700F405080013\r
-:100BB000EC050700E5050700DE050700D70507007F\r
-:100BC000D0050700C9050700C2050700BB050700DF\r
-:100BD000B4050700AD050700A6050600A00507003F\r
-:100BE00099050700920506008C050600860507009A\r
-:100BF0007F05060079050600730507006C050600F1\r
-:100C000066050600600506005A0506005405060044\r
-:100C10004E05060048050600420505003D05060094\r
-:100C200037050600310505002C05060026050500E0\r
-:100C3000210506001B050500160506001005050028\r
-:100C40000B0505000605060000050500FB04050070\r
-:100C5000F6040500F1040500EC040500E7040500B6\r
-:100C6000E2040500DD040500D8040500D3040500F6\r
-:100C7000CE040500C9040500C4040500BF04040037\r
-:100C8000BB040500B6040500B10405006563686F88\r
-:100C90003A00205A3A0020593A0020583A00656E2E\r
-:100CA0006473746F7073206869743A2000457272BF\r
-:100CB0006F723A0054656D7065726174757265206B\r
-:100CC0006865617465642062656420737769746324\r
-:100CD000686564206F66662E204D415854454D501E\r
-:100CE00020747269676765726564202121003A206B\r
-:100CF000457874727564657220737769746368658A\r
-:100D000064206F66662E204D494E54454D50207428\r
-:100D100072696767657265642021003A20457874BE\r
-:100D20007275646572207377697463686564206F97\r
-:100D300066662E204D415854454D502074726967A7\r
-:100D400067657265642021001000C90220013C0122\r
-:100D500030020A014003EF005004DD006005D000BE\r
-:100D60007006C5008007BC009008B500A009AE0061\r
-:100D7000B00AA900C00BA300D00C9F00E00D9A00A0\r
-:100D8000F00E96000010930010118F0020128C00BE\r
-:100D900030138800401485005015820060168000D2\r
-:100DA00070177D0080187A0090197800A01A7500DD\r
-:100DB000B01B7300C01C7000D01D6E00E01E6C00E4\r
-:100DC000F01F6A00002167001022650020236300E5\r
-:100DD0003024610040255F0050265C0060275A00E7\r
-:100DE0007028580080295600902A5400A02B5100EA\r
-:100DF000B02C4F00C02D4D00D02E4B00E02F4800EE\r
-:100E0000F0304600003243001033400020343D00F3\r
-:100E100030353A0040363700503734006038300003\r
-:100E200070392C00803A2800903B2200A03C1C0026\r
-:100E3000B03D1400C03E0800D03F0000202D2049E6\r
-:100E40006E76616C69642065787472756465722071\r
-:100E50006E756D626572202100202D20496E7661CD\r
-:100E60006C6964206578747275646572206E756D46\r
-:100E7000626572210020403A006F6B20543A0050A6\r
-:100E80004944204175746F74756E65206661696CA4\r
-:100E9000656420212C2054656D70657261747572D3\r
-:100EA0006520746F206869676800204B643A2000F1\r
-:100EB000204B693A2000204B703A2000204E6F20D2\r
-:100EC0006F76657273686F6F742000204B643A20F0\r
-:100ED00000204B693A2000204B703A200020536FCD\r
-:100EE0006D65206F76657273686F6F742000204B9C\r
-:100EF000643A2000204B693A2000204B703A2000D1\r
-:100F000020436C617369632050494420002054756C\r
-:100F10003A2000204B753A2000206D61783A20007D\r
-:100F2000206D696E3A200020643A200020626961D9\r
-:100F3000733A2000002124272A002225282B002094\r
-:100F4000232629020202020202020204040404040B\r
-:100F50000404040303030303030303010101010168\r
-:100F60000101010102040810204080010204081060\r
-:100F7000204080010204081020408080402010089A\r
-:100F80000402010000000102000000000000000453\r
-:100F90000307060000000000000000000000000041\r
-:100FA000000000494E46494E4954594E414ECDCC61\r
-:100FB000CC3D0AD7233C17B7D13877CC2B32959547\r
-:100FC000E6241FB14F0A000020410000C842004043\r
-:100FD0001C4620BCBE4CCA1B0E5AAEC59D7477245D\r
-:100FE00011241FBECFEFD0E1DEBFCDBF12E0A0E0E5\r
-:100FF000B1E0E2E2F2EB02C005900D92A638B10733\r
-:10100000D9F71AE0A6E8B2E001C01D92A73FB107E8\r
-:10101000E1F71FE0C0EEDFE004C02297FE010E946E\r
-:101020005D53CE3DD107C9F70E9498200C940F590B\r
-:101030000C940000AF92BF92CF92DF92EF92FF929A\r
-:101040000F931F93DF93CF93CDB7DEB7E0970FB623\r
-:10105000F894DEBF0FBECDBFDE011196EFE6F2E0E1\r
-:1010600080E101900D928150E1F7DE015196EFE5AC\r
-:10107000F2E080E101900D928150E1F7DE0191965E\r
-:10108000EFE4F2E080E101900D928150E1F7BE01C2\r
-:101090006F5F7F4F40E255E021E1A22EB12CAC0EF4\r
-:1010A000BD1E00E115E091E2E92EF12CEC0EFD1ED3\r
-:1010B00080E3C82E85E0D82E20E030E0FB0181914E\r
-:1010C0009191A191B191BF01FA0181939193A19363\r
-:1010D000B193AF01F50181919191A191B1915F011E\r
-:1010E000F80181939193A193B1938F01F7018191BD\r
-:1010F0009191A191B1917F01F60181939193A19377\r
-:10110000B1936F012F5F3F4F24303105B9F680E076\r
-:1011100090E0AAEFB3E48093440590934505A09333\r
-:101120004605B093470580E090E8ABE3B5E48093D3\r
-:10113000480590934905A0934A05B0934B0580E07C\r
-:1011400090E0DC018093400590934105A093420517\r
-:10115000B093430520E23EE440E050E020930C05CC\r
-:1011600030930D0540930E0550930F05809358055D\r
-:1011700090935905A0935A05B0935B0580E090E0E9\r
-:10118000A0EAB1E480934C0590934D05A0934E05E1\r
-:10119000B0934F058DEC9CECACECBEE38093500516\r
-:1011A00090935105A0935205B093530580E090E0D1\r
-:1011B000A0EAB0E48093540590935505A09356059A\r
-:1011C000B0935705E6E6F1E007C09091C00095FFA7\r
-:1011D000FCCF8093C600319684918823B1F7E0E07C\r
-:1011E000F1E006C09091C00095FFFCCF8093C6004F\r
-:1011F00081918823B9F78091C00085FFFCCF8AE0F8\r
-:101200008093C600E0960FB6F894DEBF0FBECDBF48\r
-:10121000CF91DF911F910F91FF90EF90DF90CF90D2\r
-:10122000BF90AF900895DF93CF9300D0CDB7DEB7D6\r
-:101230008091F10A9091F20A9E012F5F3F4F009733\r
-:1012400019F4275F3A4002C0281B390B3A832983DF\r
-:1012500089819A810F900F90CF91DF910895AF927D\r
-:10126000BF92CF92DF92EF92FF920F931F93CF9393\r
-:10127000DF938BE095E040E052EC61E070E00E948B\r
-:101280008F22EBE3F4E007C09091C00095FFFCCF04\r
-:101290008093C600319684918823B1F78091C00075\r
-:1012A00085FFFCCF8AE08093C60086E691E0FC01D2\r
+:1000B0003CA6AAAA2ABE000000803F6563686F3A8A\r
+:1000C00000737461727400506F7765725570002010\r
+:1000D00045787465726E616C20526573657400209A\r
+:1000E00042726F776E206F7574205265736574006D\r
+:1000F000205761746368646F67205265736574008C\r
+:1001000020536F6674776172652052657365740061\r
+:100110004D61726C696E3A2000312E302E302052C3\r
+:10012000433200204C6173742055706461746564BF\r
+:100130003A2000323031322D30352D303200207CE3\r
+:1001400020417574686F723A20006572696B0020F7\r
+:1001500046726565204D656D6F72793A20002020EA\r
+:10016000506C616E6E657242756666657242797436\r
+:1001700065733A20004572726F723A004C696E6581\r
+:10018000204E756D626572206973206E6F74204C0D\r
+:10019000617374204C696E65204E756D6265722BBB\r
+:1001A000312C204C617374204C696E653A00636891\r
+:1001B00065636B73756D206D69736D617463682C15\r
+:1001C000204C617374204C696E653A004E6F204379\r
+:1001D0006865636B73756D2077697468206C696EF0\r
+:1001E00065206E756D6265722C204C617374204CB5\r
+:1001F000696E653A004E6F204C696E65204E756DD4\r
+:10020000626572207769746820636865636B7375D3\r
+:100210006D2C204C617374204C696E653A006F6BD5\r
+:10022000005072696E7465722073746F70706564CB\r
+:100230002064657520746F206572726F72732E2052\r
+:1002400046697820746865206572726F7220616EED\r
+:100250006420757365204D39393920746F207265BB\r
+:100260007374617274212E202854656D70657261FB\r
+:10027000747572652069732072657365742E2053DE\r
+:100280006574206974206265666F7265207265739B\r
+:1002900074617274696E6729006F6B20543A002094\r
+:1002A0002F0020423A00202F0020403A00543A000C\r
+:1002B00020453A0020573A00543A0020453A0020A1\r
+:1002C000423A004649524D574152455F4E414D45D5\r
+:1002D0003A4D61726C696E2056313B2053707269E1\r
+:1002E0006E7465722F6772626C206D6173687570D1\r
+:1002F00020666F722067656E36204649524D574121\r
+:1003000052455F55524C3A687474703A2F2F777784\r
+:10031000772E6D656E64656C2D70617274732E63DB\r
+:100320006F6D2050524F544F434F4C5F56455253C0\r
+:10033000494F4E3A312E30204D414348494E455F9A\r
+:10034000545950453A4D656E64656C204558545279\r
+:10035000554445525F434F554E543A310A00583A7E\r
+:1003600000593A005A3A00453A0020436F756E74BE\r
+:1003700020583A00593A005A3A00785F6D696E3A4F\r
+:1003800000795F6D696E3A007A5F6D696E3A00556B\r
+:100390006E6B6E6F776E20636F6D6D616E643A2267\r
+:1003A000002200526573656E643A006F6B005072F4\r
+:1003B000696E7465722068616C7465642E206B6967\r
+:1003C0006C6C28292063616C6C65642021210050CD\r
+:1003D00072696E7465722073746F707065642064E6\r
+:1003E000657520746F206572726F72732E20466976\r
+:1003F0007820746865206572726F7220616E642067\r
+:10040000757365204D39393920746F2072657374A6\r
+:10041000617274212E202854656D70657261747547\r
+:1004200072652069732072657365742E205365743C\r
+:10043000206974206265666F7265207265737461ED\r
+:100440007274696E6729000000000102000000005C\r
+:100450000000000403070600000000000000000088\r
+:10046000000000000000000102040810204080018C\r
+:1004700002040810204080010204081020408080FF\r
+:1004800040201008040201020202020202020204D9\r
+:100490000404040404040403030303030303030127\r
+:1004A00001010101010101002225282B002124273F\r
+:1004B0002A6563686F3A0020636F6C642065787406\r
+:1004C000727573696F6E2070726576656E7465649F\r
+:1004D0000020746F6F206C6F6E6720657874727582\r
+:1004E00073696F6E2070726576656E746564006501\r
+:1004F00063686F3A00656E6473746F707320686927\r
+:10050000743A200020583A0020593A00205A3A0004\r
+:1005100024F427D3FD204D0FB0119A05160CE902E3\r
+:100520002D09C801650733013206DE005405A70016\r
+:10053000AD0483002A046900C10356006B03480020\r
+:1005400023033D00E6023500B1022D00840228009D\r
+:100550005C0223003902200019021C00FD01190071\r
+:10056000E4011700CD011500B8011300A501110029\r
+:100570009401100084010F0075010E0067010D0049\r
+:100580005A010C004E010B0043010A0039010A0018\r
+:100590002F010900260109001D01080015010700AF\r
+:1005A0000E01080006010700FF000600F900060022\r
+:1005B000F3000600ED000600E7000500E20005007C\r
+:1005C000DD000500D8000500D3000400CF000500C1\r
+:1005D000CA000400C6000400C2000400BE000300FC\r
+:1005E000BB000400B7000300B4000300B100040026\r
+:1005F000AD000300AA000300A7000200A50003004D\r
+:10060000A20003009F0002009D0003009A00020068\r
+:100610009800030095000200930002009100020080\r
+:100620008F0002008D0002008B0002008900020092\r
+:1006300087000200850002008300020081000100A3\r
+:10064000800002007E0002007C0001007B000200AE\r
+:1006500079000100780002007600010075000100B9\r
+:1006600074000200720001007100010070000200BD\r
+:100670006E0001006D0001006C0001006B000200C3\r
+:1006800069000100680001006700010066000100C8\r
+:1006900065000100640001006300010062000100C8\r
+:1006A00061000100600001005F0001005E000100C8\r
+:1006B0005D0001005C0001005B0000005B000100C8\r
+:1006C0005A000100590001005800010057000000C5\r
+:1006D00057000100560001005500010054000000C1\r
+:1006E00054000100530001005200010051000000BD\r
+:1006F00051000100500001004F0000004F000100B8\r
+:100700004E0000004E0001004D0001004C000000B2\r
+:100710004C0001004B0000004B0001004A000100AA\r
+:1007200049000000490001004800000048000100A5\r
+:10073000470000004700010046000000460001009D\r
+:100740004500000045000100440000004400010095\r
+:10075000430000004300010042000000420001008D\r
+:100760004100000041000000410001004000000085\r
+:10077000400001003F0000003F0001003E0000007B\r
+:100780003E0000003E0001003D0000003D00010071\r
+:100790003C0000003C0000003C0001003B00000069\r
+:1007A0003B0000003B0001003A0000003A0000005E\r
+:1007B0003A00010039000000390000003900010052\r
+:1007C0003800000038000000380001003700000049\r
+:1007D000370000003700010036000000360000003E\r
+:1007E0003600010035000000350000003500000033\r
+:1007F0003500010034000000340000003400010026\r
+:10080000330000003300000033000000330001001B\r
+:10081000320000003200000032000000320001000F\r
+:100820003100000031000000310000003100010003\r
+:1008300030000000300000003000000030000100F7\r
+:100840002F0000002F0000002F0000002F000100EB\r
+:100850002E0000002E0000002E0000002E000000E0\r
+:100860002E0001002D0000002D0000002D000000D2\r
+:100870002D0001002C0000002C0000002C000000C6\r
+:100880002C0000002C0001002B0000002B000000B9\r
+:100890002B0000002B0000002B0001002A000000AC\r
+:1008A0002A0000002A0000002A0000002A000000A0\r
+:1008B0002A00010029000000290000002900000092\r
+:1008C0002900000029000000290001002800000084\r
+:1008D0002800000028000000280000002800010077\r
+:1008E000270000002700000027000000270000006C\r
+:1008F000270000002700000027000100260000005C\r
+:10090000260000002600000026000000260000004F\r
+:1009100024F4B12873CB111D62AECC159698F41057\r
+:10092000A287900D127A190BF96E4009B965D307A9\r
+:10093000E65DB5063157D005615116054B4C7D0477\r
+:10094000CE47FD03D14392033F403603093DE90200\r
+:10095000203AA4027C376A0212353602DC320802E1\r
+:10096000D430E101F32EBD01362D9E01982B81017B\r
+:10097000172A6701B028500160273B01252628016E\r
+:10098000FD241601E7230701E022F800E821EB002F\r
+:10099000FD20DE001F20D3004C1FC800841EBF00B6\r
+:1009A000C51DB500101DAD00631CA500BE1B9E003B\r
+:1009B000201B9700891A9100F8198A006E1985008A\r
+:1009C000E9187F006A187B00EF177600791771002D\r
+:1009D00008176D009B166A0031166500CC15620081\r
+:1009E0006A155F000B155B00B014580058145600D0\r
+:1009F00002145200B013500060134E0012134B004B\r
+:100A0000C71249007E12460038124500F311430018\r
+:100A1000B011400070113F0031113D00F4103C0056\r
+:100A2000B8103A007E103800461037000F1035001D\r
+:100A3000DA0F3400A60F3300730F3100420F30007D\r
+:100A4000120F3000E20E2D00B50E2D00880E2C0086\r
+:100A50005C0E2B00310E2A00070E2800DF0D280047\r
+:100A6000B70D2700900D26006A0D2600440D2400C6\r
+:100A7000200D2400FC0C2300D90C2200B70C22000E\r
+:100A8000950C2100740C2000540C1F00350C1F0025\r
+:100A9000160C1F00F70B1E00D90B1D00BC0B1C0011\r
+:100AA000A00B1C00840B1C00680B1B004D0B1B00D3\r
+:100AB000320B1A00180B1900FF0A1900E60A190078\r
+:100AC000CD0A1800B50A18009D0A1800850A1700FB\r
+:100AD0006E0A1600580A1600420A16002C0A160062\r
+:100AE000160A1500010A1500EC091400D8091400B3\r
+:100AF000C4091400B00914009C09130089091300EB\r
+:100B00007609130063091200510912003F0912000F\r
+:100B10002D0911001C0912000A091100F908100022\r
+:100B2000E9081100D8081000C8081000B808100023\r
+:100B3000A808100098080F0089080F007A080F0015\r
+:100B40006B080F005C080F004D080E003F080E00F8\r
+:100B500031080E0023080E0015080E0007080D00CE\r
+:100B6000FA070D00ED070D00E0070D00D3070D009B\r
+:100B7000C6070D00B9070C00AD070C00A1070D005A\r
+:100B800094070B0089070C007D070C0071070C000F\r
+:100B900065070B005A070B004F070B0044070B00BB\r
+:100BA00039070B002E070B0023070B0018070A005C\r
+:100BB0000E070B0003070A00F9060A00EF060A00F9\r
+:100BC000E5060A00DB060A00D1060900C8060A008D\r
+:100BD000BE060900B5060A00AB060900A206090018\r
+:100BE0009906090090060900870609007E0609009B\r
+:100BF000750609006C060800640609005B0608001B\r
+:100C0000530609004A060800420608003A06080092\r
+:100C1000320608002A060800220608001A06080004\r
+:100C2000120607000B06080003060800FB05070074\r
+:100C3000F4050800EC050700E5050700DE050700E0\r
+:100C4000D7050700D0050700C9050700C205070042\r
+:100C5000BB050700B4050700AD050700A6050600A3\r
+:100C6000A005070099050700920506008C050600FF\r
+:100C7000860507007F050600790506007305070055\r
+:100C80006C05060066050600600506005A050600AC\r
+:100C9000540506004E0506004805060042050500FD\r
+:100CA0003D05060037050600310505002C05060048\r
+:100CB00026050500210506001B0505001605060092\r
+:100CC000100505000B0505000605060000050500DA\r
+:100CD000FB040500F6040500F1040500EC04050022\r
+:100CE000E7040500E2040500DD040500D804050062\r
+:100CF000D3040500CE040500C9040500C4040500A2\r
+:100D0000BF040400BB040500B6040500B1040500DF\r
+:100D100020626961733A200020643A2000206D69E6\r
+:100D20006E3A2000206D61783A2000204B753A2001\r
+:100D3000002054753A200020436C61736963205091\r
+:100D400049442000204B703A2000204B693A200093\r
+:100D5000204B643A2000504944204175746F7475EB\r
+:100D60006E65206661696C6564212054656D7065EF\r
+:100D700072617475726520746F2068696768006FAE\r
+:100D80006B20543A0020403A005049442041757489\r
+:100D90006F74756E65206661696C65642120746985\r
+:100DA0006D656F757400504944204175746F74759A\r
+:100DB0006E652066696E6973686564202120506CD9\r
+:100DC00061636520746865204B702C204B6920613D\r
+:100DD0006E64204B6420636F6E7374616E74732055\r
+:100DE000696E2074686520636F6E666967757261ED\r
+:100DF00074696F6E2E68004572726F723A00202D12\r
+:100E000020496E76616C69642065787472756465DA\r
+:100E100072206E756D62657221001000C90220019A\r
+:100E20003C0130020A014003EF005004DD00600580\r
+:100E3000D0007006C5008007BC009008B500A0096E\r
+:100E4000AE00B00AA900C00BA300D00C9F00E00DBB\r
+:100E50009A00F00E96000010930010118F002012DF\r
+:100E60008C003013880040148500501582006016F5\r
+:100E7000800070177D0080187A0090197800A01A01\r
+:100E80007500B01B7300C01C7000D01D6E00E01E0A\r
+:100E90006C00F01F6A00002167001022650020230B\r
+:100EA00063003024610040255F0050265C0060270D\r
+:100EB0005A007028580080295600902A5400A02B10\r
+:100EC0005100B02C4F00C02D4D00D02E4B00E02F14\r
+:100ED0004800F03046000032430010334000203418\r
+:100EE0003D0030353A004036370050373400603826\r
+:100EF000300070392C00803A2800903B2200A03C42\r
+:100F00001C00B03D1400C03E0800D03F0000202D62\r
+:100F100020496E76616C69642065787472756465C9\r
+:100F200072206E756D6265722021003A20457874DA\r
+:100F30007275646572207377697463686564206F85\r
+:100F400066662E204D415854454D50207472696795\r
+:100F500067657265642021003A2045787472756473\r
+:100F60006572207377697463686564206F66662EA6\r
+:100F7000204D494E54454D50207472696767657223\r
+:100F8000656420210054656D7065726174757265C9\r
+:100F90002068656174656420626564207377697494\r
+:100FA00063686564206F66662E204D415854454D38\r
+:100FB0005020747269676765726564202121004959\r
+:100FC0004E46494E4954594E414E000020410000C2\r
+:100FD000C84200401C4620BCBE4CCA1B0E5AAEC5BF\r
+:100FE0009D74CDCCCC3D0AD7233C17B7D13877CCF4\r
+:100FF0002B329595E6241FB14F0A11241FBECFEF67\r
+:10100000D0E1DEBFCDBF12E0A0E0B1E0E8EDFAEA4A\r
+:1010100002C005900D92A038B107D9F71AE0A0E8F8\r
+:10102000B2E001C01D92A13FB107E1F70E942E215D\r
+:101030000C946A550C940000AF92BF92CF92DF924D\r
+:10104000EF92FF920F931F93CF93DF93CDB7DEB74D\r
+:10105000E0970FB6F894DEBF0FBECDBF80E1E7E3A7\r
+:10106000F1E0DE01919601900D928A95E1F780E121\r
+:10107000E7E4F1E0DE01519601900D928A95E1F7E7\r
+:1010800080E1E7E5F1E0DE01119601900D928A958D\r
+:10109000E1F76E0181E2C80ED11C85E2E82E8AE0FC\r
+:1010A000F82E8E010F5E1F4F65E37AE0AE014F5FB1\r
+:1010B0005F4F95E1A92E9AE0B92E20E030E0F601CD\r
+:1010C00081919191A191B1916F01F70181939193D8\r
+:1010D000A193B1937F01F80181919191A191B19177\r
+:1010E0008F01FB0181939193A193B193BF01FA0109\r
+:1010F00081919191A191B191AF01F501819391936A\r
+:10110000A193B1935F012F5F3F4F24303105B9F6B2\r
+:1011100080E090E0AAEFB3E480930D0A90930E0A6A\r
+:10112000A0930F0AB093100A80E090E8ABE3B5E417\r
+:101130008093090A90930A0AA0930B0AB0930C0AB1\r
+:101140001092110A1092120A1092130A1092140AA5\r
+:1011500080E29EE4A0E0B0E08093450A9093460AC6\r
+:10116000A093470AB093480A1092F9091092FA091D\r
+:101170001092FB091092FC0980E090E0A0EAB1E433\r
+:101180008093050A9093060AA093070AB093080A71\r
+:101190008DEC9CECACECBEE38093010A9093020AC8\r
+:1011A000A093030AB093040A80E090E0A0EAB0E4C0\r
+:1011B0008093FD099093FE09A093FF09B093000A64\r
+:1011C000EBEBF0E007C09091C00095FFFCCF80935F\r
+:1011D000C600319684918111F6CFE7E6F1E006C0B2\r
+:1011E0009091C00095FFFCCF8093C6008191811142\r
+:1011F000F7CF8091C00085FFFCCF8AE08093C600C6\r
+:10120000E0960FB6F894DEBF0FBECDBFDF91CF9151\r
+:101210001F910F91FF90EF90DF90CF90BF90AF9014\r
+:101220000895CF93DF9300D0CDB7DEB78091EB0A5E\r
+:101230009091EC0A9E012F5F3F4F009719F4215FB8\r
+:101240003A4002C0281B390B3A83298389819A814D\r
+:101250000F900F90DF91CF910895CF92DF92EF9290\r
+:10126000FF920F931F93CF93DF9300D000D0CDB7A1\r
+:10127000DEB740E052EC61E070E081E894E00E946B\r
+:101280001623E1ECF0E007C09091C00095FFFCCF81\r
+:101290008093C600319684918111F6CF8091C00071\r
+:1012A00085FFFCCF8AE08093C6008BEB90E0FC01C9\r
 :1012B00007C03091C00035FFFCCF2093C6003196A7\r
-:1012C00024912223B1F724B720FF14C0E3E3F4E014\r
+:1012C00024912111F6CF24B720FF14C0E7ECF0E001\r
 :1012D00007C04091C00045FFFCCF3093C600319657\r
-:1012E00034913323B1F73091C00035FFFCCF3AE0A1\r
-:1012F0003093C60021FF14C0E3E2F4E007C0409140\r
-:10130000C00045FFFCCF3093C600319634913323A3\r
-:10131000B1F73091C00035FFFCCF3AE03093C60002\r
-:1013200022FF14C0E2E1F4E007C04091C00045FF95\r
-:10133000FCCF3093C600319634913323B1F730910E\r
+:1012E00034913111F6CF3091C00035FFFCCF3AE098\r
+:1012F0003093C60021FF14C0EFECF0E007C040912E\r
+:10130000C00045FFFCCF3093C600319634913111B7\r
+:10131000F6CF3091C00035FFFCCF3AE03093C600E5\r
+:1013200022FF14C0EFEDF0E007C04091C00045FF80\r
+:10133000FCCF3093C600319634913111F6CF309105\r
 :10134000C00035FFFCCF3AE03093C60023FF14C045\r
-:10135000E2E0F4E007C04091C00045FFFCCF3093CD\r
-:10136000C600319634913323B1F73091C00035FF78\r
-:10137000FCCF3AE03093C60025FF14C0E2EFF3E063\r
+:10135000E0EFF0E007C04091C00045FFFCCF3093C4\r
+:10136000C600319634913111F6CF3091C00035FF6F\r
+:10137000FCCF3AE03093C60025FF14C0E0E0F1E076\r
 :1013800007C03091C00035FFFCCF2093C6003196D6\r
-:1013900024912223B1F72091C00025FFFCCF2AE041\r
-:1013A0002093C60014BEE9EEF3E007C03091C00000\r
-:1013B00035FFFCCF2093C600319624912223B1F74C\r
-:1013C000EFEDF3E007C03091C00035FFFCCF209374\r
-:1013D000C600319624912223B1F72091C00025FF49\r
-:1013E000FCCF2AE02093C600FC012491E6E6F1E060\r
+:1013900024912111F6CF2091C00025FFFCCF2AE037\r
+:1013A0002093C60014BEE0E1F1E007C03091C00018\r
+:1013B00035FFFCCF2093C600319624912111F6CF42\r
+:1013C000E9E1F1E007C03091C00035FFFCCF209388\r
+:1013D000C600319624912111F6CF2091C00025FF3F\r
+:1013E000FCCF2AE02093C600FC012491EBEBF0E057\r
 :1013F00008C03091C00035FFFCCF2093C600319665\r
-:1014000024912223B1F7EFECF3E007C03091C00044\r
-:1014100035FFFCCF2093C600319624912223B1F7EB\r
-:10142000E4ECF3E007C03091C00035FFFCCF20931F\r
-:10143000C600319624912223B1F7E8EBF3E007C010\r
+:1014000024912111F6CFE3E2F1E007C03091C00052\r
+:1014100035FFFCCF2093C600319624912111F6CFE1\r
+:10142000E3E3F1E007C03091C00035FFFCCF20932B\r
+:10143000C600319624912111F6CFEEE3F1E007C00A\r
 :101440003091C00035FFFCCF2093C6003196249127\r
-:101450002223B1F7E3EBF3E007C03091C00035FF82\r
-:10146000FCCF2093C600319624912223B1F720911E\r
+:101450002111F6CFEAE4F1E007C03091C00035FF7A\r
+:10146000FCCF2093C600319624912111F6CF209114\r
 :10147000C00025FFFCCF2AE02093C600FC01849128\r
-:10148000E6E6F1E008C09091C00095FFFCCF8093A4\r
-:10149000C600319684918823B1F7E4EAF3E007C0EF\r
+:10148000EBEBF0E008C09091C00095FFFCCF80939B\r
+:10149000C600319684918111F6CFEFE4F1E007C0E8\r
 :1014A0009091C00095FFFCCF8093C6003196849147\r
-:1014B0008823B1F7B8DEBC018BE095E04AE050E04C\r
-:1014C0000E949C23EDE8F3E007C09091C00095FFD7\r
-:1014D000FCCF8093C600319684918823B1F78BE0CE\r
-:1014E00095E060ED74E04AE050E00E949C2380911A\r
-:1014F000C00085FFFCCF8AE08093C6001092740480\r
-:1015000010927504109276041092770480E092DDB8\r
-:10151000C0E3D5E000E215E03CE5E32E35E0F32E34\r
-:101520006991799189919991F801A190B190C190B7\r
-:10153000D1908F010E94DD4FA60195010E941252A9\r
-:101540000E94B14FF70161937193819391937F0151\r
-:10155000F5E0C034DF0721F70E94BA4B0E94CF2C80\r
-:101560000E94D340DF91CF911F910F91FF90EF9098\r
-:10157000DF90CF90BF90AF90089580916C049091D0\r
-:101580006D04019660E070E00C94615380916C04EE\r
-:1015900090916D04019660E070E04AE050E00C9498\r
-:1015A000CE54682FE091EA02F091EB0240E650E061\r
-:1015B000E49F9001E59F300DF49F300D1124C90187\r
-:1015C00084519D4F70E00E9418569C0190936D04C9\r
-:1015D00080936C0481E02115310509F480E00895C1\r
-:1015E0000E94E2206093B4027093B5028093B60229\r
-:1015F0009093B702EBE5F1E007C09091C00095FF32\r
-:10160000FCCF8093C600319684918823B1F78091F6\r
-:10161000C00085FFFCCF8AE08093C60008958BE070\r
-:1016200095E00E94D222EEE5F1E007C09091C00063\r
-:1016300095FFFCCF8093C600319684918823B1F743\r
-:101640004091AC025091AD026091AE027091AF0238\r
-:101650004F5F5F4F6F4F7F4F8BE095E02AE030E0A8\r
-:101660000E946C238091C00085FFFCCF8AE08093AC\r
-:10167000C600B6CF4F925F926F927F928F929F92E9\r
-:10168000AF92BF92CF92DF92EF92FF920F931F9390\r
-:10169000CF93DF9370E6C72ED12C64E0662E712CB9\r
-:1016A00051E0A52EB12CE0E7F2E084904AE0942EC0\r
-:1016B000E8EEF2E05490442443941CC28D3071F063\r
-:1016C0008A3321F490916F04992341F020917004A2\r
-:1016D000309171042F3531050CF4EEC1E0917004A6\r
-:1016E000F0917104309719F410926F0422C2809126\r
-:1016F0007204909173048C9DE0018D9DD00D9C9D92\r
-:10170000D00D1124EC0FFD1FE451FD4F10822091EC\r
-:101710006F04222309F0CBC110926F048C589B4FA9\r
-:10172000FC0110828E0104511D4FC8016EE470E06F\r
-:101730000E941856009709F412C190936D0480938B\r
-:101740006C049501201B310B280F391F2C0F3D1FF6\r
-:10175000C90184519D4F60E070E04AE050E00E9472\r
-:10176000CE54609378047093790480937A049093B4\r
-:101770007B04E090AC02F090AD020091AE021091BB\r
-:10178000AF02A80197012F5F3F4F4F4F5F4F621786\r
-:1017900073078407950709F43AC0209172043091C9\r
-:1017A00073042C9DC0012D9D900D3C9D900D112426\r
-:1017B00084519D4F68E171E00E942356009739F5EE\r
-:1017C000EBEBF0E007C09091C00095FFFCCF809359\r
-:1017D000C600319684918823B1F7EBE5F3E007C0AA\r
-:1017E0009091C00095FFFCCF8093C6003196849104\r
-:1017F0008823B1F78BE095E0B801A7012AE030E03B\r
-:101800000E946C238091C00085FFFCCF92C0809124\r
-:101810007204909173048C9DE0018D9DD00D9C9D70\r
-:10182000D00D1124CE0184519D4F6AE270E00E94D8\r
-:101830001856009709F457C020E000E002C00327C3\r
-:101840002F5FFE01E20FF11DE451FD4F30813A326E\r
-:10185000B1F790936D0480936C049E0124513D4F29\r
-:10186000A501421B530B9A01280F391F2C0F3D1F56\r
-:10187000C90184519D4F60E070E00E9461530E9455\r
-:10188000AC4F10E00617170709F458C0EBEBF0E077\r
-:1018900007C09091C00095FFFCCF8093C6003196A1\r
-:1018A00084918823B1F7EDE3F3E007C09091C00085\r
-:1018B00095FFFCCF8093C600319684918823B1F7C1\r
-:1018C0004091AC025091AD026091AE027091AF02B6\r
-:1018D0008BE095E02AE030E00E946C238091C0000C\r
-:1018E00085FFFCCF26C0EBEBF0E007C09091C00075\r
-:1018F00095FFFCCF8093C600319684918823B1F781\r
-:10190000E4E1F3E007C09091C00095FFFCCF809325\r
-:10191000C600319684918823B1F78BE095E0B80139\r
-:10192000A7012AE030E00E946C238091C00085FF6F\r
-:10193000FCCF8AE08093C60072DE47C080917804B5\r
-:1019400090917904A0917A04B0917B048093AC02C9\r
-:101950009093AD02A093AE02B093AF023BC0C8011A\r
-:101960006AE270E00E9418560097A1F1EBEBF0E0FC\r
-:1019700007C09091C00095FFFCCF8093C6003196C0\r
-:1019800084918823B1F7EBEEF2E007C09091C0009C\r
-:1019900095FFFCCF8093C600319684918823B1F7E0\r
-:1019A0004091AC025091AD026091AE027091AF02D5\r
-:1019B0008BE095E02AE030E00E946C238091C0002B\r
-:1019C00085FFFCCF8AE08093C600109271041092CC\r
-:1019D0007004AFC080917204909173048C9D80015B\r
-:1019E0008D9D100D9C9D100D1124E801C451DD4FFB\r
-:1019F000CE0167E470E00E941856009709F442C0D7\r
-:101A000090936D0480936C0495012C1B3D0B280F63\r
-:101A1000391F200F311FC90184519D4F60E070E0D4\r
-:101A20000E9461530E94AC4F6430710558F580915B\r
-:101A3000AB02882399F4852DE8EEF2E008C090917E\r
-:101A4000C00095FFFCCF8093C60031968491882317\r
-:101A5000B1F78091C00085FFFCCF12C0882DE0E770\r
-:101A6000F2E008C09091C00095FFFCCF8093C600C3\r
-:101A7000319684918823B1F78091C00085FFFCCF17\r
-:101A80009092C60080917204909173040196B30104\r
-:101A90000E94F752909373048093720480917C04A7\r
-:101AA00090917D04019690937D0480937C04109224\r
-:101AB0007104109270041EC08B3311F440926F04B5\r
-:101AC00090916F049923B1F4409172045091730482\r
-:101AD0004C9DF0014D9DF00D5C9DF00D1124E20F29\r
-:101AE000F31FE451FD4F80832F5F3F4F309371040C\r
-:101AF00020937004809107059091080520910905B5\r
-:101B000030910A05821B930B8F779070009789F0B4\r
-:101B100080917C0490917D048430910554F48BE095\r
-:101B200095E00E94B62280936E048A3009F0C6CDFB\r
-:101B3000D5CDDF91CF911F910F91FF90EF90DF9066\r
-:101B4000CF90BF90AF909F908F907F906F905F905D\r
-:101B50004F9008958F929F92AF92BF92CF92DF9253\r
-:101B6000EF92FF920F931F93CF93DF93F1E1EF2E4C\r
-:101B7000F2E0FF2ECDE8D2E008EC12E0E6E8CE2E4F\r
-:101B8000E2E0DE2EF70181917F010BDD882321F158\r
-:101B9000F4DC4B015C01F6018081882319F460912B\r
-:101BA000D80201C061E070E0882777FD8095982F0A\r
-:101BB0000E94DF4F288139814A815B810E94125245\r
-:101BC0009B01AC01C501B4010E94644EF801608321\r
-:101BD00071838283938309C088819981AA81BB81A3\r
-:101BE000F80180839183A283B38324960C5F1F4FF7\r
-:101BF0000894C11CD11CF5E1EF16F2E0FF0609F0D4\r
-:101C0000C1CF86E4CEDC8823D1F0B7DC7B018C0128\r
-:101C10006093D9027093DA028093DB029093DC0226\r
-:101C200020E030E0A9010E944051181644F4E092EF\r
-:101C3000F201F092F3010093F4011093F501DF91AA\r
-:101C4000CF911F910F91FF90EF90DF90CF90BF90B9\r
-:101C5000AF909F908F9008957DDF89E4A2DC882368\r
-:101C600051F08BDC6093BC027093BD028093BE0286\r
-:101C70009093BF020BC080E090E0DC018093BC0237\r
-:101C80009093BD02A093BE02B093BF028AE489DCA8\r
-:101C9000882351F072DC6093C0027093C10280937C\r
-:101CA000C2029093C302089580E090E0DC0180932B\r
-:101CB000C0029093C102A093C202B093C3020895E0\r
-:101CC000CF92DF92EF92FF920F931F936091C80221\r
-:101CD0007091C9028091CA029091CB0220E030E05D\r
-:101CE000A9010E943D4F87FF0BC080E090E0DC011E\r
-:101CF0008093C8029093C902A093CA02B093CB020A\r
-:101D00006091CC027091CD028091CE029091CF0271\r
-:101D100020E030E0A9010E943D4F87FF0BC080E02A\r
-:101D200090E0DC018093CC029093CD02A093CE0290\r
-:101D3000B093CF026091D0027091D1028091D20213\r
-:101D40009091D30220E030E0A9010E943D4F87FF2F\r
-:101D50000BC080E090E0DC018093D0029093D10230\r
-:101D6000A093D202B093D3026091C8027091C902CD\r
-:101D70008091CA029091CB0220E030E04DE453E420\r
-:101D80000E944051181664F480E090E0ADE4B3E4A2\r
-:101D90008093C8029093C902A093CA02B093CB0269\r
-:101DA0006091CC027091CD028091CE029091CF02D1\r
-:101DB00020E030E04DE453E40E944051181664F4F2\r
-:101DC00080E090E0ADE4B3E48093CC029093CD0248\r
-:101DD000A093CE02B093CF026091D0027091D10255\r
-:101DE0008091D2029091D30220E030E040EF52E4A3\r
-:101DF0000E944051181664F480E090E0A0EFB2E435\r
-:101E00008093D0029093D102A093D202B093D302D8\r
-:101E10000E94E2206093B4027093B5028093B602F0\r
-:101E20009093B7026091EA017091EB01882777FDEA\r
-:101E30008095982F0E94DF4F2091F2013091F3019D\r
-:101E40004091F4015091F5010E94125220E030E0DF\r
-:101E500040E752E40E94444F20E030E048EC52E476\r
-:101E60000E94444F7B018C0188EC92E06CEC72E0A4\r
-:101E700040ED52E024ED32E0A9EACA2EA2E0DA2ECB\r
-:101E80000E945E2D8091C8029091C902A091CA0261\r
-:101E9000B091CB0280938D0290938E02A0938F021B\r
-:101EA000B09390028091CC029091CD02A091CE028D\r
-:101EB000B091CF028093910290939202A0939302EB\r
-:101EC000B09394028091D0029091D102A091D2025D\r
-:101ED000B091D3028093950290939602A0939702BB\r
-:101EE000B09398028091D4029091D502A091D6022D\r
-:101EF000B091D7028093990290939A02A0939B028B\r
-:101F0000B0939C021F910F91FF90EF90DF90CF90C4\r
-:101F100008959F92AF92BF92CF92DF92EF92FF927D\r
-:101F20000F931F93CF93DF93982E6091BC02709113\r
-:101F3000BD028091BE029091BF022091C0023091FB\r
-:101F4000C1024091C2025091C3020E944D517B01D7\r
-:101F50008C016091EA017091EB0100D000D000D0BB\r
-:101F6000CDB7DEB72196882777FD8095982F0E9400\r
-:101F7000DF4F2091F2013091F3014091F401509133\r
-:101F8000F5010E94125220E030E040E752E40E9446\r
-:101F9000444F20E030E048EC52E40E94444F5B01A3\r
-:101FA0006C01E882F9820A831B839C828091A902DA\r
-:101FB0008D838DE892E068EC72E04CEB52E020E01B\r
-:101FC00001E0B2E0EB2E0E9478248091C80290914B\r
-:101FD000C902A091CA02B091CB0280938D02909366\r
-:101FE0008E02A0938F02B09390028091CC029091C8\r
-:101FF000CD02A091CE02B091CF0280939102909336\r
-:102000009202A0939302B09394028091D002909197\r
-:10201000D102A091D202B091D30280939502909305\r
-:102020009602A0939702B09398028091D402909167\r
-:10203000D502A091D602B091D702809399029093D5\r
-:102040009A02A0939B02B0939C028DB79EB706960E\r
-:102050000FB6F8949EBF0FBE8DBF0E94E220609322\r
-:10206000B4027093B5028093B6029093B702DF91E9\r
-:10207000CF911F910F91FF90EF90DF90CF90BF9085\r
-:10208000AF909F900895F8940E94184C5A985A98CF\r
-:102090005A985A98EBEBF0E007C09091C00095FF7A\r
-:1020A000FCCF8093C600319684918823B1F7EAE390\r
-:1020B000F1E007C09091C00095FFFCCF8093C6006F\r
-:1020C000319684918823B1F78091C00085FFFCCFC1\r
-:1020D0008AE08093C600FFCFEF92FF920F931F9389\r
-:1020E0000E94E2202091B8023091B9024091BA02D8\r
-:1020F0005091BB02E090B402F090B5020091B6029C\r
-:102100001091B7026E197F09800B910B26173707C4\r
-:102110004807590730F4211531054105510509F0EB\r
-:10212000B2DF8091EE019091EF01A091F001B091AA\r
-:10213000F1010097A105B10529F10E94E22020914B\r
-:10214000B4023091B5024091B6025091B702621BC1\r
-:10215000730B840B950B2091EE013091EF014091B0\r
-:10216000F0015091F101261737074807590750F43D\r
-:1021700090914C0A80914D0A981721F45A985A98D8\r
-:102180005A985A980E94062D1EBA1F910F91FF90DF\r
-:10219000EF9008952F923F924F925F926F927F92AD\r
-:1021A0008F929F92AF92BF92CF92DF92EF92FF9267\r
-:1021B0000F931F93DF93CF93CDB7DEB7A2970FB6E0\r
-:1021C000F894DEBF0FBECDBF87E4EBD9882309F4B6\r
-:1021D000A3C5D3D90E94AC4F6430710509F43CC04B\r
-:1021E0006530710554F46230710531F16330710569\r
-:1021F00054F577FF19C00C94F41F6A35710509F482\r
-:1022000027C56B35710534F46C31710511F00C94F0\r
-:10221000F41F64C06B35710509F41EC56C3571057A\r
-:1022200011F00C94F41F1DC58091AB02882321F49A\r
-:1022300091DC46DD0C9413208091AB02882319F4C5\r
-:102240000BDD81E006C08091AB02882329F404DD18\r
-:1022500080E05FDE0C94132080E5A3D9882341F051\r
-:102260008CD90E94B14FE62EF72E082F192F03C0EC\r
-:10227000EE24FF24870183E594D9882369F07DD972\r
-:1022800020E030E04AE754E40E9412520E94B14F2D\r
-:10229000E62EF72E082F192F0E9412410E94E220ED\r
-:1022A0005B016C01AE0CBF1CC01ED11E0E94E2205F\r
-:1022B0006093B4027093B5028093B6029093B70214\r
-:1022C00004C00E94AB4381E007DF0E94E2206A1550\r
-:1022D0007B058C059D05A8F30C94F41F8091F201F9\r
-:1022E0009091F301A091F401B091F5018093DD028A\r
-:1022F0009093DE02A093DF02B093E0028091EA01A6\r
-:102300009091EB0190938B0280938A0284E690E097\r
-:102310009093EB018093EA010E94E2206093B40263\r
-:102320007093B5028093B6029093B70281E00E9449\r
-:10233000D43A80918D0290918E02A0918F02B0913B\r
-:1023400090028093C8029093C902A093CA02B093EE\r
-:10235000CB028091910290919202A0919302B09150\r
-:1023600094028093CC029093CD02A093CE02B093BE\r
-:10237000CF028091950290919602A0919702B09120\r
-:1023800098028093D0029093D102A093D202B0938E\r
-:10239000D3028091990290919A02A0919B02B091F0\r
-:1023A0009C028093D4029093D502A093D602B0935E\r
-:1023B000D70280E090E0DC018093F2019093F3017A\r
-:1023C000A093F401B093F50188E5EBD8882351F48C\r
-:1023D00089E5E7D8882331F48AE5E3D8882311F426\r
-:1023E00081E001C080E08093F60188E5DAD8882397\r
-:1023F00009F4E6C089E5D5D8882309F4E1C080E076\r
-:1024000090E0DC0180938D0290938E02A0938F0266\r
-:10241000B09390028093910290939202A0939302C2\r
-:10242000B09394028DE892E061E972E045E952E0F0\r
-:1024300029E932E00E94453980E090ECA9E9B3EC4B\r
-:102440008093C8029093C902A093CA02B093CB02B2\r
-:102450008093CC029093CD02A093CE02B093CF0292\r
-:102460002091DA013091DB014091DC015091DD01D6\r
-:102470002093F2013093F3014093F4015093F5015E\r
-:10248000E090DE01F090DF010091E0011091E101A8\r
-:10249000C801B7010E943D4F87FF08C0E092F201DA\r
-:1024A000F092F3010093F4011093F5016091F201B1\r
-:1024B0007091F3018091F4019091F50120E030E0FA\r
-:1024C00040E752E40E94444F7B018C0188EC92E08B\r
-:1024D0006CEC72E040ED52E024ED32E0B9EACB2E34\r
-:1024E000B2E0DB2E0E945E2D0E9412410F2EF0E022\r
-:1024F0008F2EF0E09F2EF0E0AF2EF0E0BF2EF02DFB\r
-:1025000080928D0290928E02A0928F02B0929002E1\r
-:102510008092910290929202A0929302B0929402C1\r
-:102520008DE892E061E972E045E952E029E932E0A4\r
-:102530000E94453980918D0290918E02A0918F0268\r
-:10254000B09190028093C8029093C902A093CA02EE\r
-:10255000B093CB028091910290919202A09193024C\r
-:10256000B09194028093CC029093CD02A093CE02BE\r
-:10257000B093CF026091F2017091F3018091F40168\r
-:102580009091F50120E030E040E752E40E94444F92\r
-:102590007B018C0188EC92E06CEC72E040ED52E043\r
-:1025A00024ED32E00E945E2D8092F2019092F301C0\r
-:1025B000A092F401B092F5010E9412410E94CD3A1E\r
-:1025C0008091F601882331F488E50E94D10A88239E\r
-:1025D00009F4DEC00F2EF0E08F2EF0E09F2EF0E029\r
-:1025E000AF2EF0E0BF2EF02D80928D0290928E02E1\r
-:1025F000A0928F02B09290028DE892E061E972E0C1\r
-:1026000045E952E029E932E00E94453980E090EC4A\r
-:10261000A9E9B3EC8093C8029093C902A093CA02BF\r
-:10262000B093CB026091DA017091DB018091DC0103\r
-:102630009091DD016093F2017093F3018093F401B6\r
-:102640009093F50120E030E040E752E40E94444FCF\r
-:102650007B018C0188EC92E06CEC72E040ED52E082\r
-:1026600024ED32E0A9EACA2EA2E0DA2E0E945E2D05\r
-:102670000E94124180928D0290928E02A0928F024F\r
-:10268000B09290028DE892E061E972E045E952E093\r
-:1026900029E932E00E94453980E090E0A0EAB0E408\r
-:1026A0008093C8029093C902A093CA02B093CB0250\r
-:1026B0006091F2017091F3018091F4019091F50124\r
-:1026C00020E030E040E752E40E94444F7B018C015F\r
-:1026D00088EC92E06CEC72E040ED52E024ED32E0E8\r
-:1026E0000E945E2D0E94124180E090E0A0E2B1ECD9\r
-:1026F0008093C8029093C902A093CA02B093CB0200\r
-:102700006091DA017091DB018091DC019091DD0133\r
-:1027100020E030E040E05FE30E941252262F372F86\r
-:10272000482F592F2093F2013093F3014093F40185\r
-:102730005093F50120E030E040E752E40E94444F1E\r
-:102740007B018C0188EC92E06CEC72E040ED52E091\r
-:1027500024ED32E00E945E2D0E94124180928D0293\r
-:1027600090928E02A0928F02B09290028092C80244\r
-:102770009092C902A092CA02B092CB028092F2015A\r
-:102780009092F301A092F401B092F5010E94CD3A2B\r
-:102790008091F601882331F489E50E94D10A8823CB\r
-:1027A00009F4DEC00F2EF0E08F2EF0E09F2EF0E057\r
-:1027B000AF2EF0E0BF2EF02D809291029092920207\r
-:1027C000A0929302B09294028DE892E061E972E0E7\r
-:1027D00045E952E029E932E00E94453980E090EC79\r
-:1027E000A9E9B3EC8093CC029093CD02A093CE02E2\r
-:1027F000B093CF026091DE017091DF018091E00122\r
-:102800009091E1016093F2017093F3018093F401E0\r
-:102810009093F50120E030E040E752E40E94444FFD\r
-:102820007B018C0188EC92E06CEC72E040ED52E0B0\r
-:1028300024ED32E0F9EACF2EF2E0DF2E0E945E2D89\r
-:102840000E9412418092910290929202A092930271\r
-:10285000B09294028DE892E061E972E045E952E0BD\r
-:1028600029E932E00E94453980E090E0A0EAB0E436\r
-:102870008093CC029093CD02A093CE02B093CF026E\r
-:102880006091F2017091F3018091F4019091F50152\r
-:1028900020E030E040E752E40E94444F7B018C018D\r
-:1028A00088EC92E06CEC72E040ED52E024ED32E016\r
-:1028B0000E945E2D0E94124180E090E0A0E2B1EC07\r
-:1028C0008093CC029093CD02A093CE02B093CF021E\r
-:1028D0006091DE017091DF018091E0019091E10152\r
-:1028E00020E030E040E05FE30E941252262F372FB5\r
-:1028F000482F592F2093F2013093F3014093F401B4\r
-:102900005093F50120E030E040E752E40E94444F4C\r
-:102910007B018C0188EC92E06CEC72E040ED52E0BF\r
-:1029200024ED32E00E945E2D0E94124180929102BD\r
-:1029300090929202A0929302B09294028092CC0262\r
-:102940009092CD02A092CE02B092CF028092F2017C\r
-:102950009092F301A092F401B092F5010E94CD3A59\r
-:102960008091F601882331F48AE50E94D10A8823F8\r
-:1029700009F4DEC00F2EF0E08F2EF0E09F2EF0E085\r
-:10298000AF2EF0E0BF2EF02D80929502909296022D\r
-:10299000A0929702B09298028DE892E061E972E00D\r
-:1029A00045E952E029E932E00E94453980E090E0B3\r
-:1029B000A4E3B3EC8093D0029093D102A093D2020F\r
-:1029C000B093D3026091E2017091E3018091E40140\r
-:1029D0009091E5016093F2017093F3018093F4010B\r
-:1029E0009093F50120E030E040E752E40E94444F2C\r
-:1029F0007B018C0188EC92E06CEC72E040ED52E0DF\r
-:102A000024ED32E0E9EACE2EE2E0DE2E0E945E2DD9\r
-:102A10000E9412418092950290929602A092970293\r
-:102A2000B09298028DE892E061E972E045E952E0E7\r
-:102A300029E932E00E94453980E090E0A0E8BFE358\r
-:102A40008093D0029093D102A093D202B093D3028C\r
-:102A50006091F2017091F3018091F4019091F50180\r
-:102A600020E030E040E752E40E94444F7B018C01BB\r
-:102A700088EC92E06CEC72E040ED52E024ED32E044\r
-:102A80000E945E2D0E94124180E090E0A0E0B0EC38\r
-:102A90008093D0029093D102A093D202B093D3023C\r
-:102AA0006091E2017091E3018091E4019091E50170\r
-:102AB00020E030E040E05FE30E941252262F372FE3\r
-:102AC000482F592F2093F2013093F3014093F401E2\r
-:102AD0005093F50120E030E040E752E40E94444F7B\r
-:102AE0007B018C0188EC92E06CEC72E040ED52E0EE\r
-:102AF00024ED32E00E945E2D0E94124180929502E8\r
-:102B000090929602A0929702B09298028092D00280\r
-:102B10009092D102A092D202B092D3028092F2019E\r
-:102B20009092F301A092F401B092F5010E94CD3A87\r
-:102B300088E50E94D10A8823D9F00E94C60A61154F\r
-:102B4000710581059105A1F00E94BD0A20919D02A9\r
-:102B500030919E0240919F025091A0020E94644ECB\r
-:102B600060938D0270938E0280938F0290939002F7\r
-:102B700089E50E94D10A8823D9F00E94C60A61150E\r
-:102B8000710581059105A1F00E94BD0A2091A10265\r
-:102B90003091A2024091A3025091A4020E94644E7F\r
-:102BA00060939102709392028093930290939402A7\r
-:102BB0008AE50E94D10A8823D9F00E94C60A6115CD\r
-:102BC000710581059105A1F00E94BD0A2091A50221\r
-:102BD0003091A6024091A7025091A8020E94644E33\r
-:102BE0006093950270939602809397029093980257\r
-:102BF0008DE892E061E972E045E952E029E932E0CE\r
-:102C00000E9445398091DD029091DE02A091DF02A1\r
-:102C1000B091E0028093F2019093F301A093F4014C\r
-:102C2000B093F50180918A0290918B029093EB0111\r
-:102C30008093EA010E94E2206093B4027093B5028F\r
-:102C40008093B6029093B7020E94CD3A0C94F41F81\r
-:102C50001092D8020C94F41F81E08093D8020C9457\r
-:102C6000F41F85E40E94D10A882311F40E941241C6\r
-:102C700041E1842E42E0942E3DE9E32E32E0F32E32\r
-:102C80000DE812E0AA24F40181914F010E94D10ABB\r
-:102C90008823A9F10E94BD0AF70120813181428178\r
-:102CA00053810E94644EF801608371838283938311\r
-:102CB000FA2DF33061F40E94BD0AF801608371833C\r
-:102CC0008283938389E992E00E94F23918C00E94BE\r
-:102CD000BD0AF70120813181428153810E94644EF7\r
-:102CE000F80160837183828393838DE892E061E9C8\r
-:102CF00072E045E952E029E932E00E944539A394A7\r
-:102D000024E030E0E20EF31E0C5F1F4F3A2D34300A\r
-:102D100009F0B9CF0C94F41F8DE40E94D10A8823E6\r
-:102D200011F40C944A1F0E94BD0A0E94AC4F6737F1\r
-:102D3000710509F434C6683771050CF056C0653565\r
-:102D4000710509F412C5663571051CF56A32710505\r
-:102D500009F41BC16B32710574F46231710509F419\r
-:102D6000C0C46F31710509F4A5C06131710511F05E\r
-:102D70000C94F41F99C06335710509F4AEC4643531\r
-:102D800071050CF0AEC46235710511F00C94F41F9E\r
-:102D9000A1C46A36710509F473C46B36710574F405\r
-:102DA0006836710509F434C1693671050CF0A1C1AA\r
-:102DB0006C35710511F00C94F41FEDC46D3671057E\r
-:102DC00009F429C26E36710534F46B36710511F0C1\r
-:102DD0000C94F41F7CC46237710509F407C563378E\r
-:102DE000710511F00C94F41FF3C46C3D710509F4E6\r
-:102DF00028C76D3D71051CF56B3C710509F469C66A\r
-:102E00006C3C710574F46E3B710509F49BC3693C1D\r
-:102E1000710509F424C66C38710511F00C94F41F87\r
-:102E200055C16D3C710509F491C66D3C71050CF4FA\r
-:102E30006DC66E3C710511F00C94F41FE5C681E07F\r
-:102E40006F32780709F4F9C791E06033790784F4A9\r
-:102E5000E1E06D327E0709F415C7F1E06E327F07BD\r
-:102E60000CF0E7C76D3D710511F00C94F41FFBC623\r
-:102E700021E0653F720709F4F2C731E0663F73074E\r
-:102E80003CF481E06039780711F00C94F41FE4C73A\r
-:102E900091E0663F790709F4E4C7E3E0673E7E0707\r
-:102EA00011F00C94F41FE1C75A9A5A9A5A9A5A9AF6\r
-:102EB0000C94F41F0E94E2206093E1027093E202FE\r
-:102EC0008093E3029093E4022091E5023091E602C0\r
-:102ED0004091E7025091E802621B730B840B950B43\r
-:102EE00028EE33E040E050E00E940A538DB79EB7D1\r
-:102EF00008970FB6F8949EBF0FBE8DBF0DB71EB7D3\r
-:102F00000F5F1F4FCE010196EDB7FEB7928381830D\r
-:102F100083E291E0F80193838283CA01B9012CE333\r
-:102F200030E040E050E00E940A53F80135832483EA\r
-:102F3000778366830E943D56E6E6F1E084912DB7E3\r
-:102F40003EB7285F3F4F0FB6F8943EBF0FBE2DBF70\r
-:102F500008C09091C00095FFFCCF8093C6003196C9\r
-:102F600084918823B1F7FE01319606C09091C0008C\r
-:102F700095FFFCCF8093C60081918823B9F780919B\r
-:102F8000C00085FFFCCF0C94F11F83E50E94D10A9D\r
-:102F9000882311F40C94F41F0E94BD0A7B018C015C\r
-:102FA00080E50E94D10A882311F40C94F41FC80113\r
-:102FB000B7010E94AC4F8B0177FF02C00C94F41F45\r
-:102FC0006F3F710519F014F00C94F41F0E94BD0AB4\r
-:102FD0000E94AC4F7B01E5E1F2E0819191918E1569\r
-:102FE0009F0511F40C94F41F32E0E938F307A9F7B8\r
-:102FF000F7FE01C0F9C78E2D61E00E9403228E2DDD\r
-:10300000602F0E9424228E2DB8010E947821ECC7E7\r
-:103010008091A9028093E90284E50E94D10A882365\r
-:1030200061F10E94BD0A0E94B14F6093E9026623DC\r
-:1030300021F1E6E6F1E007C09091C00095FFFCCFDA\r
-:103040008093C600319684918823B1F7E2E3F1E0E2\r
-:1030500006C09091C00095FFFCCF8093C60081917F\r
-:103060008823B9F78BE095E040E050E00E946623AA\r
-:103070008091C00085FFFCCFB4C783E50E94D10AD0\r
-:10308000882309F10E94BD0A7B018C01D090E902DE\r
-:10309000AD2CBB240E94AC4FDC01CB016D2D0E94F6\r
-:1030A000A041F501EE0FFF1FE755F54F9183808397\r
-:1030B000F501EE0FFF1FEE0FFF1FEF54F54FE082FB\r
-:1030C000F182028313830E94174C8EC783E50E940E\r
-:1030D000D10A882309F488C70E94BD0A0E94AC4F18\r
-:1030E000DC01CB010E9456429093AC0A8093AB0A5C\r
-:1030F0007BC78091A9028093E90284E50E94D10AEE\r
-:10310000882361F10E94BD0A0E94B14F6093E902D9\r
-:10311000662321F1E6E6F1E007C09091C00095FF3B\r
-:10312000FCCF8093C600319684918823B1F7E9E4FF\r
-:10313000F1E006C09091C00095FFFCCF8093C600DF\r
-:1031400081918823B9F78BE095E040E050E00E9440\r
-:1031500066238091C00085FFFCCF43C7EAE6F2E01A\r
-:1031600007C09091C00095FFFCCF8093C6003196B8\r
-:1031700084918823B1F76091E902E62FF0E0EE0F29\r
-:10318000FF1FE355F54F808191810E94A642AB015C\r
-:10319000BC018BE095E022E030E00E947524E6E679\r
-:1031A000F2E007C09091C00095FFFCCF8093C6006D\r
-:1031B000319684918823B1F78091AF0A9091B00A3B\r
-:1031C0000E94204BAB01BC018BE095E022E030E097\r
-:1031D0000E947524E2E6F2E007C09091C00095FFDE\r
-:1031E000FCCF8093C600319684918823B1F78091FB\r
-:1031F000E90290E00E949A41BC018BE095E04AE030\r
-:1032000050E00E949C238091C00085FFFCCF8AE0A3\r
-:103210008093C60008C78091A9028093E90284E5E3\r
-:103220000E94D10A882361F10E94BD0A0E94B14F19\r
-:103230006093E902662321F1E6E6F1E007C0909190\r
-:10324000C00095FFFCCF8093C600319684918823FF\r
-:10325000B1F7E0E6F1E006C09091C00095FFFCCF29\r
-:103260008093C60081918823B9F78BE095E040E018\r
-:1032700050E00E9466238091C00085FFFCCFB1C65C\r
-:1032800083E50E94D10A882309F10E94BD0A7B01CF\r
-:103290008C01D090E902AD2CBB240E94AC4FDC0124\r
-:1032A000CB016D2D0E94A041F501EE0FFF1FE755E8\r
-:1032B000F54F91838083F501EE0FFF1FEE0FFF1F87\r
-:1032C000EF54F54FE082F182028313830E94174C82\r
-:1032D00079D75B016C018091E90290E0880F991F1A\r
-:1032E000FC01E755F54F208031808355954FFC0157\r
-:1032F0000190F081E02DF8A3EF8FEE24EA94FE2CEC\r
-:103300008701EFE5F2E0249129A3EBE5F2E0449098\r
-:10331000E7E5F2E034913AA35AE0552E04C189A1C1\r
-:10332000EFE5F2E008C09091C00095FFFCCF8093DC\r
-:10333000C600319684918823B1F76091E902E62FA7\r
-:10334000F0E0EE0FFF1FE355F54F808191810E9461\r
-:10335000A642AB01BC018BE095E022E030E00E9488\r
-:103360007524842DEBE5F2E008C09091C00095FF34\r
-:10337000FCCF8093C600319684918823B1F7609189\r
-:10338000E9028BE095E070E04AE050E00E949C2367\r
-:103390008AA1E7E5F2E008C09091C00095FFFCCF5C\r
-:1033A0008093C600319684918823B1F717FF03C03C\r
-:1033B000E7E7F1E026C006D79B01AC01C801B701E1\r
-:1033C000605F784D8F4F9F4F621B730B840B950B83\r
-:1033D00028EE33E040E050E00E940A538BE095E095\r
-:1033E000BA01A9012AE030E00E9456238091C00072\r
-:1033F00085FFFCCF0DC09091C00095FFFCCF80935E\r
-:10340000C60081918823B9F78091C00085FFFCCF69\r
-:103410005092C600D7D65B016C010E94AB4381E09D\r
-:103420000E946C108FEFE8168FEFF8068FEF0807F9\r
-:103430008FEF180751F58091E902EF8DF8A1E215A1\r
-:10344000F30594F490E0880F991FFC01E755F54FC0\r
-:103450008355954F20813181FC01808191818217B4\r
-:1034600093070CF048C04CC090E0880F991FFC01F6\r
-:10347000E755F54F8355954F20813181FC018081BF\r
-:10348000918128173907BCF53BC017FD39C0609101\r
-:10349000E902E62FF0E0EE0FFF1FE355F54F8081C4\r
-:1034A00091810E94A6423B014C016091E902E62F06\r
-:1034B000F0E0EE0FFF1FE755F54F808191810E94EC\r
-:1034C000A6429B01AC01C401B3010E94634E0E945D\r
-:1034D000AC4F262F372F482F592F57FF07C0509535\r
-:1034E0004095309521953F4F4F4F5F4F2430310528\r
-:1034F000410551052CF066D6E62EF72E082F192F20\r
-:10350000FFEFEF16FFEFFF06FFEF0F07FFEF1F07BD\r
-:1035100051F017FD6CC556D66E197F0927E2603150\r
-:10352000720708F064C54ED66A197B098C099D099B\r
-:10353000693E33E0730730E0830730E0930708F01B\r
-:10354000EECE6BCF83E50E94D10A882361F00E9402\r
-:10355000BD0A0E94AC4FDC01CB010E945642909301\r
-:10356000AC0A8093AB0A2ED67B018C01E4E5F2E035\r
-:10357000A490E0E5F2E08490ECE4F2E0D490EAE09C\r
-:103580006E2E71C01FD66E197F09800B910B693E9C\r
-:10359000E3E07E07E0E08E07E0E09E0708F45EC00F\r
-:1035A0006091A902E62FF0E0EE0FFF1FE355F54F03\r
-:1035B000808191810E94A642AB01BC018A2DE4E585\r
-:1035C000F2E008C09091C00095FFFCCF8093C60048\r
-:1035D000319684918823B1F78BE095E022E030E0CA\r
-:1035E0000E947524882DE0E5F2E008C09091C000AB\r
-:1035F00095FFFCCF8093C600319684918823B1F764\r
-:103600006091A9028BE095E070E04AE050E00E94F2\r
-:103610009C238D2DECE4F2E008C09091C00095FF52\r
-:10362000FCCF8093C600319684918823B1F78091B6\r
-:10363000AF0A9091B00A0E94204BAB01BC018BE015\r
-:1036400095E022E030E00E9475248091C00085FF63\r
-:10365000FCCF6092C600B6D57B018C010E94AB43C3\r
-:1036600081E00E946C102091AB0A3091AC0A8091ED\r
-:10367000AF0A9091B00A821793070CF483CFC0C4AD\r
-:1036800083E50E94D10A8823F1F00E94BD0A20E060\r
-:1036900030E0A9010E943D4F87FD0FC00E94BD0A86\r
-:1036A00020E030E04FE753E40E94405118163CF010\r
-:1036B0000E94BD0A0E94B14F03C060E001C06FEFDD\r
-:1036C0006093AA0291C48FEF8093AA028DC41092D6\r
-:1036D000AA028AC41092890287C481E08093890279\r
-:1036E00083C483E50E94D10A882399F00E94BD0A11\r
-:1036F00020E030E04AE754E40E9412520E94B14FA9\r
-:103700006093EE017093EF018093F0019093F101CB\r
-:103710006BC488E50E94D10A882309F07BC489E53F\r
-:103720000E94D10A882309F075C48AE50E94D10A53\r
-:10373000882309F06FC485E40E94D10A882309F028\r
-:1037400069C40E9412415A980E947D414DC45A9802\r
-:1037500089E50E94D10A81115A988AE50E94D10A0E\r
-:10376000882309F441C45A983FC483E50E94D10AD2\r
-:103770000E94BD0A20E030E04AE754E40E94125261\r
-:103780000E94B14F6093B8027093B9028093BA025D\r
-:103790009093BB0229C401E112E050E2E52E55E00E\r
-:1037A000F52EF80181918F010E94D10A882339F00A\r
-:1037B0000E94BD0AF701608371838283938324E0B2\r
-:1037C00030E0E20EF31E32E00531130751F70CC46E\r
-:1037D000E1EBF1E007C09091C00095FFFCCF809332\r
-:1037E000C600319684918823B1F7FEC3EEEAF1E07A\r
-:1037F00007C09091C00095FFFCCF8093C600319622\r
-:1038000084918823B1F740918D0250918E0260918E\r
-:103810008F02709190028BE095E022E030E00E94F0\r
-:103820007524EBEAF1E007C09091C00095FFFCCF52\r
-:103830008093C600319684918823B1F7409191021C\r
-:103840005091920260919302709194028BE095E006\r
-:1038500022E030E00E947524E8EAF1E007C0909190\r
-:10386000C00095FFFCCF8093C600319684918823D9\r
-:10387000B1F7409195025091960260919702709134\r
-:1038800098028BE095E022E030E00E947524E5EAA2\r
-:10389000F1E007C09091C00095FFFCCF8093C60077\r
-:1038A000319684918823B1F74091990250919A0200\r
-:1038B00060919B0270919C028BE095E022E030E0E9\r
-:1038C0000E947524EBE9F1E007C09091C00095FFDC\r
-:1038D000FCCF8093C600319684918823B1F70E9473\r
-:1038E0006B410E94DF4F20912005309121054091CE\r
-:1038F0002205509123050E94444FAB01BC018BE08F\r
-:1039000095E022E030E0F1D7E8E9F1E007C09091DE\r
-:10391000C00095FFFCCF8093C60031968491882328\r
-:10392000B1F781E00E946B410E94DF4F2091240596\r
-:103930003091250540912605509127050E94444F5E\r
-:10394000AB01BC018BE095E022E030E0CED7E5E9A9\r
-:10395000F1E007C09091C00095FFFCCF8093C600B6\r
-:10396000319684918823B1F782E00E946B410E94D6\r
-:10397000DF4F209128053091290540912A0550916B\r
-:103980002B050E94444FAB01BC018BE095E022E087\r
-:1039900030E0ABD78091C00085FFFCCF22C3EEE8BA\r
-:1039A000F1E007C09091C00095FFFCCF8093C60066\r
-:1039B000319684918823B1F783B180FD03C0EDE196\r
-:1039C000F1E009C0E0E2F1E006C09091C00095FF8F\r
-:1039D000FCCF8093C60081918823B9F7E7E8F1E036\r
-:1039E00007C09091C00095FFFCCF8093C600319630\r
-:1039F00084918823B1F7199903C0EDE1F1E009C082\r
-:103A0000E0E2F1E006C09091C00095FFFCCF80930A\r
-:103A1000C60081918823B9F7E0E8F1E007C09091F2\r
-:103A2000C00095FFFCCF8093C60031968491882317\r
-:103A3000B1F71A9903C0EDE1F1E009C0E0E2F1E06D\r
-:103A400006C09091C00095FFFCCF8093C600819185\r
-:103A50008823B9F78091C00085FFFCCFC2C241E145\r
-:103A6000E42E42E0F42E00E010E0F70181917F01A6\r
-:103A70000E94D10A882339F10E94BD0A30E3A32EA7\r
-:103A800035E0B32EA00EB11E0E94B14FF501608348\r
-:103A90007183828393830E94BD0A2CE5A22E25E0C8\r
-:103AA000B22EA00EB11EF801E05EFA4F20813181E6\r
-:103AB000428153810E9412520E94B14FF5016083EE\r
-:103AC0007183828393830C5F1F4F0031110569F668\r
-:103AD0008BC201E112E090E1E92E95E0F92EF801A8\r
-:103AE00081918F010E94D10A882339F00E94BD0A7A\r
-:103AF000F701608371838283938324E030E0E20ED8\r
-:103B0000F31E32E00531130751F76EC283E50E94C0\r
-:103B1000D10A882351F00E94BD0A60934405709336\r
-:103B20004505809346059093470584E50E94D10A98\r
-:103B3000882309F459C20E94BD0A60934805709316\r
-:103B4000490580934A0590934B054EC283E50E9438\r
-:103B5000D10A882351F00E94BD0A609340057093FA\r
-:103B60004105809342059093430584E50E94D10A64\r
-:103B7000882351F00E94BD0A60935805709359053F\r
-:103B800080935A0590935B0582E40E94D10A8823B2\r
-:103B900061F00E94BD0A0E94B14F60930C057093C2\r
-:103BA0000D0580930E0590930F0588E50E94D10ABC\r
-:103BB000882351F00E94BD0A60934C0570934D0517\r
-:103BC00080934E0590934F058AE50E94D10A882381\r
-:103BD00051F00E94BD0A6093500570935105809387\r
-:103BE00052059093530585E40E94D10A882309F475\r
-:103BF000FBC10E94BD0A60935405709355058093E4\r
-:103C0000560590935705F0C101E112E08DE9E82EC9\r
-:103C100082E0F82EF80181918F010E94D10A882359\r
-:103C200039F00E94BD0AF701608371838283938318\r
-:103C300024E030E0E20EF31E32E00431130751F7C6\r
-:103C4000D3C183E50E94D10A882309F4CDC10E9423\r
-:103C5000BD0A0E94AC4F7093EB016093EA0181E0D2\r
-:103C600080938C02C1C183E50E94D10A882309F4A4\r
-:103C7000BBC10E94BD0A0E94AC4F7093ED016093DE\r
-:103C8000EC01B2C180E50E94D10A882351F00E9464\r
-:103C9000BD0A6093FC017093FD018093FE01909337\r
-:103CA000FF0189E40E94D10A882381F00E94BD0AA5\r
-:103CB00025E93FEB46ED5DE30E941252609300025E\r
-:103CC00070930102809302029093030284E40E94A5\r
-:103CD000D10A882381F00E94BD0A25E93FEB46ED19\r
-:103CE0005DE30E94444F6093040270930502809349\r
-:103CF00006029093070283E40E94D10A882351F0C0\r
-:103D00000E94BD0A609308027093090280930A0220\r
-:103D100090930B020E948341E9E7F1E006C0909185\r
-:103D2000C00095FFFCCF8093C60081918823B9F72E\r
-:103D3000ECE7F1E006C09091C00095FFFCCF8093C6\r
-:103D4000C60081918823B9F74091FC015091FD0193\r
-:103D50006091FE017091FF018BE095E022E030E080\r
-:103D6000C4D5E0E8F1E006C09091C00095FFFCCF1B\r
-:103D70008093C60081918823B9F760910002709109\r
-:103D80000102809102029091030225E93FEB46ED8A\r
-:103D90005DE30E94444FAB01BC018BE095E022E063\r
-:103DA00030E0A3D5E4E8F1E006C09091C00095FFB3\r
-:103DB000FCCF8093C60081918823B9F760910402FB\r
-:103DC00070910502809106029091070225E93FEB70\r
-:103DD00046ED5DE30E941252AB01BC018BE095E021\r
-:103DE00022E030E082D5E8E8F1E006C09091C00022\r
-:103DF00095FFFCCF8093C60081918823B9F760912D\r
-:103E000008027091090280910A0290910B0225E943\r
-:103E10003FEB46ED5DE30E941252AB01BC018BE02B\r
-:103E200095E022E030E061D58091C00085FFFCCFB5\r
-:103E3000D8C081E00E940E3AD7C083E50E94D10A23\r
-:103E4000882319F00E94BD0A04C060E070E086E19A\r
-:103E500093E40E949845C8C00E941241C5C080E00A\r
-:103E600001C081E00E941A08BFC01092AB0280918D\r
-:103E7000B0029091B102A091B202B091B3028093CE\r
-:103E8000AC029093AD02A093AE02B093AF020E9439\r
-:103E90000F0BAAC084E50E94D10A882309F45DC0F3\r
-:103EA0000E94BD0A0E94B14F6093E902E6E6F1E08C\r
-:103EB000662369F107C09091C00095FFFCCF809305\r
-:103EC000C600319684918823B1F7ECE8F1E006C092\r
-:103ED0009091C00095FFFCCF8093C600819188230C\r
-:103EE000B9F78BE095E040E050E0F0D3EEE8F1E088\r
-:103EF00006C09091C00095FFFCCF8093C6008191D1\r
-:103F00008823B9F78091C00085FFFCCF6AC010926A\r
-:103F1000A90207C09091C00095FFFCCF8093C60016\r
-:103F2000319684918823B1F7EFE9F1E006C09091D2\r
-:103F3000C00095FFFCCF8093C60081918823B9F71C\r
-:103F40006091A9028BE095E070E04AE050E0F4D384\r
-:103F50008091C00085FFFCCF44C0E6E6F1E007C0D9\r
-:103F60009091C00095FFFCCF8093C600319684915C\r
-:103F70008823B1F7EEE6F1E007C09091C00095FF0D\r
-:103F8000FCCF8093C600319684918823B1F72091AD\r
-:103F9000EA023091EB0280E690E0289FF001299F31\r
-:103FA000F00D389FF00D1124E451FD4F06C09091A3\r
-:103FB000C00095FFFCCF8093C60081918823B9F79C\r
-:103FC000ECE6F1E007C09091C00095FFFCCF809334\r
-:103FD000C600319684918823B1F78091C00085FF97\r
-:103FE000FCCF8AE08093C6000E94F00A1CC0EAD091\r
-:103FF0006093E5027093E6028093E7029093E802F3\r
-:10400000E1D06093B4027093B5028093B6029093AE\r
-:10401000B702EACF0E94124188E50E94D10A8823A4\r
-:1040200009F095CB95CBA2960FB6F894DEBF0FBEE4\r
-:10403000CDBFCF91DF911F910F91FF90EF90DF9057\r
-:10404000CF90BF90AF909F908F907F906F905F9038\r
-:104050004F903F902F90089580917C0490917D0423\r
-:104060008330910514F40E943A0B80917C04909166\r
-:104070007D040097C1F00E94CA1080917C04909149\r
-:104080007D04019790937D0480937C048091EA02E3\r
-:104090009091EB02019664E070E00E94F7529093D9\r
-:1040A000EB028093EA020E94AB4381E00E946C1015\r
-:1040B0000C94113A0E94184C8091AB028823A1F510\r
-:1040C00081E08093AB028091AC029091AD02A0910F\r
-:1040D000AE02B091AF028093B0029093B102A09370\r
-:1040E000B202B093B302EBEBF0E007C09091C000D6\r
-:1040F00095FFFCCF8093C600319684918823B1F759\r
-:10410000E2ECF0E007C09091C00095FFFCCF8093F7\r
-:10411000C600319684918823B1F78091C00085FF55\r
-:10412000FCCF8AE08093C60008958091AB02089589\r
-:10413000A4D00E942F0990DFFECF1F920F920FB6DE\r
-:104140000F9211242F933F938F939F93AF93BF931D\r
-:104150008091820490918304A0918404B09185049D\r
-:1041600030918604232F2A592D3720F02D570196A0\r
-:10417000A11DB11D20938604809382049093830433\r
-:10418000A0938404B093850480917E0490917F0471\r
-:10419000A0918004B09181040196A11DB11D80936E\r
-:1041A0007E0490937F04A0938004B0938104BF9118\r
-:1041B000AF919F918F913F912F910F900FBE0F90D4\r
-:1041C0001F9018958FB7F894209182043091830442\r
-:1041D00040918404509185048FBFB901CA010895AC\r
-:1041E0003FB7F89480917E0490917F04A091800461\r
-:1041F000B091810426B5A89B05C02F3F19F0019608\r
-:10420000A11DB11D3FBFBA2FA92F982F8827820F5C\r
-:10421000911DA11DB11D9C01AD01220F331F441F33\r
-:10422000551F280F391F4A1F5B1FB901CA01089586\r
-:10423000EF92FF920F931F93CF93DF937B018C013B\r
-:10424000CFDFEB010EC0CCDF6C1B7D0B83E0683E43\r
-:10425000780738F00894E108F10801091109C851FC\r
-:10426000DC4FE114F1040105110569F7DF91CF91ED\r
-:104270001F910F91FF90EF900895789484B582601C\r
-:1042800084BD84B5816084BD85B5826085BD85B5FA\r
-:10429000816085BDEEE6F0E0808181608083E1E8A9\r
-:1042A000F0E01082808182608083808181608083E1\r
-:1042B000E0E8F0E0808181608083E1EBF0E08081E4\r
-:1042C00084608083E0EBF0E0808181608083EAE7B6\r
-:1042D000F0E080818460808380818260808380813F\r
-:1042E000816080838081806880831092C1000895FE\r
-:1042F0001F93CF93DF93182FEB0161E084D02097B9\r
-:1043000009F44AC0CF3FD10509F449C0E12FF0E0DC\r
-:10431000ED57F04FE491E330C1F0E43028F4E130A0\r
-:1043200051F0E230B1F50CC0E63019F1E73049F157\r
-:10433000E43079F514C084B5806884BDC7BD32C04F\r
-:1043400084B5806284BDC8BD2DC080918000806826\r
-:1043500080938000D0938900C093880023C080910F\r
-:104360008000806280938000D0938B00C0938A008D\r
-:1043700019C08091B00080688093B000C093B300F2\r
-:1043800011C08091B00080628093B000C093B400EF\r
-:1043900009C0C038D1051CF4812F60E002C0812F14\r
-:1043A00061E052D0DF91CF911F910895833071F079\r
-:1043B000843028F48130A1F0823021F514C0863099\r
-:1043C000B1F08730D1F08430E9F404C080918000EE\r
-:1043D0008F7703C0809180008F7D80938000089547\r
-:1043E00084B58F7702C084B58F7D84BD0895809198\r
-:1043F000B0008F778093B00008958091B0008F7DDA\r
-:104400008093B000089590E0FC01ED59F04F2491A5\r
-:10441000FC01ED5BF04FE491EE23A9F0F0E0EC5CE1\r
-:10442000F04FA491B0E0662341F49FB7F8948C91CB\r
-:10443000209582238C939FBF08959FB7F8948C9109\r
-:10444000822B8C939FBF08950F931F93DF93CF937D\r
-:104450000F92CDB7DEB7282F30E0F901ED57F04FBE\r
-:104460008491F901ED59F04F14912D5B304FF90112\r
-:1044700004910023C9F0882319F0698397DF6981CB\r
-:10448000E02FF0E0E75CF04FA491B0E0662331F458\r
-:104490009FB7F8948C911095812304C09FB7F8942E\r
-:1044A0008C91812B8C939FBF0F90CF91DF911F91A7\r
-:1044B0000F9108951F920F920FB60F9211242F9310\r
-:1044C0003F934F935F936F938F939F93EF93FF93DC\r
-:1044D0006091C6002091070530910805C901019639\r
-:1044E0008F7790704091090550910A0584179507C0\r
-:1044F00041F029573B4FF901608390930805809361\r
-:104500000705FF91EF919F918F916F915F914F916F\r
-:104510003F912F910F900FBE0F901F9018959A0109\r
-:10452000AB0182E08093C00060E47BE48CE490E027\r
-:104530000E942C532150304040405040CA01B901E4\r
-:1045400022E030E040E050E00E942C533093C50060\r
-:104550002093C400E1ECF0E0808180618083808161\r
-:1045600088608083808180688083089580910905B8\r
-:1045700090910A0520910705309108052817390701\r
-:1045800069F0FC01E957FB4F208101968F7790700D\r
-:1045900090930A058093090530E002C02FEF3FEFAA\r
-:1045A000C90108958091090590910A059093080525\r
-:1045B0008093070508956F927F928F929F92AF929A\r
-:1045C000BF92CF92DF92EF92FF920F931F93DF93F0\r
-:1045D000CF93CDB7DEB7A0970FB6F894DEBF0FBE6E\r
-:1045E000CDBF5C01CB01BA01611571058105910553\r
-:1045F00031F4C50160E340E050E0A6D042C06E0156\r
-:104600000894C11CD11CEE24FF248701622E77245C\r
-:1046100088249924A40193010E940A53F60161930E\r
-:104620006F010894E11CF11C011D111DB901CA01A3\r
-:10463000611571058105910569F7D801C7010197D9\r
-:10464000A109B1096E010894C11CD11CC80ED91E64\r
-:1046500013C0F60160816A3010F4605D01C0695CCE\r
-:10466000C50140E050E070D00894E108F10801096C\r
-:1046700011090894C108D108E114F10401051105DC\r
-:1046800041F7A0960FB6F894DEBF0FBECDBFCF9115\r
-:10469000DF911F910F91FF90EF90DF90CF90BF902F\r
-:1046A000AF909F908F907F906F9008952115310566\r
-:1046B00039F48091C00085FFFCCF4093C600089577\r
-:1046C0007ACF9A01AB0160E070E0F0CF9A01462FFB\r
-:1046D00050E060E070E0EACFEF92FF920F931F93FB\r
-:1046E000CF93DF93EC017A018B012115310539F469\r
-:1046F0008091C00085FFFCCFE092C60016C02A3032\r
-:10470000310591F477FF0CC06DE240E050E01CD021\r
-:1047100010950095F094E094E11CF11C011D111D11\r
-:10472000CE01B801A7012AE046DFDF91CF911F91AA\r
-:104730000F91FF90EF9008959A01FB01AF0166275A\r
-:1047400057FD6095762FC8CF9A01462F50E060E064\r
-:1047500070E0C2CFCF93DF93EC016DE040E050E01A\r
-:10476000F3DFCE016AE040E050E0EEDFDF91CF9171\r
-:104770000895CF93DF93EC01A4DFCE01EBDFDF914F\r
-:10478000CF9108958F929F92BF92CF92DF92EF9236\r
-:10479000FF920F931F93CF93DF934C017A018B010C\r
-:1047A000D22ECB01BA0120E030E0A9010E943D4F9A\r
-:1047B00087FF09C0C4016DE240E050E0C5DF17FB90\r
-:1047C000109517F91095C0E050E040E030E02FE37D\r
-:1047D00011C0DA01F9016B2F742F8F2F922F20E077\r
-:1047E00030E040E251E40E94444F562F472F382FCB\r
-:1047F000292FCF5FCD1568F3C801B701DA01F901A0\r
-:104800002B2F342F4F2F5E2F0E94644EC62EF72E73\r
-:104810008C01912F0E94B14FC62FE72ED82FB92EB1\r
-:104820000E94DD4F9B01AC016C2D7F2D802F912FBD\r
-:104830000E94634EC62EF72E182F092FC4014C2F4D\r
-:104840005E2D6D2F7B2D2AE030E030DFDD2009F476\r
-:104850003EC0E1EBF1E006C09091C00095FFFCCFB7\r
-:104860008093C60081918823B9F731C098016C2DDF\r
-:104870007F2D832F902F20E030E040E251E40E9412\r
-:1048800012528B01F82EE92E9701712F832F922F50\r
-:104890000E94AC4F9B01AC01EB01C401B9014AE09D\r
-:1048A00050E04ADFBE01882777FD8095982F0E944F\r
-:1048B000DF4F9B01AC01F701602F712F8F2F9E2FCF\r
-:1048C0000E94634EC62EF72E182F092FDA94DD2092\r
-:1048D00069F6DF91CF911F910F91FF90EF90DF90DC\r
-:1048E000CF90BF909F908F9008954CCF08950895DA\r
-:1048F0002F923F924F925F926F927F928F929F92F0\r
-:10490000AF92BF92CF92DF92EF92FF920F931F93DD\r
-:10491000DF93CF93CDB7DEB7C055D0400FB6F89434\r
-:10492000DEBF0FBECDBF4C017A8F698F3A012AA737\r
-:104930000EABEFAAA8AEB9AECAAEDBAE022F10E046\r
-:10494000000F111F000F111F9301200F311F3BABF0\r
-:104950002AABD9012D903D904D905C90FC01E00F69\r
-:10496000F11FC201B10120813181428153810E9436\r
-:10497000644E6CAF7DAF8EAF9FAFBEA9EB2EFF2410\r
-:10498000EE0CFF1CEE0CFF1CF301EE0DFF1DFDAB4A\r
-:10499000ECABA080B180C280D380F401EE0DFF1D8E\r
-:1049A000C601B50120813181428153810E94644E4C\r
-:1049B00021966FAF219722967FAF229723968FAFD4\r
-:1049C000239724969FAF2497FFA98F2F90E0880FFD\r
-:1049D000991F880F991FF401E80FF91F2081318179\r
-:1049E000428153812B8F3C8F4D8F5E8F498D5A8D25\r
-:1049F000840F951FDC016D917D918D919C912B8D84\r
-:104A00003C8D4D8D5E8D0E94634E262F372F482F93\r
-:104A1000592F2F8F38A349A35AA3E98DFA8D3C96BD\r
-:104A20002996FFAFEEAF2997A98DBA8D1C962D91CF\r
-:104A30003D914D915C911F972EA73FA748AB59AB75\r
-:104A4000D4011C962D913D914D915C911F972BA304\r
-:104A50003CA34DA35EA3A20191015058298B3A8B30\r
-:104A60004B8B5C8B1501260157FA509457F85094E4\r
-:104A7000E98DFA8DE00FF11F608171818281938150\r
-:104A8000BCADADADFEADEFAD2B2F3A2F4F2F5E2F4E\r
-:104A90000E94634EB62EA72E882E692EE98DFA8DC0\r
-:104AA000EE0DFF1D60817181828193812196BFADE2\r
-:104AB00021972296AFAD22972396FFAD2397249698\r
-:104AC000EFAD24972B2F3A2F4F2F5E2F0E94634E6E\r
-:104AD0008B01F82EE92E69897A898B899C89F701E7\r
-:104AE000202F312F4F2F5E2F0E9412526D8B7E8B05\r
-:104AF0008F8B988FC201B101D5012B2F3A2F482DF2\r
-:104B0000562D0E9412529B01AC016D897E898F89BE\r
-:104B1000988D0E94634E6D8B7E8B8F8B988F6989E9\r
-:104B20007A898B899C89D5012B2F3A2F482D562DB8\r
-:104B30000E9412525B016C01C201B101F701202FEA\r
-:104B4000312F4F2F5E2F0E9412529B01AC01C601E4\r
-:104B5000B5010E94644E9B01AC016D897E898F89ED\r
-:104B6000988D0E94D74E162F072FF82EE92EA801F8\r
-:104B70009701652F742F832F922F20E030E0A90139\r
-:104B80000E943D4F87FF10C0A8019701652F742F29\r
-:104B9000832F922F2BED3FE049EC50E40E94644EAE\r
-:104BA000162F072FF82EE92EAA968FADAA978823E5\r
-:104BB00081F0A8019701652F702F832F9E2D2BED7B\r
-:104BC0003FE049EC50E40E94634E162F072FF82E69\r
-:104BD000E92EA8019701652F702F832F9E2DA9968E\r
-:104BE0002CAD3DAD4EAD5FADA9970E9412522F8DF9\r
-:104BF00038A149A15AA15F770E944D515B016C0118\r
-:104C00002FE632E143E85AE30E943D4F87FDA6C2FA\r
-:104C1000C601B5010E941A500E94B14F7DA76CA732\r
-:104C20006115710521F481E090E09DA78CA7ACA5EA\r
-:104C3000BDA5BD0180E090E00E94DD4F5B016C01ED\r
-:104C4000A8019701652F702F832F9E2DA601950136\r
-:104C50000E94444F6D8B7FA388A799A76F8D78A181\r
-:104C600089A19AA1A60195010E94444F2A966FAF8F\r
-:104C70002A972B967FAF2B972C968FAF2C972D963C\r
-:104C80009FAF2D976EA57FA588A999A92BA13CA1BF\r
-:104C90004DA15EA10E94634EA60195010E94444F62\r
-:104CA0002E966FAF2E972F967FAF2F9760968FAF70\r
-:104CB000609761969FAF61975D894FA138A529A53F\r
-:104CC000652F742F832F922F20E030E040E05FE3C8\r
-:104CD0000E941252BD89AFA1F8A5E9A52B2F3A2F4A\r
-:104CE0004F2F5E2F0E9412529B01AC0160E070E0DA\r
-:104CF00080E89FE30E94634E6EA725967FAF2597BD\r
-:104D000026968FAF269727969FAF2797BFA9EB2FA1\r
-:104D1000F0E0EE0FFF1FEE0FFF1FCE010196E80F30\r
-:104D2000F91F2B8D3C8D4D8D5E8D20833183428309\r
-:104D300053832BA13CA14DA15EA12D873E874F87B8\r
-:104D4000588BBB2441E050E05CA34BA3BAA5AB2F2A\r
-:104D5000B0E0AA0FBB1FAA0FBB1F9C012A0F3B1F6D\r
-:104D60003C8F2B8F5EA9452F50E0440F551F440FF9\r
-:104D7000551F81E090E08C0F9D1F840F951F98A315\r
-:104D80008F8FFBA7EAA7CAC19B2D99310CF068C091\r
-:104D900069897A898B899C89BD89AFA1F8A5E9A524\r
-:104DA0002B2F3A2F4F2F5E2F0E9412527B018C0126\r
-:104DB000C201B101BEA52596AFAD25972696FFADE0\r
-:104DC00026972796EFAD27972B2F3A2F4F2F5E2F41\r
-:104DD0000E9412529B01AC01C801B7010E94644EAF\r
-:104DE000D62EA72E882E692E69897A898B899C896F\r
-:104DF000BEA52596AFAD25972696FFAD269727969B\r
-:104E0000EFAD27972B2F3A2F4F2F5E2F0E94125274\r
-:104E1000162F072FF82EE92EC201B101BD89AFA1CF\r
-:104E2000F8A5E9A52B2F3A2F4F2F5E2F0E94125283\r
-:104E30009B01AC01D801F7016B2F7A2F8F2F9E2F8A\r
-:104E40000E94634E262F372F482F592F298B3A8BDC\r
-:104E50004B8B5C8BB3942D2C3A2C482C562C6AC06F\r
-:104E6000ABA1BCA1BD0180E090E00E94DD4FBD89F7\r
-:104E7000AFA1F8A5E9A52B2F3A2F4F2F5E2F0E9447\r
-:104E800012527B018C017F2D912F0E94414F1B01FB\r
-:104E90002C016E2D7F2D802F912F0E9475525B016A\r
-:104EA0006C01EAA9FBA9E080F1800281138117FB64\r
-:104EB000109517F91095ACA9BDA96D907D908D90B6\r
-:104EC0009C90C801B701A20191010E941252698B06\r
-:104ED0007A8B8B8B9C8BC401B301A60195010E9438\r
-:104EE00012529B01AC0169897A898B899C890E9445\r
-:104EF000644E262F372F482F592F298B3A8B4B8BF7\r
-:104F00005C8BC801B701A60195010E9412527B017A\r
-:104F10008C01C401B301A20191010E9412529B01B4\r
-:104F2000AC01C801B7010E94634E262E372E482ED1\r
-:104F3000592EBB245CAD4DAD3EAD2FAD652F742F0A\r
-:104F4000832F922F29893A894B895C890E94644E6C\r
-:104F5000EB8DFC8D608371838283938321965FAD9B\r
-:104F6000219722964FAD229723963FAD2397249603\r
-:104F70002FAD2497652F742F832F922FA2019101BB\r
-:104F80000E94644EAF8DB8A16D937D938D939C93D9\r
-:104F90001397EAA5FBA560817181828193812A968E\r
-:104FA000BFAD2A972B96AFAD2B972C96FFAD2C97C4\r
-:104FB0002D96EFAD2D972B2F3A2F4F2F5E2F0E945E\r
-:104FC000644EAAA5BBA56D937D938D939C93139777\r
-:104FD0006D857E858F8598892E96BFAD2E972F96ED\r
-:104FE000AFAD2F976096FFAD60976196EFAD61977B\r
-:104FF0002B2F3A2F4F2F5E2F0E94644E6D877E8796\r
-:105000008F87988B69817A818B819C8120E030E049\r
-:10501000A9010E943D4F87FF07C080E090E0DC01BE\r
-:1050200089839A83AB83BC836D817E818F819885D0\r
-:1050300020E030E0A9010E943D4F87FF07C080E0DB\r
-:1050400090E0DC018D839E83AF83B88769857A8584\r
-:105050008B859C8520E030E0A9010E943D4F87FFB1\r
-:1050600007C080E090E0DC0189879A87AB87BC8726\r
-:1050700069817A818B819C8120E030E04DE453E4AA\r
-:105080000E944051181644F480E090E0ADE4B3E48F\r
-:1050900089839A83AB83BC836D817E818F81988560\r
-:1050A00020E030E04DE453E40E944051181644F4EF\r
-:1050B00080E090E0ADE4B3E48D839E83AF83B88756\r
-:1050C00069857A858B859C8520E030E040EF52E44D\r
-:1050D0000E944051181644F480E090E0A0EFB2E442\r
-:1050E00089879A87AB87BC87CE010196BE016B5F2B\r
-:1050F0007F4FAE01475F5F4F9E01235F3F4FE8AC9C\r
-:10510000F9AC0AAD1BADFAE6CF2ED12CCC0EDD1ECC\r
-:10511000D5D4EBA1FCA13196FCA3EBA32BA13CA120\r
-:105120004CA55DA52417350708F42ECE698D7A8D20\r
-:105130006C5F7F4F498D5A8D485F5F4F898D9A8D87\r
-:1051400029962EAD3FAD2997E8ACF9AC0AAD1BAD61\r
-:10515000EAE6CE2ED12CCC0EDD1EB0D4C05BDF4FE4\r
-:105160000FB6F894DEBF0FBECDBFCF91DF911F9178\r
-:105170000F91FF90EF90DF90CF90BF90AF909F90F6\r
-:105180008F907F906F905F904F903F902F900895F9\r
-:105190008F5F803109F480E008952F923F924F9203\r
-:1051A0005F926F927F928F929F92AF92BF92CF92B7\r
-:1051B000DF92EF92FF920F931F93DF93CF93CDB7C0\r
-:1051C000DEB76A970FB6F894DEBF0FBECDBF9A8FD9\r
-:1051D000898F3A014B0178018901DC01D8966D91E4\r
-:1051E0007D918D919C91DB970E94DD4F5B016C015D\r
-:1051F000A40193010E9412520E942A4F0E94B14FB3\r
-:10520000262F372F482F592F2D873E874F87588BB2\r
-:10521000C601B501A80197010E9412520E942A4FAF\r
-:105220000E94B14F9B01AC01298B3A8B4B8B5C8B5D\r
-:105230008D859E85AF85B88988379105A105B10513\r
-:1052400040F488E790E0A0E0B0E08D879E87AF87CC\r
-:10525000B88B283731054105510540F428E730E087\r
-:1052600040E050E0298B3A8B4B8B5C8BE98DFA8DBB\r
-:10527000EC5BFF4F6080718082809380A98DBA8D36\r
-:10528000DC966D917D918D919C91DF970E94DD4F11\r
-:105290006D837E838F839887C401B3010E94DF4FA3\r
-:1052A0001B012C0120E030E0A9010E943D4F882322\r
-:1052B00029F1C601B501A60195010E9412527B0198\r
-:1052C0008C016D817E818F8198859B01AC010E944C\r
-:1052D00012529B01AC01C801B7010E94634E7B01D1\r
-:1052E0008C01C201B101A20191010E94644E9B0197\r
-:1052F000AC01C801B7010E94444F04C060E070E0F7\r
-:1053000080E090E00E942A4F0E94AC4F69837A832C\r
-:105310008B839C83E980FA800B811C81E98DFA8D57\r
-:10532000E05CFF4F60817181828193810E94DD4F3B\r
-:1053300069877A878B879C8766277727CB016619D1\r
-:105340007709880999090E94DF4F3B014C0120E051\r
-:1053500030E0A9010E943D4F882349F169857A8593\r
-:105360008B859C859B01AC010E9412526D8B7E8BBC\r
-:105370008F8B988FC601B501A60195010E9412522C\r
-:105380009B01AC016D897E898F89988D0E94634E47\r
-:105390005B016C01C401B301A40193010E94644E3E\r
-:1053A0009B01AC01C601B5010E94444F04C060E0FE\r
-:1053B00070E080E090E00E941A50E98DFA8DA0889C\r
-:1053C000B188C288D3883501460129813A814B8151\r
-:1053D0005C81621A730A840A950A0E94AC4FA40188\r
-:1053E0009301261B370B480B590BDA01C90157FFF4\r
-:1053F00068C0C201B10120E030E0A9010E943D4F28\r
-:10540000882309F443C0C201B101A20191010E94A5\r
-:10541000644E7B018C01C601B5010E94DD4F9B01EA\r
-:10542000AC01C801B7010E9412527B018C016D8151\r
-:105430007E818F8198859B01AC010E9412529B0155\r
-:10544000AC01C801B7010E94634E7B018C016985E4\r
-:105450007A858B859C859B01AC010E9412529B0131\r
-:10546000AC01C801B7010E94644E7B018C01C201EE\r
-:10547000B10120E030E040E850E40E9412529B016C\r
-:10548000AC01C801B7010E94444F04C060E070E065\r
-:1054900080E090E00E942A4F0E94AC4FE62EF72E4B\r
-:1054A000082F192F17FF03C0EE24FF248701EA14E9\r
-:1054B000FB040C051D0510F08601750180E090E0ED\r
-:1054C000DC012FB7F894E98DFA8DE45BFF4F308152\r
-:1054D000332311F5E98DFA8DE48AF58A068B178B53\r
-:1054E000E80EF91E0A1F1B1FE08EF18E028F138F2C\r
-:1054F0008D859E85AF85B88984AF95AFA6AFB7AFD0\r
-:10550000AF01405C5F4F89899A89AB89BC89FA01F8\r
-:1055100080839183A283B3832FBF6A960FB6F894DA\r
-:10552000DEBF0FBECDBFCF91DF911F910F91FF90D6\r
-:10553000EF90DF90CF90BF90AF909F908F907F9033\r
-:105540006F905F904F903F902F900895AF92BF92D1\r
-:10555000CF92DF92EF92FF920F931F93CF93DF933F\r
-:10556000EB018A01209709F472C04115510509F435\r
-:105570006EC0DAA4CBA4BCA4ADA46EA17FA188A503\r
-:1055800099A5D601F5012B2F3A2F4F2F5E2F0E94A0\r
-:105590003D4F882309F45BC08FA9882309F04BC0D5\r
-:1055A000F801E6A0F7A000A511A5A6019501652FB9\r
-:1055B000742F832F922FA80197010E944051181633\r
-:1055C000D4F5C801B701A80197010E9412527B01CE\r
-:1055D0008C012AA93BA94CA95DA95058CA01B9015F\r
-:1055E0000E94644E2EA53FA548A959A90E941252B7\r
-:1055F0009B01AC01C801B7010E94634E0E947F521B\r
-:10560000E62E172F082FF92EA6019501652F742F6E\r
-:10561000832F922F2E2D312F402F5F2D0E943D4F33\r
-:1056200087FF04C0ED2C1C2D0B2DFA2C5E2D412F75\r
-:10563000302F2F2D02C0A6019501852F942FA32F67\r
-:10564000B22F8EA39FA3A8A7B9A781E08EABDF914D\r
-:10565000CF911F910F91FF90EF90DF90CF90BF906F\r
-:10566000AF900895CF92DF92EF92FF920F931F9326\r
-:10567000DF93CF930F92CDB7DEB780914C0A809124\r
-:105680004C0A20914D0A90E04096821B91098F7040\r
-:1056900090708430910544F120914C0A23502F7072\r
-:1056A00040E050E000E010E08DE4E82EF12C18C05E\r
-:1056B000222309F420E12150822F90E08E9D600189\r
-:1056C0008F9DD00C9E9DD00C11248CE795E0C80EC8\r
-:1056D000D91EC601B801298339DFA80186012981B5\r
-:1056E00080914D0A281721F70F90CF91DF911F91DC\r
-:1056F0000F91FF90EF90DF90CF9008958F929F923F\r
-:10570000AF92BF92CF92DF92EF92FF920F931F93CF\r
-:10571000CF93DF93EC016B01009709F467C08FA969\r
-:10572000882309F063C0EEA0FFA008A519A5FB011E\r
-:10573000B6A0A7A090A481A4C801B701D501F40127\r
-:105740002B2F3A2F4F2F5E2F0E943D4F87FF4EC0C9\r
-:10575000C801B701A80197010E9412527B018C0178\r
-:105760002AA93BA94CA95DA95058CA01B9010E94B8\r
-:10577000644E2EA53FA548A959A90E9412529B012B\r
-:10578000AC01C801B7010E94634E0E947F52E62E11\r
-:10579000C72FD82F192FA5019401652F742F832FA0\r
-:1057A000922F2E2D3C2F4D2F512F0E943D4F87FFC2\r
-:1057B00004C0EB2CCA2DD92D182DA5019401652FFD\r
-:1057C0007A2D832F982D2E2D3C2F4D2F512F0E9457\r
-:1057D0003D4F882359F08E2D9C2FAD2FB12FF60110\r
-:1057E00086A397A3A0A7B1A781E086ABDF91CF9155\r
-:1057F0001F910F91FF90EF90DF90CF90BF90AF90EF\r
-:105800009F908F900895DF92EF92FF920F931F93D6\r
-:10581000CF93DF93D0904D0A00E010E080E090E05D\r
-:105820002DE4E22EF12C13C02D2D30E02E9DE00151\r
-:105830002F9DD00D3E9DD00D1124C458DA4FB801D4\r
-:10584000AE015CDF8D2DA4DCD82EC8018E01209125\r
-:105850004C0AD21649F7B80140E050E04FDFDF9123\r
-:10586000CF911F910F91FF90EF90DF9008952F92AD\r
-:105870003F924F925F926F927F928F929F92AF92E0\r
-:10588000BF92CF92DF92EF92FF920F931F93CF932D\r
-:10589000DF93F0904D0AC0E0D0E03DE4632E712C20\r
-:1058A0003EC0069D6001079DD00C169DD00C1124B2\r
-:1058B0008CE795E0C80ED91E209769F18EA9882340\r
-:1058C00021F4F60186A9882331F18AA09BA0ACA01F\r
-:1058D000BDA06EA17FA188A599A5A50194010E94F4\r
-:1058E000444F1B012C01069DF001079DF00D169DF4\r
-:1058F000F00D1124E458FA4F66A177A180A591A577\r
-:10590000A50194010E94444F8B019C01CE01B2017C\r
-:10591000A10143DC1EAA8F2D3BDCF82EE6010F2DE2\r
-:10592000112707FD109580914C0A90E00817190780\r
-:1059300009F0B7CF2097E9F0CAA0DBA0ECA0FDA04A\r
-:105940006EA17FA188A599A5A70196010E94444F49\r
-:105950004B015C016DEC7CEC8CE49DE3A7019601AE\r
-:105960000E94444F8B019C01CE01B501A40115DCBE\r
-:105970001EAADF91CF911F910F91FF90EF90DF90C2\r
-:10598000CF90BF90AF909F908F907F906F905F90DF\r
-:105990004F903F902F90089565DE35DF68CF1092CD\r
-:1059A0004C0A10924D0A80E1ECE6F5E0DF011D9211\r
-:1059B0008A95E9F780E090E0DC018093530A9093A8\r
-:1059C000540AA093550AB093560A8093570A9093AD\r
-:1059D000580AA093590AB0935A0A80935B0A90938D\r
-:1059E0005C0AA0935D0AB0935E0A80935F0A90936D\r
-:1059F000600AA093610AB093620A80934F0A909361\r
-:105A0000500AA093510AB093520A0895CF939091EF\r
-:105A10004D0A80914C0A981779F140914D0A242F34\r
-:105A200030E08DE490E0289FF001299FF00D389F31\r
-:105A3000F00D1124EC53FA4FC08150E02DE430E01A\r
-:105A400016C0842F90E0829FF001839FF00D929FFB\r
-:105A5000F00D1124EC53FA4F80819181A281B38122\r
-:105A60000097A105B10509F05F5F4F5F4F7080910E\r
-:105A70004C0A481731F70AC06091AA02662321F048\r
-:105A80008EE070E00E947821C0E050E08091AA0290\r
-:105A9000882339F4552329F48EE060E070E00E94F9\r
-:105AA00078218091AA02882339F0CC2329F08EE056\r
-:105AB0006C2F70E00E947821CF9108952F923F9231\r
-:105AC0004F925F926F927F928F929F92AF92BF920E\r
-:105AD000CF92DF92EF92FF920F931F93DF93CF93BA\r
-:105AE000CDB7DEB7C555D0400FB6F894DEBF0FBEB8\r
-:105AF000CDBF2C013B011A013AA329A39E2CAF2C48\r
-:105B0000802EB12EDCAACBAA80914C0A41DB649690\r
-:105B10008FAF6497082F112707FD109505C00E94CD\r
-:105B2000AB4381E00E946C1080914D0A90E0801799\r
-:105B30009107A9F3D2016D917D918D919C91209156\r
-:105B400020053091210540912205509123050E94A6\r
-:105B500012520E94E2516FAB78AF89AF9AAFF30156\r
-:105B60006081718182819381209124053091250586\r
-:105B700040912605509127050E9412520E94E25141\r
-:105B80006BAF7CAF8DAF9EAFD1016D917D918D914B\r
-:105B90009C91209128053091290540912A0550912A\r
-:105BA0002B050E9412520E94E2516FAF21967FAFE7\r
-:105BB000219722968FAF229723969FAF2397E9A133\r
-:105BC000FAA1608171818281938120912C053091AD\r
-:105BD0002D0540912E0550912F050E9412520E94D2\r
-:105BE000E2516FA778AB89AB9AAB80917805909121\r
-:105BF0007905A0917A05B0917B052FA538A949A90F\r
-:105C00005AA9281739074A075B0709F445C060916C\r
-:105C1000A902E62FF0E0EE0FFF1FE355F54F80815C\r
-:105C200091810E94A64220E030E046E153E40E94C8\r
-:105C30003D4F87FF31C080914E0A882369F54FA5FB\r
-:105C400058A969A97AA9409378055093790560937A\r
-:105C50007A0570937B05EEE4F4E007C09091C000F4\r
-:105C600095FFFCCF8093C600319684918823B1F7CD\r
-:105C7000E2E7F4E007C09091C00095FFFCCF80936D\r
-:105C8000C600319684918823B1F78091C00085FFCA\r
-:105C9000FCCF8AE08093C6008091780590917905C9\r
-:105CA000A0917A05B0917B052FA538A949A95AA9D9\r
-:105CB000281B390B4A0B5B0BCA01B90157FF07C000\r
-:105CC00090958095709561957F4F8F4F9F4F0E9463\r
-:105CD000DF4F7B018C0160912C0570912D05809127\r
-:105CE0002E0590912F0520E030E04DEC53E40E940A\r
-:105CF00012529B01AC01C801B7010E944051181615\r
-:105D00006CF54FA558A969A97AA9409378055093D5\r
-:105D1000790560937A0570937B05EEE4F4E007C0A3\r
-:105D20009091C00095FFFCCF8093C600319684917E\r
-:105D30008823B1F7E4E5F4E007C09091C00095FF37\r
-:105D4000FCCF8093C600319684918823B1F780916F\r
-:105D5000C00085FFFCCF8AE08093C60080914C0A8A\r
-:105D6000682F70E07AA369A38DE490E0689FF0014A\r
-:105D7000699FF00D789FF00D1124E458FA4FDF0170\r
-:105D8000A45BBF4F1C9280916C0590916D05A09112\r
-:105D90006E05B0916F058BA39CA3ADA3BEA38FA985\r
-:105DA00098ADA9ADBAAD2BA13CA14DA15EA1821BBE\r
-:105DB000930BA40BB50BB7FF07C0B095A0959095BA\r
-:105DC00081959F4FAF4FBF4F80839183A283B38351\r
-:105DD0004091700550917105609172057091730545\r
-:105DE0004FA358A769A77AA78DE490E069A17AA18B\r
-:105DF000689FF001699FF00D789FF00D1124E45821\r
-:105E0000FA4F8BAD9CADADADBEAD2FA138A549A568\r
-:105E10005AA5821B930BA40BB50BB7FF07C0B09517\r
-:105E2000A095909581959F4FAF4FBF4F84839583E9\r
-:105E3000A683B783409174055091750560917605EE\r
-:105E4000709177054BA75CA76DA77EA78DE490E0C6\r
-:105E500069A17AA1689FF001699FF00D789FF00D0C\r
-:105E60001124E458FA4F23968CAD9DADAEADBFAD75\r
-:105E700023972BA53CA54DA55EA5821B930BA40BD8\r
-:105E8000B50BB7FF07C0B095A095909581959F4F32\r
-:105E9000AF4FBF4F80879187A287B3874090780527\r
-:105EA0005090790560907A0570907B052091EC0107\r
-:105EB0003091ED016FA578A989A99AA9641975098E\r
-:105EC0008609970997FF07C0909580957095619511\r
-:105ED0007F4F8F4F9F4F442737FD4095542F0E948F\r
-:105EE000D85224E630E040E050E00E942C538DE48C\r
-:105EF00090E069A17AA1689FF001699FF00D789FF9\r
-:105F0000F00D1124E458FA4F2487358746875787C8\r
-:105F1000C080D18072816381E480F5800681178121\r
-:105F200080859185A285B3858E159F05A007B10751\r
-:105F300014F4D801C70182179307A407B50714F416\r
-:105F4000DA01C901FB0196014F2F562F2817390797\r
-:105F50004A075B0714F49C01AD018DE490E0A9A110\r
-:105F6000BAA1A89FF001A99FF00DB89FF00D1124D0\r
-:105F7000E458FA4F208B318B428B538B26303105FE\r
-:105F80004105510510F40C942B399F01285B3F4FBC\r
-:105F90008091AA02482F50E060E070E0D9014D9353\r
-:105FA0005D936D937C93139710A22FA938AD49ADE3\r
-:105FB0005AAD6BA17CA18DA19EA12617370748077A\r
-:105FC000590714F481E080A38BAD9CADADADBEAD9F\r
-:105FD0002FA138A549A55AA582179307A407B5078D\r
-:105FE00084F48DE490E049A15AA1489FF001499FB3\r
-:105FF000F00D589FF00D1124E458FA4F80A18260F3\r
-:1060000080A323966CAD7DAD8EAD9FAD23972BA560\r
-:106010003CA54DA55EA5621773078407950784F418\r
-:106020008DE490E049A15AA1489FF001499FF00DED\r
-:10603000589FF00D1124E458FA4F80A1846080A38A\r
-:106040006FA578A989A99AA964157505860597058C\r
-:1060500084F48DE490E0A9A1BAA1A89FF001A99FC2\r
-:10606000F00DB89FF00D1124E458FA4F80A188601C\r
-:1060700080A38DE490E029A13AA1289FF001299FF7\r
-:10608000F00D389FF00D1124E458FA4FABA9BCA9CC\r
-:106090008C9181A380819181A281B3810097A10518\r
-:1060A000B10509F05A9A8DE490E029A13AA1289F00\r
-:1060B000F001299FF00D389FF00D1124E458FA4F9C\r
-:1060C00084819581A681B7810097A105B10509F06A\r
-:1060D0005A9A8DE490E049A15AA1489FF001499F46\r
-:1060E000F00D589FF00D1124E458FA4F80859185EA\r
-:1060F000A285B3850097A105B10509F05A9A8DE4F0\r
-:1061000090E069A17AA1689FF001699FF00D789FE6\r
-:10611000F00D1124E458FA4F84859585A685B7853E\r
-:106120000097A105B10509F05A9A8DE490E0A9A164\r
-:10613000BAA1A89FF001A99FF00DB89FF00D1124FE\r
-:10614000E458FA4F84859585A685B7850097A10503\r
-:10615000B10549F4F090580510915905E0905A05A1\r
-:1061600000915B0508C0F090400510914105E0905A\r
-:10617000420500914305692D7A2D882D9B2D2F2DE9\r
-:10618000312F4E2D502F0E943D4F87FD04C0F92C1A\r
-:106190001A2DE82C0B2D90914C0A80914D0AE92F75\r
-:1061A000F0E07096E81BF109EF70F070FCA7EBA728\r
-:1061B000BF01882777FD8095982F0E94DF4F4B0104\r
-:1061C0005C0120E030E040E051E40E943D4F87FF59\r
-:1061D00017C02BA53CA52230310594F06F2D712FEF\r
-:1061E0008E2D902FA50194010E94125220E030E0E4\r
-:1061F00040E05EE30E941252F62E172FE82E092F80\r
-:1062000080916C0590916D05A0916E05B0916F0520\r
-:106210002FA938AD49AD5AAD281B390B4A0B5B0B82\r
-:10622000CA01B9010E94DF4F20912005309121055C\r
-:1062300040912205509123050E94444F762E672EEF\r
-:106240008BA39FA3A301382F292F852F942FA32F32\r
-:10625000B22F89839A83AB83BC8380917005909120\r
-:106260007105A0917205B09173052BAD3CAD4DAD9C\r
-:106270005EAD281B390B4A0B5B0BCA01B9010E94AA\r
-:10628000DF4F20912405309125054091260550913E\r
-:1062900027050E94444F2B018BAB24969FAF249778\r
-:1062A000382F292F862F952DA32FB22F8D839E83D4\r
-:1062B000AF83B8878091740590917505A09176059C\r
-:1062C000B091770523962CAD3DAD4EAD5FAD2397D4\r
-:1062D000281B390B4A0B5B0BCA01B9010E94DF4F27\r
-:1062E000209128053091290540912A0550912B05D0\r
-:1062F0000E94444F362E272E28968FAF28972C9633\r
-:106300009FAF2C97A101382F292F852F942FA32FD2\r
-:10631000B22F89879A87AB87BC878090EC019090D9\r
-:10632000ED018091780590917905A0917A05B09161\r
-:106330007B052FA538A949A95AA9281B390B4A0B57\r
-:106340005B0BCA01B9010E94DF4F20912C053091EF\r
-:106350002D0540912E0550912F050E94444F5B0161\r
-:106360006C01B401882777FD8095982F0E94DF4F3C\r
-:106370009B01AC01C601B5010E94125220E030E041\r
-:1063800048EC52E40E94444F6B01B82FA92F4B01F7\r
-:10639000A82EB92E9B01482F592F2D873E874F8756\r
-:1063A000588B8DE490E049A15AA1489FF001499F84\r
-:1063B000F00D589FF00D1124E458FA4F20813181DF\r
-:1063C00042815381211531054105510591F5248103\r
-:1063D000358146815781211531054105510549F522\r
-:1063E00020853185428553852115310541055105AB\r
-:1063F00001F5B6018B2F9A2F20E030E0A9010E9411\r
-:106400004051181624F0B7FAB094B7F8B0948DE460\r
-:1064100090E069A17AA1689FF001699FF00D789FD3\r
-:10642000F00D1124E458FA4F86A697A6A0AAB1AAA7\r
-:1064300047C0A3013BA12FA1652F762D832F922F5B\r
-:106440000E94BD524B015C013BA924962FAD2497BD\r
-:10645000642D752D832F922F0E94BD522B013C017C\r
-:10646000A10128963FAD28972C962FAD2C97652F2C\r
-:10647000722D832F922F0E94BD526BA37CA38DA3FC\r
-:106480009EA3C501B401A30192010E94644E2BA1F9\r
-:106490003CA14DA15EA10E94644E0E947F522DE45A\r
-:1064A00030E0A9A1BAA1A29FF001A39FF00DB29F75\r
-:1064B000F00D1124E458FA4F66A777A780AB91AB93\r
-:1064C0008DE490E0E9A1FAA1E89F6001E99FD00C7A\r
-:1064D000F89FD00C11242CE735E0C20ED31ED60154\r
-:1064E0009E968D909D90AD90BC90D19760E070E0AD\r
-:1064F00080E89FE3A50194010E94444F9B01AC01F9\r
-:106500006F2D712F8E2D902F0E941252362E272E16\r
-:10651000782E692EC501B401D101F3012B2F3A2F3A\r
-:106520004F2F5E2F0E941252F60162A373A384A321\r
-:1065300095A360897189828993890E94DD4FD10179\r
-:10654000F3012B2F3A2F4F2F5E2F0E9412520E94E1\r
-:106550002A4F0E94B14FD601D8966D937D938D93AB\r
-:106560009C93DB978E010F5F1F4FB1E14B2E512C97\r
-:106570004C0E5D1E7201F8016191719181919191B2\r
-:106580008F01D101F3012B2F322D4F2F562D0E9459\r
-:106590001252D7016D937D938D939D937D010415C8\r
-:1065A000150549F7E0E1F5E0F8A7EFA39E012F5D9F\r
-:1065B0003F4F66963FAF2EAF66973F011201DD2435\r
-:1065C000CC24A0E88A2EFFE3BF2ED101ED90FD90F0\r
-:1065D0000D911D911D01AA24A394C801B70120E0CB\r
-:1065E00030E0A9010E94405118162CF0AA24C801DD\r
-:1065F000B701905802C0C801B701D3012D913D9158\r
-:106600004D915D913D012BA33CA34DA35EA30E9440\r
-:106610004051181664F5AA2021F4A801970150589A\r
-:1066200002C0A80197016BA17CA18DA19EA10E942F\r
-:10663000444F9B01AC01ED2DFC2DA82DBB2DBF01BE\r
-:10664000CD010E943D4F87FD12C0AA2021F417FB07\r
-:10665000109517F910956BA17CA18DA19EA1A801A1\r
-:1066600097010E94444FD62EC72E882EB92E6696CB\r
-:10667000EEADFFAD66972E163F0609F0A6CFA60138\r
-:10668000652F7C2D882D9B2D20E030E040E85FE3D6\r
-:106690000E943D4F87FFA8C012015CA24BA2D1010E\r
-:1066A000ED90FD900D911D911D01AA24A394C801A8\r
-:1066B000B70120E030E0A9010E94405118162CF0EB\r
-:1066C000AA24C801B701905802C0C801B701EFA1C0\r
-:1066D000F8A54190519061907190F8A7EFA3A301A4\r
-:1066E00092010E944051181634F5AA2021F4A80105\r
-:1066F0009701505802C0A8019701C301B2010E943E\r
-:10670000444F9B01AC016D2D7C2D882D9B2D0E944B\r
-:106710003D4F87FD10C0AA2021F417FB109517F9F3\r
-:106720001095C301B201A80197010E94444FD62ED3\r
-:10673000C72E882EB92E66962EAD3FAD66972216CF\r
-:10674000330609F0ACCF4BA05CA0D2016D917D91D6\r
-:106750008D919C91D6012B2F3C2D482D5B2D0E94B5\r
-:106760001252F20161937193819391932F01669676\r
-:106770002EAD3FAD6697E217F30739F78DE490E051\r
-:1067800049A15AA1489F8001499F100D589F100DA3\r
-:10679000112404581A4FD80192966D917D918D91D4\r
-:1067A0009C919597D6012B2F3C2D482D5B2D0E9457\r
-:1067B0001252F80162A373A384A395A360AD71ADD7\r
-:1067C00082AD93AD0E94DD4FD6012B2F3C2D482D7D\r
-:1067D0005B2D0E9412520E94B14FD801D8966D9342\r
-:1067E0007D938D939C93DB978DE490E0E9A1FAA1D2\r
-:1067F000E89F8001E99F100DF89F100D11240458A7\r
-:106800001A4FD80150966D917D918D919C9153971F\r
-:106810000E94DD4FF80126A537A540A951A90E9485\r
-:10682000444F562E472E382E292EF8018081918113\r
-:10683000A281B3810097A105B10569F58481958195\r
-:10684000A681B7810097A105B10529F580859185BD\r
-:10685000A285B3850097A105B105E9F4A2019101D4\r
-:10686000652F742F832F922F209148053091490571\r
-:1068700040914A0550914B050E9412520E942A4FA6\r
-:106880000C5B1F4F0E94B14FD8016D937D938D9388\r
-:106890009C93139765C1A2019101652F742D832FDD\r
-:1068A000922D209144053091450540914605509127\r
-:1068B00047050E9412520E942A4F0E94B14F2DE4B8\r
-:1068C00030E0E9A1FAA1E29F8001E39F100DF29F61\r
-:1068D000100D112404581A4FE4E46E2E712C600E32\r
-:1068E000711ED3016D937D938D939C93139780902C\r
-:1068F0005C0590905D05A0905E05B0905F050E94DC\r
-:10690000DD4F6B017C01F80160817181828193818F\r
-:106910000E94DF4F9B01AC01C701B6010E941252D9\r
-:106920006B017C01D80150966D917D918D919C9168\r
-:1069300053970E94DD4F9B01AC01C701B6010E9435\r
-:10694000444F7B018C01C501B4010E94DD4F9B01C6\r
-:10695000AC01C801B7010E94405118162CF4F30194\r
-:1069600080829182A282B3828090600590906105BE\r
-:10697000A0906205B09063058DE490E029A13AA152\r
-:10698000289F8001299F100D389F100D1124045855\r
-:106990001A4F64E4662E712C600E711ED3016D9146\r
-:1069A0007D918D919C910E94DD4F6B017C01F801DE\r
-:1069B00064817581868197810E94DF4F9B01AC01C4\r
-:1069C000C701B6010E9412526B017C01D80150969A\r
-:1069D0006D917D918D919C9153970E94DD4F9B010C\r
-:1069E000AC01C701B6010E94444F7B018C01C50177\r
-:1069F000B4010E94DD4F9B01AC01C801B7010E94A8\r
-:106A0000405118162CF4F30180829182A282B38245\r
-:106A10008090680590906905A0906A05B0906B051C\r
-:106A20008DE490E029A13AA1289F8001299F100DB3\r
-:106A3000389F100D112404581A4F54E4652E712C00\r
-:106A4000600E711ED3016D917D918D919C910E947C\r
-:106A5000DD4F6B017C01F80164857585868597851E\r
-:106A60000E94DF4F9B01AC01C701B6010E94125288\r
-:106A70006B017C01D80150966D917D918D919C9117\r
-:106A800053970E94DD4F9B01AC01C701B6010E94E4\r
-:106A9000444F7B018C01C501B4010E94DD4F9B0175\r
-:106AA000AC01C801B7010E94405118162CF4F30143\r
-:106AB00080829182A282B382809064059090650565\r
-:106AC000A0906605B09067058DE490E029A13AA1F9\r
-:106AD000289F8001299F100D389F100D1124045804\r
-:106AE0001A4F44E4642E712C600E711ED3016D9117\r
-:106AF0007D918D919C910E94DD4F6B017C01F8018D\r
-:106B000060857185828593850E94DF4F9B01AC0172\r
-:106B1000C701B6010E9412526B017C01D801509648\r
-:106B20006D917D918D919C9153970E94DD4F9B01BA\r
-:106B3000AC01C701B6010E94444F7B018C01C50125\r
-:106B4000B4010E94DD4F9B01AC01C801B7010E9456\r
-:106B5000405118162CF4F30180829182A282B382F4\r
-:106B60008DE490E029A13AA1289F8001299F100D72\r
-:106B7000389F100D112404581A4FF801EC5BFF4F99\r
-:106B800060817181828193810E94DD4F6B017C0164\r
-:106B9000D201F1012B2F342D4F2F522D0E94444F43\r
-:106BA000D801D2966D937D938D939C93D597C70111\r
-:106BB000B6012DEB37E346E051E40E9412520E94E9\r
-:106BC000AC4FF801648F758F868F978F20914C059D\r
-:106BD00030914D0540914E0550914F052B962CAFAD\r
-:106BE0003DAF4EAF5FAF2B97498D5A8D6B8D7C8D2E\r
-:106BF0004BAB5CAB6DAB7EABCB01BA0120E030E0C0\r
-:106C0000A9010E94405118164CF08BA89CA8ADA871\r
-:106C1000BEA8B7FAB094B7F8B09404C08BA89CA8EB\r
-:106C2000ADA8BEA8609150057091510580915205A4\r
-:106C3000909153052F966CAF7DAF8EAF9FAF2F977E\r
-:106C400020E030E040E05FE30E9412527B016C01E3\r
-:106C5000C501B4012E2D3F2D4C2D5D2D0E944051BC\r
-:106C6000181674F02B966CAD7DAD8EAD9FAD2B9745\r
-:106C700020E030E040E05FE30E9412527B016C01B3\r
-:106C80008DE490E0E9A1FAA1E89FD001E99FB00D61\r
-:106C9000F89FB00D1124A458BA4FFD01B2969296F8\r
-:106CA0003C90218022812BA333813FA36E2D7F2D29\r
-:106CB0008C2D9D2DD101FBA1EFA12B2F3A2F4F2F12\r
-:106CC0005E2F0E943D4F87FD04C0E32CF22CCBA029\r
-:106CD000DFA04D8D5E8D6F8D78A127964CAF5DAF97\r
-:106CE0006EAF7FAF2797CB01BA0120E030E0A9015A\r
-:106CF0000E94405118165CF027968CAC9DACAEAC4F\r
-:106D0000BFAC2797B7FAB094B7F8B09406C02796EF\r
-:106D10008CAC9DACAEACBFAC279760915405709124\r
-:106D20005505809156059091570563966CAF7DAFE0\r
-:106D30008EAF9FAF639720E030E040E05FE30E94BA\r
-:106D40001252162F072F482E792EC501B401D801F3\r
-:106D50002B2F3A2F442D572D0E94405118168CF49A\r
-:106D60006E2D7F2D8C2D9D2DD8012B2F3A2F442D4C\r
-:106D7000572D0E943D4F87FD04C0E12EF02EC42CFC\r
-:106D8000D72C8BA59CA5823091050CF469C160912C\r
-:106D90004F0A7091500A8091510A9091520A27E14E\r
-:106DA00037EB41ED58E30E94405118160CF058C1E2\r
-:106DB0002091530A3091540A4091550A5091560A35\r
-:106DC0002BA73CA74DA75EA769897A898B899C89E7\r
-:106DD0000E94634E9B01AC010E941252162F072F96\r
-:106DE000782E692E8090570A9090580AA090590AE0\r
-:106DF000B0905A0A6D897E898F89988DA50194017A\r
-:106E00000E94634E9B01AC010E941252B62FA72F25\r
-:106E1000F82FE92FB801C301272F362F492F582FFC\r
-:106E2000CA01B9018D013F01212F302F472D562D69\r
-:106E30000E94644E0E947F522B013C016BA57CA5F1\r
-:106E40008DA59EA520E030E0A9010E9440511816B2\r
-:106E50006CF46BA57CA58DA59EA527E137EB41EDD4\r
-:106E600058E30E94405118167CF10CC06BA57CA51C\r
-:106E70008DA59EA527E137EB41ED58EB0E943D4FD4\r
-:106E800087FD22C0C501B40120E030E0A9010E94C5\r
-:106E9000405118165CF4C501B40127E137EB41ED10\r
-:106EA00058E30E94405118167CF00AC0C501B40195\r
-:106EB00027E137EB41ED58EB0E943D4F87FD04C0C1\r
-:106EC0003E2C2F2CCBA2DFA2C301B2012B962CADFE\r
-:106ED0003DAD4EAD5FAD2B970E9440511816CCF4DE\r
-:106EE0002B966CAD7DAD8EAD9FAD2B97A30192011E\r
-:106EF0000E94444F9B01AC01D101FBA1EFA16B2F7C\r
-:106F0000722D8F2F9E2F0E941252362E272E8BA36A\r
-:106F10009FA36BA97CA98DA99EA920915B0A3091A2\r
-:106F20005C0A40915D0A50915E0A0E94634ED62E23\r
-:106F3000C72EB82E892EE62EF72E082F192FAA2439\r
-:106F4000A39420E030E0A9010E94405118162CF0D3\r
-:106F5000AA24C801B701905804C06D2D7C2D8B2D3B\r
-:106F6000982D2F962CAD3DAD4EAD5FAD2F970E9465\r
-:106F700040511816FCF4AA2021F417FB109517F9BC\r
-:106F800010952F966CAD7DAD8EAD9FAD2F97A8015E\r
-:106F900097010E94444F9B01AC01D101FBA1EFA1DD\r
-:106FA0006B2F722D8F2F9E2F0E941252362E272E5E\r
-:106FB0008BA39FA327966CAD7DAD8EAD9FAD27971C\r
-:106FC00020915F0A3091600A4091610A5091620AF3\r
-:106FD0000E94634ED62EC72EB82E892EE62EF72E8F\r
-:106FE000082F192FAA24A39420E030E0A9010E94C1\r
-:106FF000405118162CF0AA24C801B701905804C0BB\r
-:107000006D2D7C2D8B2D982D63962CAD3DAD4EAD09\r
-:107010005FAD63970E9440511816F4F4AA2021F442\r
-:1070200017FB109517F9109563966CAD7DAD8EAD7D\r
-:107030009FAD6397A80197010E94444F9B01AC014B\r
-:10704000D101FBA1EFA16B2F722D8F2F9E2F0E94DC\r
-:1070500012527B016C0104C0E32CF22CCBA0DFA008\r
-:107060008DE490E049A15AA1489F8001499F100DED\r
-:10707000589F100D112404581A4F8E2D9F2DAC2DA2\r
-:10708000BD2DF80182A793A7A4A7B5A722A933A96C\r
-:1070900044A955A95058CA01B9010E94644ED801AB\r
-:1070A0009E962D913D914D915C91D1970E941252E7\r
-:1070B0009B01AC016BE077ED83E29BE30E94634EA2\r
-:1070C0000E947F52B62E872EA82E992E6E2D7F2DD0\r
-:1070D0008C2D9D2D2B2D382D4A2D592D0E943D4F45\r
-:1070E00087FD04C0EB2CF82CCA2CD92C8DE490E041\r
-:1070F000E9A1FAA1E89F8001E99F100DF89F100D0A\r
-:10710000112404581A4F8E2D9F2DAC2DBD2DF80142\r
-:1071100086A397A3A0A7B1A762A173A184A195A1FB\r
-:107120002B2D382D4A2D592D0E943D4F181634F025\r
-:1071300081E0D801D7968C93D79702C0F80117AA9F\r
-:107140008DE490E029A13AA1289FF001299FF00D3C\r
-:10715000389FF00D1124E458FA4F81E086ABA3E587\r
-:10716000BAE0FE01719680E101900D928150E1F745\r
-:107170008DE490E049A15AA1489F8001499F100DDC\r
-:10718000589F100D112404581A4FD8019296CD9093\r
-:10719000DD90ED90FC909597C0924F0AD092500AE6\r
-:1071A000E092510AF092520A96966D917D918D91DE\r
-:1071B0009C919997A70196010E94444F4B015C0155\r
-:1071C0006DEC7CEC8CE49DE3A70196010E94444F9A\r
-:1071D0006B017C01C801B501A401970186010E94E1\r
-:1071E000CD286496BFAD6497B0934C0A2FA938ADF3\r
-:1071F00049AD5AAD20936C0530936D0540936E05F3\r
-:1072000050936F054BAD5CAD6DAD7EAD4093700599\r
-:1072100050937105609372057093730523966CAD5E\r
-:107220007DAD8EAD9FAD239760937405709375050A\r
-:1072300080937605909377058FA598A9A9A9BAA9F7\r
-:107240008093780590937905A0937A05B0937B0598\r
-:107250000E94CC2CACD1CB5ADF4F0FB6F894DEBFD6\r
-:107260000FBECDBFCF91DF911F910F91FF90EF9097\r
-:10727000DF90CF90BF90AF909F908F907F906F9056\r
-:107280005F904F903F902F900895CF92DF92EF92B2\r
-:10729000FF920F931F93CF93DF938B017A016901C4\r
-:1072A000FC01608171818281938120912005309160\r
-:1072B000210540912205509123050E9412520E94FF\r
-:1072C000E251CCE6D5E060936C0570936D05809338\r
-:1072D0006E0590936F05F8016081718182819381C1\r
-:1072E00020912405309125054091260550912705D0\r
-:1072F0000E9412520E94E2518E010C5F1F4F609358\r
-:107300007005F801718382839383F7016081718135\r
-:1073100082819381209128053091290540912A0589\r
-:1073200050912B050E9412520E94E25128E0E22E59\r
-:10733000F12CEC0EFD1E60937405F70171838283BE\r
-:107340009383F601608171818281938120912C0564\r
-:1073500030912D0540912E0550912F050E9412521B\r
-:107360000E94E251FE013C9660937805718382830E\r
-:107370009383CE01B801A7019F0160D780E090E020\r
-:10738000DC0180934F0A9093500AA093510AB09366\r
-:10739000520A8093530A9093540AA093550AB093CB\r
-:1073A000560A8093570A9093580AA093590AB093AB\r
-:1073B0005A0A80935B0A90935C0AA0935D0AB0938B\r
-:1073C0005E0A80935F0A9093600AA093610AB0936B\r
-:1073D000620ADF91CF911F910F91FF90EF90DF90A4\r
-:1073E000CF900895FC016081718182819381209109\r
-:1073F0002C0530912D0540912E0550912F050E94AE\r
-:1074000012520E94E251609378057093790580933F\r
-:107410007A0590937B0588E795E04CC780934E0AE8\r
-:1074200008958091970A882349F48091990A8823C6\r
-:1074300029F480919B0A882309F4AEC0ECE8FCE0B3\r
-:1074400007C09091C00095FFFCCF8093C600319695\r
-:1074500084918823B1F7EEE9FCE007C09091C00069\r
-:1074600095FFFCCF8093C600319684918823B1F7B5\r
-:107470008091970A882349F1EAE9FCE007C09091DE\r
-:10748000C00095FFFCCF8093C6003196849188237D\r
-:10749000B1F76091650A7091660A8091670A9091D0\r
-:1074A000680A0E94DF4F209120053091210540910C\r
-:1074B0002205509123050E94444FAB01BC018BE093\r
-:1074C00095E022E030E00E9475248091990A88239B\r
-:1074D00049F1E6E9FCE007C09091C00095FFFCCFC0\r
-:1074E0008093C600319684918823B1F76091690A30\r
-:1074F00070916A0A80916B0A90916C0A0E94DF4F2A\r
-:1075000020912405309125054091260550912705AD\r
-:107510000E94444FAB01BC018BE095E022E030E0DB\r
-:107520000E94752480919B0A882349F1E2E9FCE0DE\r
-:1075300007C09091C00095FFFCCF8093C6003196A4\r
-:1075400084918823B1F760916D0A70916E0A8091E1\r
-:107550006F0A9091700A0E94DF4F209128053091A8\r
-:10756000290540912A0550912B050E94444FAB01FB\r
-:10757000BC018BE095E022E030E00E947524809110\r
-:10758000C00085FFFCCF8AE08093C6001092970A66\r
-:107590001092990A10929B0A08951092970A1092DD\r
-:1075A000990A10929B0A08958093FB010895EFE6D3\r
-:1075B000F0E080818260808308951F920F920FB661\r
-:1075C0000F9211242F923F924F925F926F927F926F\r
-:1075D0008F929F92AF92BF92CF92DF92EF92FF92E3\r
-:1075E0000F931F932F933F934F935F936F937F93CB\r
-:1075F0008F939F93AF93BF93EF93FF93DF93CF93BB\r
-:1076000000D000D0CDB7DEB78091630A9091640AB4\r
-:10761000009709F05DC190914C0A80914D0A98172E\r
-:10762000A1F020914D0A30E08DE490E0289FF00118\r
-:10763000299FF00D389FF00D1124E458FA4FDF0117\r
-:10764000A45BBF4F81E08C9302C0E0E0F0E0F093D8\r
-:10765000640AE093630A309709F434C11092A30AD4\r
-:107660001092A40A1092A50A1092A60A34AD25AD74\r
-:107670003093A10A2093A20AC901692F782F27E22B\r
-:107680006131720710F060E177E281E080939C0A3B\r
-:107690006832710510F468E270E06852704038E0BA\r
-:1076A00060307307E0F0872F90E0880F991F880FF4\r
-:1076B000991F84579B4FFC01329645915491AA27FC\r
-:1076C000659F9001649F210D3A1F06942A1F3A1F5F\r
-:1076D0001124FC0145915491421B530B1FC0CB0157\r
-:1076E000969587958C7F8457974FFC0145915491CF\r
-:1076F0000296FC0125913491E62FF0E0E770F070DE\r
-:107700002E9FC0012F9F900D3E9F900D1124E3E00E\r
-:1077100096958795EA95E1F7481B590B4436510534\r
-:10772000A0F4E3EBF1E006C09091C00095FFFCCF20\r
-:107730008093C60081918823B9F78BE095E04AE0F9\r
-:1077400050E00E94B92344E650E0CA01A0E0B0E056\r
-:1077500080939D0A90939E0AA0939F0AB093A00ADB\r
-:107760005093890040938800E091630AF091640A85\r
-:1077700090AD81AD692F782F87E26131780710F0E5\r
-:1077800060E177E281E080939C0A6832710510F431\r
-:1077900068E270E068527040E8E060307E07E0F038\r
-:1077A000872F90E0880F991F880F991F84579B4F50\r
-:1077B000FC01329645915491AA27659F9001649FE0\r
-:1077C000210D3A1F06942A1F3A1F1124FC014591EE\r
-:1077D0005491421B530B1FC0CB01969587958C7F0C\r
-:1077E0008457974FFC01459154910296FC012591D5\r
-:1077F0003491E62FF0E0E770F0702E9FC0012F9FCC\r
-:10780000900D3E9F900D112403E0969587950A9563\r
-:10781000E1F7481B590B44365105A0F4E3EBF1E0C6\r
-:1078200006C09091C00095FFFCCF8093C600819167\r
-:107830008823B9F78BE095E04AE050E00E94B92335\r
-:1078400044E650E05093A80A4093A70AE091630AE7\r
-:10785000F091640A80899189A289B389B695A79528\r
-:1078600097958795B095A095909581959F4FAF4F2F\r
-:10787000BF4F8093810A9093820AA093830AB093AA\r
-:10788000840A8093850A9093860AA093870AB0930E\r
-:10789000880A8093890A90938A0AA0938B0AB093EE\r
-:1078A0008C0A80938D0A90938E0AA0938F0AB093CE\r
-:1078B000900A1092910A1092920A1092930A1092D2\r
-:1078C000940A06C080ED97E0909389008093880029\r
-:1078D000E091630AF091640A309709F43EC480A1F4\r
-:1078E0008093950A80FF37C016988FEF8093F70139\r
-:1078F00023B1217031E0232759F18091960A882322\r
-:1079000039F180819181A281B381181619061A0676\r
-:107910001B06F4F48091710A9091720AA091730A87\r
-:10792000B091740A8093650A9093660AA093670ADF\r
-:10793000B093680A3093970A80899189A289B389A4\r
-:107940008093910A9093920AA093930AB093940A19\r
-:107950002093960A04C0169A81E08093F7018091E3\r
-:10796000950A81FF3BC0149A8FEF8093F80121E0C4\r
-:10797000199B02C020E02FC08091980A882359F1FA\r
-:10798000E091630AF091640A84819581A681B781B0\r
-:10799000181619061A061B06F4F48091750A9091C0\r
-:1079A000760AA091770AB091780A8093690A909339\r
-:1079B0006A0AA0936B0AB0936C0A2093990A808993\r
-:1079C0009189A289B3898093910A9093920AA09396\r
-:1079D000930AB093940A2093980A04C0149881E003\r
-:1079E0008093F8018091950A82FF3BC046988FEF03\r
-:1079F0008093F90121E01A9B02C020E02FC0809102\r
-:107A00009A0A882359F1E091630AF091640A80850B\r
-:107A10009185A285B385181619061A061B06F4F47B\r
-:107A20008091790A90917A0AA0917B0AB0917C0AA0\r
-:107A300080936D0A90936E0AA0936F0AB093700AB8\r
-:107A400020939B0A80899189A289B3898093910AA6\r
-:107A50009093920AA093930AB093940A20939A0A5F\r
-:107A600004C0469A81E08093F9018091950A83FFD2\r
-:107A700003C045988FEF02C0459A81E08093FA01D8\r
-:107A800080919C0A282F30E03A8329832091810A33\r
-:107A90003091820A4091830A5091840A8091850A2C\r
-:107AA0009091860AA091870AB091880AA090890ACD\r
-:107AB000B0908A0AC0908B0AD0908C0A60908D0A90\r
-:107AC00070908E0A80908F0A9090900A1C821B8280\r
-:107AD00035C16091C00067FF19C02090C600E091D9\r
-:107AE0000705F0910805BF016F5F7F4F6F777070DA\r
-:107AF000E0900905F0900A056E157F0539F0E95709\r
-:107B0000FB4F20827093080560930705E091630A9C\r
-:107B1000F091640AE080F180028113812E0D3F1DF7\r
-:107B2000401F511F12161306140615060CF4159A61\r
-:107B3000E091630AF091640AE480F5800681178180\r
-:107B40008E0D9F1DA01FB11F181619061A061B06C1\r
-:107B50000CF4139AE091630AF091640AE084F184D2\r
-:107B600002851385AE0CBF1CC01ED11E1A141B0447\r
-:107B70001C041D040CF4479AE091630AF091640A16\r
-:107B8000E484F584068517856E0C7F1C801E911E8B\r
-:107B900016141704180419040CF4179A1216130675\r
-:107BA000140615061CF5E091630AF091640AE0885A\r
-:107BB000F188028913892E193F09400B510BE0907F\r
-:107BC000710AF090720A0091730A1091740A609120\r
-:107BD000F701E60EF11C011D111DE092710AF092F1\r
-:107BE000720A0093730A1093740A159818161906EE\r
-:107BF0001A061B061CF5E091630AF091640AE088FE\r
-:107C0000F188028913898E199F09A00BB10BE090AE\r
-:107C1000750AF090760A0091770A1091780A6091BF\r
-:107C2000F801E60EF11C011D111DE092750AF0929B\r
-:107C3000760A0093770A1093780A13981A141B0493\r
-:107C40001C041D041CF5E091630AF091640AE088AD\r
-:107C5000F18802891389AE18BF08C00AD10AE090E2\r
-:107C6000790AF0907A0A00917B0A10917C0A60915F\r
-:107C7000F901E60EF11C011D111DE092790AF09246\r
-:107C80007A0A00937B0A10937C0A4798161417040B\r
-:107C9000180419041CF5E091630AF091640AE08865\r
-:107CA000F188028913896E187F08800A910AE09092\r
-:107CB0007D0AF0907E0A00917F0A1091800A6091FF\r
-:107CC000FA01E60EF11C011D111DE0927D0AF092F1\r
-:107CD0007E0A00937F0A1093800A1798E090910A19\r
-:107CE000F090920A0091930A1091940A0894E11C72\r
-:107CF000F11C011D111DE092910AF092920A00936D\r
-:107D0000930A1093940A2090910A3090920A40901E\r
-:107D1000930A5090940A6B817C816F5F7F4F7C83C4\r
-:107D20006B83E091630AF091640AE088F18802892C\r
-:107D300013892E143F044006510640F4EB81FC8168\r
-:107D400069817A81E617F7070CF4C3CE2093810A84\r
-:107D50003093820A4093830A5093840A8093850A61\r
-:107D60009093860AA093870AB093880AA092890A02\r
-:107D7000B0928A0AC0928B0AD0928C0A60928D0AC5\r
-:107D800070928E0A80928F0A9092900A2091910AA6\r
-:107D90003091920A4091930A5091940AE091630ABB\r
-:107DA000F091640A84899589A689B7898217930717\r
-:107DB000A407B50708F4C8C020919D0A30919E0A17\r
-:107DC00040919F0A5091A00A648D758D868D978D84\r
-:107DD000AA27279FB12D389F7001489FF00C479F1D\r
-:107DE000E00CF11C289FB00DE11CFA1E379FB00D6E\r
-:107DF000E11CFA1E469FB00DE11CFA1E369FB10D24\r
-:107E0000EA1EFA1EB695EA1EFA1E112424AD35ADFF\r
-:107E10002E0D3F1D3093A20A2093A10A80AD91AD93\r
-:107E2000A2ADB3AD40E050E082179307A407B507B9\r
-:107E300020F49093A20A8093A10A9091A10A8091C4\r
-:107E4000A20A692F782F87E26131780710F060E18C\r
-:107E500077E281E080939C0A6832710510F468E251\r
-:107E600070E068527040E8E060307E07E0F0872FF5\r
-:107E700090E0880F991F880F991F84579B4FFC0132\r
-:107E8000329625913491AA27639FA001629F410DEC\r
-:107E90005A1F06944A1F5A1F1124FC012591349140\r
-:107EA000241B350B1FC0CB01969587958C7F84577B\r
-:107EB000974FFC01259134910296FC014591549114\r
-:107EC000E62FF0E0E770F0704E9FC0014F9F900DDD\r
-:107ED0005E9F900D1124F3E096958795FA95E1F752\r
-:107EE000281B390B24363105A0F4E3EBF1E006C082\r
-:107EF0009091C00095FFFCCF8093C60081918823AC\r
-:107F0000B9F78BE095E04AE050E00E94B92324E6FF\r
-:107F100030E0309389002093880040E050E0809169\r
-:107F20009D0A90919E0AA0919F0AB091A00A820F8B\r
-:107F3000931FA41FB51F80939D0A90939E0AA09340\r
-:107F40009F0AB093A00AE4C02091910A3091920A4E\r
-:107F50004091930A5091940A808D918DA28DB38D9A\r
-:107F600082179307A407B50708F0CAC02091A30A97\r
-:107F70003091A40A4091A50A5091A60A648D758D8E\r
-:107F8000868D978DAA27279FB12D389F7001489F16\r
-:107F9000F00C479FE00CF11C289FB00DE11CFA1E6D\r
-:107FA000379FB00DE11CFA1E469FB00DE11CFA1E72\r
-:107FB000369FB10DEA1EFA1EB695EA1EFA1E11246E\r
-:107FC0006091A10A7091A20A6E157F0538F4DF0155\r
-:107FD000A05CBF4F6D917C91119702C06E197F0913\r
-:107FE000E05CFF4F80819181A281B3819B0140E0E1\r
-:107FF00050E0281739074A075B0708F4BC01F7E28D\r
-:1080000061317F0710F060E177E281E080939C0AA4\r
-:108010006832710510F468E270E06852704028E040\r
-:1080200060307207E0F0872F90E0880F991F880F6B\r
-:10803000991F84579B4FFC01329625913491AA27B2\r
-:10804000639FA001629F410D5A1F06944A1F5A1F49\r
-:108050001124FC0125913491241B350B1FC0CB0149\r
-:10806000969587958C7F8457974FFC012591349185\r
-:108070000296FC0145915491E62FF0E0E770F07014\r
-:108080004E9FC0014F9F900D5E9F900D112443E0C5\r
-:10809000969587954A95E1F7281B390B24363105CB\r
-:1080A000A0F4E3EBF1E006C09091C00095FFFCCF97\r
-:1080B0008093C60081918823B9F78BE095E04AE070\r
-:1080C00050E00E94B92324E630E0309389002093E9\r
-:1080D000880040E050E08091A30A9091A40AA0910A\r
-:1080E000A50AB091A60A820F931FA41FB51F809303\r
-:1080F000A30A9093A40AA093A50AB093A60A08C065\r
-:108100008091A70A9091A80A909389008093880093\r
-:108110002091910A3091920A4091930A5091940AC9\r
-:10812000E091630AF091640A80899189A289B389F8\r
-:10813000281739074A075B0780F01092640A1092EB\r
-:10814000630A90914C0A80914D0A981731F0809102\r
-:108150004D0A8F5F8F7080934D0A2496DEBFCDBF8E\r
-:10816000CF91DF91FF91EF91BF91AF919F918F914F\r
-:108170007F916F915F914F913F912F911F910F913F\r
-:10818000FF90EF90DF90CF90BF90AF909F908F9037\r
-:108190007F906F905F904F903F902F900F900FBE09\r
-:1081A0000F901F9018950E9A0C9A3E9A3D9A529AEB\r
-:1081B000529A529A529A2098289A2198299A22984B\r
-:1081C0002A9A0D9A0B9A3F9A0F9AA1E8B0E08C91E7\r
-:1081D0008F7E8C938C9188608C93E0E8F0E08081B6\r
-:1081E0008D7F808380818E7F808380818F73808369\r
-:1081F00080818F7C80838C91887F82608C9380E0EB\r
-:1082000090E49093890080938800109285001092EA\r
-:108210008400EFE6F0E080818260808381E0C4D951\r
-:108220007894089590914C0A80914D0A981729F0FE\r
-:1082300092D281E00E946C10F5CF0895CF93DF9326\r
-:10824000EFB7F894EC0188819981AA81BB81809372\r
-:10825000710A9093720AA093730AB093740AEB01A7\r
-:1082600088819981AA81BB818093750A9093760A4F\r
-:10827000A093770AB093780AEA0188819981AA814C\r
-:10828000BB818093790A90937A0AA0937B0AB0937A\r
-:108290007C0AE90188819981AA81BB8180937D0A4A\r
-:1082A00090937E0AA0937F0AB093800AEFBFDF917C\r
-:1082B000CF9108952FB7F894FC0180819181A2811C\r
-:1082C000B38180937D0A90937E0AA0937F0AB09336\r
-:1082D000800A2FBF08959FB7F894E82FF0E0EE0FC3\r
-:1082E000FF1FEE0FFF1FEF58F54F208131814281B4\r
-:1082F00053819FBFB901CA01089594DF5A985A98D3\r
-:108300005A985A98089560E070E08FE793E42091BE\r
-:1083100000023091010240910202509103020E943A\r
-:10832000444F6093D00A7093D10A8093D20A9093FD\r
-:10833000D30A0895FC01EB54F54F808190E0089535\r
-:108340000F931F93CF93DF93EC01062F662359F110\r
-:10835000EDEAFCE007C09091C00095FFFCCF809350\r
-:10836000C600319684918823B1F78BE095E0602FA9\r
-:1083700070E04AE050E00E949C23E9E5FEE007C07F\r
-:108380009091C00095FFFCCF8093C60031968491F8\r
-:108390008823B1F78091C00085FFFCCF8AE08093ED\r
-:1083A000C6000E944310602F70E0660F771FFB012C\r
-:1083B000EF57FD4F80819181009709F45BC06D57A5\r
-:1083C0007D4FFB01A081B18101E037C0A901440FBD\r
-:1083D000551F440F551FFA013296E80FF91F65919A\r
-:1083E00074916C177D0744F5D9011197AA0FBB1F33\r
-:1083F000AA0FBB1FFC01EA0FFB1F259134911296B7\r
-:10840000A80FB91FFD0105911491840F951FFC0160\r
-:10841000A591B491A21BB30BC01BD10BAC9FC001A3\r
-:10842000AD9F900DBC9F900D1124601B710B0E949D\r
-:10843000F752620F731F19C00F5F202F30E02A1709\r
-:108440003B070CF4C3CF2A173B0769F41197AA0F17\r
-:10845000BB1FAA0FBB1FA80FB91FFD0185919491E7\r
-:10846000682F792F02C060E070E020EF3FE3261B09\r
-:10847000370B16C0BE01882777FD8095982F0E9484\r
-:10848000DF4F2FE632E143E050E40E94125220E039\r
-:1084900030E040E851E40E9412520E94AC4F9B0130\r
-:1084A000C901DF91CF911F910F91089520E030E035\r
-:1084B000D9011196AD01440F551F440F551FFA0104\r
-:1084C000E65BF24F65917491681779073CF5D90125\r
-:1084D000AA0FBB1FAA0FBB1FFD01E85BF24F25913E\r
-:1084E0003491A65BB24FFD01A591B491485B524F08\r
-:1084F000FA0145915491421B530BFC01EA1BFB0B03\r
-:108500004E9FC0014F9F900D5E9F900D11246A1BDE\r
-:108510007B0B0E94F752620F731F12C0422F4E5FF7\r
-:108520009D01AC33B10509F0C3CF4D3339F4E8E315\r
-:10853000FEE085919491682F792F02C060E070E091\r
-:1085400020EF3FE3261B370BC90108952F923F927E\r
-:108550004F925F926F927F928F929F92AF92BF9253\r
-:10856000CF92DF92EF92FF920F931F93CF93DF93FF\r
-:108570008C01C62F662359F1EDEAFCE007C090910B\r
-:10858000C00095FFFCCF8093C6003196849188236C\r
-:10859000B1F78BE095E06C2F70E04AE050E00E946C\r
-:1085A0009C23ECE3FEE007C09091C00095FFFCCF58\r
-:1085B0008093C600319684918823B1F78091C000E2\r
-:1085C00085FFFCCF8AE08093C6000E9443106C2F89\r
-:1085D00070E0660F771FFB01EF57FD4F808191819F\r
-:1085E000009709F488C0C0EFDFE3C01BD10B6D57C3\r
-:1085F0007D4FFB0160817181A1E060C09A01220F73\r
-:10860000331F220F331FFC01E20FF31FA590B4901C\r
-:10861000CA15DB050CF051C041505040440F551FA6\r
-:10862000440F551FFA013296E80FF91F0591149176\r
-:10863000480F591FFA01859094902E5F3F4F280FE5\r
-:10864000391FF90165907490B801882777FD8095EE\r
-:10865000982F0E94DF4F1B012C01C819D909BE01B8\r
-:10866000882777FD8095982F0E94DF4F6B017C0152\r
-:10867000601A710AB301882777FD8095982F0E94B0\r
-:10868000DF4F9B01AC01C701B6010E9412527B0172\r
-:108690008C01A818B908B501882777FD8095982F17\r
-:1086A0000E94DF4F9B01AC01C801B7010E94444FFB\r
-:1086B0009B01AC01C201B10134C0AF5F4A2F50E051\r
-:1086C000461757070CF49ACF4617570769F5660FF8\r
-:1086D000771F660F771F62507040680F791FFB018C\r
-:1086E000859194919C01B901882777FD8095982FF9\r
-:1086F0000E94DF4F1DC0B801882777FD8095982F15\r
-:108700000E94DF4F20E030E04AEF5EE30E94125209\r
-:1087100020E030E040E85DE30E94125220E030E0CB\r
-:10872000A9010E94644E04C060E070E080E090E027\r
-:10873000DF91CF911F910F91FF90EF90DF90CF903D\r
-:10874000BF90AF909F908F907F906F905F904F9071\r
-:108750003F902F9008954F925F926F927F928F92E9\r
-:108760009F92AF92BF92CF92DF92EF92FF920F93C0\r
-:108770001F93CF93DF938091B60A882309F4C7C172\r
-:108780008FB7F8941092B60A8FBF8091AD0A90917E\r
-:10879000AE0A60E0DBDE4B015C016091B10A7091D2\r
-:1087A000B20A8091B30A9091B40AA50194010E9483\r
-:1087B000634EEB01182F092F9801862F9D2FA32FB1\r
-:1087C000B22F8093D40A9093D50AA093D60AB0937F\r
-:1087D000D70A6C2F7D2F832F922F20E030E040E2CC\r
-:1087E00051E40E94405118160CF42DC198016C2FD1\r
-:1087F0007D2F832F922F20E030E040E251EC0E9449\r
-:108800003D4F87FD1CC18091D80A882309F009C11A\r
-:1088100098016C2F7D2F832F902F2091FC01309198\r
-:10882000FD014091FE015091FF010E9412522B0167\r
-:108830003C01862F952DA62DB72D8093DD0A9093B0\r
-:10884000DE0AA093DF0AB093E00A98016C2F7D2F17\r
-:10885000832F902F2091D90A3091DA0A4091DB0AB8\r
-:108860005091DC0A0E94644EF62EE72ED82EC92EB7\r
-:108870000091CC0A1091CD0AD091CE0AC091CF0AB6\r
-:10888000A7019601652F742F832F922FFE01202FB1\r
-:10889000312F4F2F5E2F0E943D4F87FFA6C09E01B4\r
-:1088A000802F912FA32FBC2F8093D90A9093DA0A9F\r
-:1088B000A093DB0AB093DC0A602F712F832F9C2FCB\r
-:1088C0002091000230910102409102025091030276\r
-:1088D0000E941252D62FC72F182F092FAE019801D0\r
-:1088E000852F942FA32FB22F8093E10A9093E20A51\r
-:1088F000A093E30AB093E40AC501B4012091E50A0C\r
-:108900003091E60A4091E70A5091E80A0E94634ECE\r
-:108910002091040230910502409106025091070215\r
-:108920000E94125220ED3CEC4CE45DE30E94125296\r
-:108930006B017C016091E90A7091EA0A8091EB0A6F\r
-:108940009091EC0A23E333E343E75FE30E94125282\r
-:108950009B01AC01C701B6010E94644E7B01D82E79\r
-:10896000C92E9601862F9F2DA32FB22F8093E90A3F\r
-:108970009093EA0AA093EB0AB093EC0A8092E50A7E\r
-:108980009092E60AA092E70AB092E80A642D752D4B\r
-:10899000862D972DDE01F8012B2F3A2F4F2F5E2FBA\r
-:1089A0000E94644EF6012E2D3F2D4F2F5E2F0E9408\r
-:1089B000634E8B01D82FC92F9E01712F832F922FC9\r
-:1089C00020E030E0A9010E943D4F87FD44C09E0198\r
-:1089D000602F712F832F922F20E030E04FE753E478\r
-:1089E0000E9440511816DCF531C00091D00A109158\r
-:1089F000D10AD091D20AC091D30AA7019601652F5E\r
-:108A0000742F832F922FFE01202F312F4F2F5E2F97\r
-:108A10000E94405118160CF442CF0F2D1E2DE60176\r
-:108A20003ECF80E090E0DC018093D90A9093DA0A8F\r
-:108A3000A093DB0AB093DC0A1092D80AE9CE81E059\r
-:108A40008093D80A08C081E08093D80A00E010E043\r
-:108A5000DFE7C3E404C000E010E0D0E0C0E08091B4\r
-:108A6000AD0A9091AE0A2091B70A3091B80A281742\r
-:108A700039071CF01092B50A12C020910C023091F7\r
-:108A80000D0282179307B4F79E01602F712F832F79\r
-:108A90009C2F0E94AC4F759567956093B50A0E9414\r
-:108AA000E2202091ED0A3091EE0A4091EF0A5091B8\r
-:108AB000F00A621B730B840B950B683823E1720775\r
-:108AC00020E0820720E0920710F10E94E2206093EC\r
-:108AD000ED0A7093EE0A8093EF0A9093F00A80916A\r
-:108AE000AF0A9091B00A1816190684F420910E026C\r
-:108AF00030910F02821793074CF42091AB0A30910A\r
-:108B0000AC0A8217930714F42C9A01C02C98DF91B9\r
-:108B1000CF911F910F91FF90EF90DF90CF90BF907A\r
-:108B2000AF909F908F907F906F905F904F9008953F\r
-:108B30002F923F924F925F926F927F928F929F926D\r
-:108B4000AF92BF92CF92DF92EF92FF920F931F935B\r
-:108B5000DF93CF93CDB7DEB7E9970FB6F894DEBFBA\r
-:108B60000FBECDBF6D877E878F87988B8FE78093F1\r
-:108B7000B50A0E94E2206B8B7C8B8D8B9E8BE7EC81\r
-:108B8000F1E006C09091C00095FFFCCF8093C60035\r
-:108B900081918823B9F78091C00085FFFCCF8AE0DE\r
-:108BA0008093C6002B893C894D895E892B8F3C8F31\r
-:108BB0004D8F5E8F2F8B388F498F5A8F8FE790E0C4\r
-:108BC000A0E0B0E089839A83AB83BC833FE7432E68\r
-:108BD000512C612C712C11E01A8A198AECE2FFE009\r
-:108BE00094919CA7E7E2FFE0A491ADA7E0E2FFE04B\r
-:108BF000B491BEA7E9E1FFE024912FA7E3E1FFE0F4\r
-:108C0000349138ABEDE0FFE0449149ABE0E0FFE0A8\r
-:108C100054915AABEAEFFEE084918BABE4EFFEE0B7\r
-:108C200094919CABEEEEFEE0A491ADABEDEDFEE0D9\r
-:108C3000B491BEABE7EDFEE024912FAB8091B60A74\r
-:108C4000882309F461C48FB7F8941092B60A8FBFD5\r
-:108C50008091AD0A9091AE0A60E078DC6D837E83EE\r
-:108C60008F8398875F8D48A139A12AA1652F742F22\r
-:108C7000832F922FBD81AE81DF80C8842B2F3A2FA6\r
-:108C80004D2D5C2D0E944051181634F03D813F8FD0\r
-:108C90004E8148A3D9A2CAA26F2D702F8E2D992D77\r
-:108CA000BD81AE81DF80C8842B2F3A2F4D2D5C2DE6\r
-:108CB0000E943D4F87FD04C0FD800E81ED2C9C2C51\r
-:108CC000112309F454C05D814E813F812885652FB1\r
-:108CD000742F832F922FBD85AE85DF84C8882B2FFC\r
-:108CE0003A2F4D2D5C2D0E94405118160CF00CC4EB\r
-:108CF0000E94E2202B8D3C8D4D8D5E8D621B730B8F\r
-:108D0000840B950B693833E1730730E0830730E05B\r
-:108D1000930708F4F9C3D301C20129813A814B8139\r
-:108D20005C81821B930BA40BB50BB595A79597950A\r
-:108D300087958093B50A0E94E2206F8B788F898F88\r
-:108D40009A8FDC01CB012B8D3C8D4D8D5E8D821B6E\r
-:108D5000930BA40BB50B88A799A7AAA7BBA73D8522\r
-:108D60003F8F4E8548A35F8559A388898AA35D817B\r
-:108D70004E813F812885652F742F832F922FBD85CB\r
-:108D8000AE851F85D8882B2F3A2F412F5D2D0E944D\r
-:108D90003D4F87FFB8C30E94E2202F89388D498D4F\r
-:108DA0005A8D621B730B840B950B693833E1730783\r
-:108DB00030E0830730E0930708F4A5C30E94E22067\r
-:108DC0006B8F7C8F8D8F9E8F49895A8941155105F4\r
-:108DD00009F47FC3DC01CB012F89388D498D5A8D71\r
-:108DE000821B930BA40BB50B28A539A54AA55BA53F\r
-:108DF000280F391F4A1F5B1F29873A874B875C87DB\r
-:108E000028A539A54AA55BA5281B390B4A0B5B0B86\r
-:108E1000CA01B90129813A814B815C810E94D852F3\r
-:108E200029853A854B855C850E942C53240D351D80\r
-:108E3000461D571D243131054105510504F1290115\r
-:108E40003A013CEE43165104610471042CF09BEE90\r
-:108E5000492E512C612C712C40E8441651046104B8\r
-:108E60007104DCF08EEF90E0A0E0B0E08419950989\r
-:108E7000A609B70989839A83AB83BC8312C084E1B6\r
-:108E8000482E512C612C712C24E130E040E050E060\r
-:108E900029833A834B835C8304C049825A826B8264\r
-:108EA0007C828CA5ECE2FFE008C09091C00095FFA9\r
-:108EB000FCCF8093C600319684918823B1F78BE074\r
-:108EC00095E0B301A2012AE030E00E946C238DA559\r
-:108ED000E7E2FFE008C09091C00095FFFCCF8093CF\r
-:108EE000C600319684918823B1F78BE095E04981E3\r
-:108EF0005A816B817C812AE030E00E946C238EA530\r
-:108F0000E0E2FFE008C09091C00095FFFCCF8093A5\r
-:108F1000C600319684918823B1F78BE095E04F2D00\r
-:108F2000502F6E2D792D22E030E00E9475248FA500\r
-:108F3000E9E1FFE008C09091C00095FFFCCF80936D\r
-:108F4000C600319684918823B1F78BE095E0FF8DC0\r
-:108F5000E8A139A12AA14F2F5E2F632F722F22E0A3\r
-:108F600030E00E9475248091C00085FFFCCF8AE02C\r
-:108F70008093C60049895A89433051050CF4A9C22F\r
-:108F800069817A818B819C810E94DF4F20E030E0F3\r
-:108F900040E850E40E9412525B016C015F8D48A1D1\r
-:108FA00039A12AA1652F742F832F922F2F2D302FB7\r
-:108FB0004E2D592D88D620ED3FE049E450E40E9423\r
-:108FC000125220E030E040E05FE30E9412529B0129\r
-:108FD000AC01C601B50158D76BA37CA38DA39EA39A\r
-:108FE00069857A858B859C85EAD720E030E04AE761\r
-:108FF00054E44AD7F62ED72EC82EB92E88A9E3E11D\r
-:10900000FFE008C09091C00095FFFCCF8093C600A0\r
-:10901000319684918823B1F78BE095E0FBA1ECA118\r
-:109020003DA12EA14F2F5E2F632F722F22E030E043\r
-:109030000E94752489A9EDE0FFE008C09091C0006E\r
-:1090400095FFFCCF8093C600319684918823B1F7B9\r
-:109050008BE095E04F2D5D2D6C2D7B2D22E030E0D7\r
-:109060000E9475248091C00085FFFCCF8AE0809328\r
-:10907000C6005BA14CA13DA12EA1652F742F832FAB\r
-:10908000922F2AE939E949E15FE30E94125269AF60\r
-:1090900078AF182F092F562F472F9801832F922F23\r
-:1090A000DA01F8012B2F3A2F4F2F5E2F0DD62F2DDF\r
-:1090B0003D2D4C2D5B2DE8D6362E272E89879FA37C\r
-:1090C00059AD48AD9801652F742F832F922F2F2D06\r
-:1090D0003D2D4C2D5B2D0E94125220E030E040E0EF\r
-:1090E0005EE30E941252E62EA72E982E892E8AA9A0\r
-:1090F000E0E0FFE039AD98AD0AC0292F9091C000A3\r
-:1091000095FFFCCF922F8093C600319684918823DF\r
-:10911000A1F78091C00085FFFCCF39AF98AF8AE0FE\r
-:109120008093C6008BA9EAEFFEE039AD98AD0AC086\r
-:10913000292F9091C00095FFFCCF922F8093C600FD\r
-:10914000319684918823A1F739AF98AF8BE095E0F1\r
-:10915000F32FE8AD98014F2F5E2F632F702F22E081\r
-:1091600030E00E9475248091C00085FFFCCF8AE02A\r
-:109170008093C6008CA9E4EFFEE008C09091C00087\r
-:1091800095FFFCCF8093C600319684918823B1F778\r
-:109190008BE095E0F10139852FA14F2F522D632FE0\r
-:1091A000722F22E030E00E9475248091C00085FF7C\r
-:1091B000FCCF8AE08093C6008DA9EEEEFEE008C0E9\r
-:1091C0009091C00095FFFCCF8093C60031968491AA\r
-:1091D0008823B1F78BE095E094014E2D5A2D632F33\r
-:1091E000782D22E030E00E9475248091C00085FF38\r
-:1091F000FCCF8AE08093C6005BA14CA13DA12EA1CB\r
-:10920000652F742F832F922F23EC35EF48EA5EE30E\r
-:109210000E94125269AF78AF182F092F9801832F3F\r
-:10922000922F2F2D3D2D4C2D5B2D2ED6362E272EF9\r
-:1092300089879FA359AD48AD9801652F742F832F5F\r
-:10924000922F2F2D3D2D4C2D5B2D0E94125220E090\r
-:1092500030E040E450E418D6E62EA72E982E892E52\r
-:109260008EA9EDEDFEE039AD98AD0AC0292F9091A1\r
-:10927000C00095FFFCCF922F8093C6003196849159\r
-:109280008823A1F78091C00085FFFCCF39AF98AF4C\r
-:109290008AE08093C6008FA9E7EDFEE039AD98AD76\r
-:1092A0000AC0292F9091C00095FFFCCF922F809388\r
-:1092B000C600319684918823A1F739AF98AF8BE02F\r
-:1092C00095E0F32FE8AD98014F2F5E2F632F702F9D\r
-:1092D00022E030E00E9475248091C00085FFFCCF21\r
-:1092E0008AE08093C600E1EDFEE007C09091C000E7\r
-:1092F00095FFFCCF8093C600319684918823B1F707\r
-:109300008BE095E0F10139852FA14F2F522D632F6E\r
-:10931000722F22E030E00E9475248091C00085FF0A\r
-:10932000FCCF8AE08093C600EBECFEE007C0909192\r
-:10933000C00095FFFCCF8093C600319684918823AE\r
-:10934000B1F78BE095E094014E2D5A2D632F782DC7\r
-:1093500022E030E00E9475248091C00085FFFCCFA0\r
-:109360008AE08093C6005BA14CA13DA12EA1652F90\r
-:10937000742F832F922F2DEC3CEC4CE45EE30E9483\r
-:1093800012526987272E182F092F562F9801832FE5\r
-:10939000922FF801252F322D4F2F5E2F95D42F2D90\r
-:1093A0003D2D4C2D5B2D70D5A62E972E882E392E57\r
-:1093B00059859801652F722D832F922F2F2D3D2DCA\r
-:1093C0004C2D5B2D0E94125220E030E040E450E42E\r
-:1093D0005BD5F62EE72ED82EC92EECEBFEE084915D\r
-:1093E00099850AC0292F9091C00095FFFCCF922F3C\r
-:1093F0008093C600319684918823A1F78091C000A4\r
-:1094000085FFFCCF99878AE08093C600E6EBFEE0FB\r
-:10941000849199850AC0292F9091C00095FFFCCFB7\r
-:10942000922F8093C600319684918823A1F7998763\r
-:109430008BE095E0F98598014F2F522D632F702F07\r
-:1094400022E030E00E9475248091C00085FFFCCFAF\r
-:109450008AE08093C600E0EBFEE007C09091C00078\r
-:1094600095FFFCCF8093C600319684918823B1F795\r
-:109470008BE095E04A2D592D682D732D22E030E0C8\r
-:109480000E9475248091C00085FFFCCF8AE0809304\r
-:10949000C600EAEAFEE007C09091C00095FFFCCF4D\r
-:1094A0008093C600319684918823B1F78BE095E0D4\r
-:1094B000F70196014F2F5E2D632F7C2D22E030E0C7\r
-:1094C0000E9475248091C00085FFFCCF8AE08093C4\r
-:1094D000C60089819A81AB81BC81840D951DA61D32\r
-:1094E000B71DB595A795979587958093B50A298956\r
-:1094F0003A892F5F3F4F3A8B298BFD840E85EF848D\r
-:10950000988811E001C010E05D854E853F8528896F\r
-:10951000652F742F832F922F20E030E040EA51E432\r
-:10952000D3D39B01AC01BD81AE81DF80C8846B2F9A\r
-:109530007A2F8D2D9C2DA4D618166CF5EFE7FEE042\r
-:1095400007C09091C00095FFFCCF8093C600319674\r
-:1095500084918823B1F78091C00085FFFCCF8AE019\r
-:109560008093C600E9960FB6F894DEBF0FBECDBF5C\r
-:10957000CF91DF911F910F91FF90EF90DF90CF90EF\r
-:10958000BF90AF909F908F907F906F905F904F9023\r
-:109590003F902F9008950E94E2202B893C894D89AD\r
-:1095A0005E89621B730B840B950B613D37E073077B\r
-:1095B00030E0830730E0930708F440CB0E94E220BC\r
-:1095C0006B8B7C8B8D8B9E8BE9E7FEE007C09091C7\r
-:1095D000C00095FFFCCF8093C6003196849188230C\r
-:1095E000B1F78091AD0A9091AE0A60E00E94A64268\r
-:1095F000AB01BC018BE095E022E030E00E947524D5\r
-:10960000E5E7FEE007C09091C00095FFFCCF809396\r
-:10961000C600319684918823B1F780E090E00E94E3\r
-:109620009A41BC018BE095E04AE050E00E949C2307\r
-:109630008091C00085FFFCCF8AE08093C600FECAFF\r
-:109640002F923F924F925F926F927F928F929F9252\r
-:10965000AF92BF92CF92DF92EF92FF920F931F9340\r
-:10966000CF93DF93C0EFDFE3C81BD90B80E090E01E\r
-:10967000AC014F5F5F4F9A01220F331F220F331F40\r
-:10968000F901E85BF24FA590B490CA15DB050CF028\r
-:1096900047C0880F991F880F991FFC01E65BF24FA6\r
-:1096A00005911491885B924FFC0185909490265B04\r
-:1096B000324FF90165907490B801882777FD809545\r
-:1096C000982F7DD41B012C01C819D909BE01882708\r
-:1096D00077FD8095982F73D46B017C01601A710A15\r
-:1096E000B301882777FD8095982F69D49B01AC0141\r
-:1096F000C701B60197D67B018C01A818B908B5013E\r
-:10970000882777FD8095982F5AD49B01AC01C8011A\r
-:10971000B701BAD39B01AC01C201B101D5D217C0C8\r
-:10972000282F2E5FCA014C33510509F0A1CF2D33EC\r
-:1097300051F4EAE3FEE065917491882777FD809506\r
-:10974000982F3DD404C060E070E080E090E0DF91AD\r
-:10975000CF911F910F91FF90EF90DF90CF90BF902E\r
-:10976000AF909F908F907F906F905F904F903F90C1\r
-:109770002F90089580E090E0DC018093CC0A9093D4\r
-:10978000CD0AA093CE0AB093CF0A60E070E08FE7D5\r
-:1097900093E4209100023091010240910202509125\r
-:1097A000030272D36093D00A7093D10A8093D20AD5\r
-:1097B0009093D30A239A249A569A87ED80937A003D\r
-:1097C000EEE7F0E01082808181608083808182609A\r
-:1097D000808380818460808380818460808380E84E\r
-:1097E00088BDEEE6F0E08081846080836AEF70E0FF\r
-:1097F00080E090E00E94182185E090E060E00E9407\r
-:10980000A0419093B80A8093B70A83E191E060E0A9\r
-:109810000E94A04190930D0280930C0286E990E093\r
-:109820000E94564290930F0280930E02089508956D\r
-:1098300080E090E060E00E94A04180E090E0DC01E8\r
-:109840008093B10A9093B20AA093B30AB093B40A7A\r
-:1098500080E090E00E9456429093AC0A8093AB0A5D\r
-:109860001092AA0A1092A90A1092B50A83E060E049\r
-:109870000E9424221092AC0A1092AB0A1092B60AEF\r
-:109880001092AE0A1092AD0A1092B70A1092AC0A6A\r
-:109890001092AB0A84E060E00C942422CF93C82F8E\r
-:1098A000E82FF0E0EE0FFF1FE158FD4F808160E0F0\r
-:1098B0000E9424220E949520882379F5EDEAFCE09D\r
-:1098C00007C09091C00095FFFCCF8093C6003196F1\r
-:1098D00084918823B1F78BE095E06C2F40E050E055\r
-:1098E0000E9466238091C00085FFFCCF8AE08093B0\r
-:1098F000C600EBE1FDE007C09091C00095FFFCCFF2\r
-:109900008093C600319684918823B1F78091C0007E\r
-:1099100085FFFCCF8AE08093C600CF910895CF9356\r
-:10992000C82FE82FF0E0EE0FFF1FE158FD4F8081B8\r
-:1099300060E00E9424220E949520882379F5EDEAB8\r
-:10994000FCE007C09091C00095FFFCCF8093C6005B\r
-:10995000319684918823B1F78BE095E06C2F40E03D\r
-:1099600050E00E9466238091C00085FFFCCF8AE012\r
-:109970008093C600EEEEFCE007C09091C00095FF1A\r
-:10998000FCCF8093C600319684918823B1F78091F3\r
-:10999000C00085FFFCCF8AE08093C600CF91089578\r
-:1099A00084E060E00E9424220E949520882309F52B\r
-:1099B000EDEAFCE007C09091C00095FFFCCF8093DA\r
-:1099C000C600319684918823B1F7E4EBFCE007C030\r
-:1099D0009091C00095FFFCCF8093C6003196849192\r
-:1099E0008823B1F78091C00085FFFCCF8AE0809387\r
-:1099F000C60008951F920F920FB60F9211242F9355\r
-:109A00003F934F935F936F937F938F939F93AF9306\r
-:109A1000BF93EF93FF9380911002882331F49091CC\r
-:109A2000B50A9093B90A91112B9A9091B90A8917A6\r
-:109A300008F02B988F5F8F77809310028091BA0A7D\r
-:109A4000833009F448C0843028F48130E1F082305A\r
-:109A5000C0F50DC0853009F466C0853008F457C0E4\r
-:109A6000863009F47CC0873009F0A6C084C010920B\r
-:109A70007B0080E480937C0080917A0080648093F6\r
-:109A80007A0081E01BC0209178003091790040E09D\r
-:109A900050E08091C70A9091C80AA091C90AB0917C\r
-:109AA000CA0A820F931FA41FB51F8093C70A909301\r
-:109AB000C80AA093C90AB093CA0A82E08093BA0A7E\r
-:109AC0007BC082E480937C0080917A0080648093E4\r
-:109AD0007A0083E0F3CF209178003091790040E064\r
-:109AE00050E08091BB0A9091BC0AA091BD0AB09150\r
-:109AF000BE0A820F931FA41FB51F8093BB0A9093C9\r
-:109B0000BC0AA093BD0AB093BE0A84E0D7CF1092DE\r
-:109B10007B0081E480937C0080917A008064809354\r
-:109B20007A0085E0CBCF209178003091790040E039\r
-:109B300050E08091C30A9091C40AA091C50AB091E7\r
-:109B4000C60A820F931FA41FB51F8093C30A909368\r
-:109B5000C40AA093C50AB093C60A86E0AFCF10929C\r
-:109B60007B0082E480937C0080917A008064809303\r
-:109B70007A0087E0A3CF209178003091790040E00F\r
-:109B800050E08091BF0A9091C00AA091C10AB091A3\r
-:109B9000C20A820F931FA41FB51F8093BF0A909320\r
-:109BA000C00AA093C10AB093C20A1092BA0A809167\r
-:109BB000CB0A8F5F8093CB0A8091CB0A803108F467\r
-:109BC00071C02FEF3FE38091C70A9091C80AA901A5\r
-:109BD000481B590BCA015093AE0A4093AD0A4091FD\r
-:109BE000BB0A5091BC0A241B350B3093B00A20935A\r
-:109BF000AF0A21E02093B60A1092CB0A1092C70A4E\r
-:109C00001092C80A1092C90A1092CA0A1092C30A86\r
-:109C10001092C40A1092C50A1092C60A1092BF0A86\r
-:109C20001092C00A1092C10A1092C20A1092BB0A86\r
-:109C30001092BC0A1092BD0A1092BE0A20910C022A\r
-:109C400030910D028217930744F01092AA0A1092E5\r
-:109C5000A90A80E023DE0E945A202091AD0A3091AB\r
-:109C6000AE0A8091B70A9091B80A8217930744F020\r
-:109C70001092AA0A1092A90A80E051DE0E945A208E\r
-:109C80002091AF0A3091B00A80910E0290910F029C\r
-:109C9000281739073CF01092AC0A1092AB0A80DE0C\r
-:109CA0000E945A20FF91EF91BF91AF919F918F91A8\r
-:109CB0007F916F915F914F913F912F910F900FBEC8\r
-:109CC0000F901F9018955058BB27AA270ED076C228\r
-:109CD0003FD230F044D220F031F49F3F11F41EF413\r
-:109CE0000FC20EF4E095E7FBDCC1E92F89D280F3C7\r
-:109CF000BA17620773078407950718F071F49EF589\r
-:109D0000B8C20EF4E0950B2EBA2FA02D0B01B901AD\r
-:109D100090010C01CA01A0011124FF27591B99F0E1\r
-:109D2000593F50F4503E68F11A16F040A22F232FED\r
-:109D3000342F4427585FF3CF469537952795A7953D\r
-:109D4000F0405395C9F77EF41F16BA0B620B730BE4\r
-:109D5000840BBAF09150A1F0FF0FBB1F661F771F55\r
-:109D6000881FC2F70EC0BA0F621F731F841F48F40A\r
-:109D7000879577956795B795F7959E3F08F0B3CF90\r
-:109D80009395880F08F09927EE0F9795879508957A\r
-:109D9000DFD158F080E891E009F49EEFE0D128F09F\r
-:109DA00040E851E059F45EEF09C0AAC162C2E92F50\r
-:109DB000E07826D268F3092E052AC1F32617370763\r
-:109DC0004807590738F00E2E07F8E02569F0E0251E\r
-:109DD000E0640AC0EF6307F8009407FADB01B901F9\r
-:109DE0009D01DC01CA01AD01EF935DD0E7D10AD03E\r
-:109DF0005F91552331F02BED3FE049E450FD49ECF4\r
-:109E000063CF0895DF93DD27B92FBF7740E85FE385\r
-:109E10001616170648075B0710F4D92F96D29F93A2\r
-:109E20008F937F936F93A9D3E0E7F0E06CD1C6D115\r
-:109E30002F913F914F915F9101D3DD2349F09058CD\r
-:109E4000A2EA2AED3FE049EC5FE3D0785D274DDFE1\r
-:109E5000DF91B4C1F7D180F09F3740F491110EF437\r
-:109E600009C260E070E080E89FE3089526F01B16C9\r
-:109E7000611D711D811D1BC135C1EFD008F481E04A\r
-:109E8000089575D1E395ABC10CD098C168D140F06D\r
-:109E90005FD130F021F45F3F19F003C15111EAC1E5\r
-:109EA0002FC1AED198F39923C9F35523B1F3951B74\r
-:109EB000550BBB27AA2762177307840738F09F5FEB\r
-:109EC0005F4F220F331F441FAA1FA9F333D00E2E5A\r
-:109ED0003AF0E0E830D091505040E695001CCAF7C7\r
-:109EE00029D0FE2F27D0660F771F881FBB1F26178C\r
-:109EF00037074807AB07B0E809F0BB0B802DBF015F\r
-:109F0000FF2793585F4F2AF09E3F510568F0C9C064\r
-:109F1000B1C15F3FECF3983EDCF38695779567958A\r
-:109F2000B795F7959F5FC9F7880F911D969587950F\r
-:109F300097F90895E1E0660F771F881FBB1F62172E\r
-:109F400073078407BA0720F0621B730B840BBA0BEC\r
-:109F5000EE1F88F7E095089504D06894B1118AC186\r
-:109F6000089556D188F09F5790F0B92F9927B7518F\r
-:109F7000A0F0D1F0660F771F881F991F1AF0BA95CD\r
-:109F8000C9F712C0B13081F074D1B1E0089571C148\r
-:109F9000672F782F8827B85F39F0B93FCCF38695C3\r
-:109FA00077956795B395D9F73EF490958095709520\r
-:109FB00061957F4F8F4F9F4F0895E89409C097FB9D\r
-:109FC0003EF490958095709561957F4F8F4F9F4F90\r
-:109FD0009923A9F0F92F96E9BB279395F6958795D4\r
-:109FE00077956795B795F111F8CFFAF4BB0F11F497\r
-:109FF00060FF1BC06F5F7F4F8F4F9F4F16C088233E\r
-:10A0000011F096E911C0772321F09EE8872F762F73\r
-:10A0100005C0662371F096E8862F70E060E02AF0B4\r
-:10A020009A95660F771F881FDAF7880F96958795A0\r
-:10A0300097F9089507D180F09F3740F491110EF001\r
-:10A0400019C160E070E080E89FEB089526F41B16CC\r
-:10A05000611D711D811D2BC045C0990F0008550F52\r
-:10A06000AA0BE0E8FEEF16161706E807F907C0F09E\r
-:10A0700012161306E407F50798F0621B730B840BA6\r
-:10A08000950B39F40A2661F0232B242B252B21F480\r
-:10A0900008950A2609F4A140A6958FEF811D811D20\r
-:10A0A000089597F99F6780E870E060E0089588233D\r
-:10A0B00071F4772321F09850872B762F07C0662301\r
-:10A0C00011F499270DC09051862B70E060E02AF0C2\r
-:10A0D0009A95660F771F881FDAF7880F96958795F0\r
-:10A0E00097F908959F3F31F0915020F48795779527\r
-:10A0F0006795B795880F911D9695879597F908955F\r
-:10A100009FEF80EC0895DF93CF931F930F93FF92FF\r
-:10A11000EF92DF927B018C01689405C0DA2EEF018B\r
-:10A120008DD1FE01E894A5912591359145915591E8\r
-:10A13000AEF3EF01DADDFE019701A801DA9479F7B9\r
-:10A14000DF90EF90FF900F911F91CF91DF910895D5\r
-:10A1500000240A9416161706180609060895002406\r
-:10A160000A9412161306140605060895C9CF50D096\r
-:10A17000E8F3E894E0E0BB279F57F0F02AED3FE0DA\r
-:10A1800049EC06C0EE0FBB0F661F771F881F28F033\r
-:10A19000B23A62077307840728F0B25A620B730B56\r
-:10A1A000840BE3959A9572F7803830F49A95BB0F3B\r
-:10A1B000661F771F881FD2F7904896CF092E039409\r
-:10A1C000000C11F4882352F0BB0F40F4BF2B11F4A4\r
-:10A1D00060FF04C06F5F7F4F8F4F9F4F0895EF93D5\r
-:10A1E000E0FF06C0A2EA2AED3FE049EC5FEB7DDD2F\r
-:10A1F000E5DF0F90039401FC9058EDE9F0E0C7C152\r
-:10A2000057FD9058440F551F59F05F3F71F0479527\r
-:10A21000880F97FB991F61F09F3F79F0879508950C\r
-:10A22000121613061406551FF2CF4695F1DF08C02B\r
-:10A23000161617061806991FF1CF86957105610548\r
-:10A2400008940895E5DFA0F0BEE7B91788F4BB27AE\r
-:10A250009F3860F41616B11D672F782F8827985FF6\r
-:10A26000F7CF869577956795B11D93959639C8F385\r
-:10A270000895E894BB2766277727CB0197F90895BF\r
-:10A28000ECDE08F48FEF089563DF19F068DF09F062\r
-:10A2900037CF07CFB901CA0125CF9F775F77B0DFEE\r
-:10A2A00098F39923B9F35523B9F3FF27951758F479\r
-:10A2B000E52FE91BED3070F75E3B10F0F1E41CC0B8\r
-:10A2C0009034E0F40AC0E92FE51BED3028F79E3BFF\r
-:10A2D00010F0F1E411C0503488F4F9EA88232AF030\r
-:10A2E0009A95660F771F881FDAF744232AF05A954C\r
-:10A2F000220F331F441FDAF79F1B5F1BFF931F932F\r
-:10A300000F93FF92EF9279018A01BB27AB2F9B013C\r
-:10A31000AC0196D09701A801BF937B018C01AA27BD\r
-:10A32000BA2FB901CA018CD0AF919701A801EF9063\r
-:10A33000FF900F911F91D9DC41DFE1D04F9140FF99\r
-:10A340000895552747FD509509C09B01AC0160E079\r
-:10A3500070E080E89FE398CDA4CEC4CE59DFE8F347\r
-:10A360009923D9F3940F511DBBF39150504094F0B1\r
-:10A3700059F0882332F0660F771F881F91505040A4\r
-:10A38000C1F79E3F510544F7880F911D969587951B\r
-:10A3900097F908955F3FACF0983E9CF0BB278695F7\r
-:10A3A00077956795B79508F4B1609395C1F7BB0FA2\r
-:10A3B00058F711F460FFE8CF6F5F7F4F8F4F9F4FCB\r
-:10A3C000E3CF58CF25DF58F19E5758F19851A0F0B0\r
-:10A3D000E9F0983020F5092E9927660F771F881F1E\r
-:10A3E000991F0A94D1F712C0062E672F782F88275D\r
-:10A3F000985F11F4000C07C0993FB4F386957795E8\r
-:10A4000067959395D9F7611D711D811D3EF4909557\r
-:10A410008095709561957F4F8F4F9F4F08956894F9\r
-:10A4200029CF27CF0BD0CACE93DE28F098DE18F0C4\r
-:10A43000952309F036CE64CE11241CCFE1DEA0F3C3\r
-:10A44000959FD1F3950F50E0551F629FF001729FC9\r
-:10A45000BB27F00DB11D639FAA27F00DB11DAA1FE8\r
-:10A46000649F6627B00DA11D661F829F2227B00D35\r
-:10A47000A11D621F739FB00DA11D621F839FA00DC0\r
-:10A48000611D221F749F3327A00D611D231F849F10\r
-:10A49000600D211D822F762F6A2F11249F57504067\r
-:10A4A0008AF0E1F088234AF0EE0FFF1FBB1F661F02\r
-:10A4B000771F881F91505040A9F79E3F510570F0BB\r
-:10A4C000F0CDD8CE5F3FECF3983EDCF386957795E0\r
-:10A4D0006795B795F795E7959F5FC1F7FE2B880FB6\r
-:10A4E000911D9695879597F908959F9340DE0F905B\r
-:10A4F00007FCEE5F74CE11F40EF402CEF3CD88DECD\r
-:10A50000D0F39923D9F3CEF39F57550B87FF38D05B\r
-:10A510000024A0E640EA900180585695979528F4CB\r
-:10A52000805C660F771F881F20F0261737074807C3\r
-:10A5300030F4621B730B840B202931294A2BA6951A\r
-:10A5400017940794202531254A2758F7660F771F5F\r
-:10A55000881F20F026173707480730F4620B730B6B\r
-:10A56000840B200D311D411DA09581F7B901842F69\r
-:10A570009158880F9695879508959B01AC0152CF0D\r
-:10A5800091505040660F771F881FD2F708959F9310\r
-:10A590008F937F936F93FF93EF939B01AC0142DF07\r
-:10A5A000EF91FF91B0DD2F913F914F915F913ACFA5\r
-:10A5B000629FD001739FF001829FE00DF11D649FA7\r
-:10A5C000E00DF11D929FF00D839FF00D749FF00D33\r
-:10A5D000659FF00D9927729FB00DE11DF91F639FD4\r
-:10A5E000B00DE11DF91FBD01CF011124089597FBA6\r
-:10A5F000092E07260AD077FD04D049D006D00020C6\r
-:10A600001AF4709561957F4F0895F6F790958195AE\r
-:10A610009F4F0895A1E21A2EAA1BBB1BFD010DC07E\r
-:10A62000AA1FBB1FEE1FFF1FA217B307E407F50702\r
-:10A6300020F0A21BB30BE40BF50B661F771F881FDE\r
-:10A64000991F1A9469F760957095809590959B0174\r
-:10A65000AC01BD01CF01089597FB092E05260ED050\r
-:10A6600057FD04D0D7DF0AD0001C38F45095409530\r
-:10A67000309521953F4F4F4F5F4F0895F6F79095D6\r
-:10A680008095709561957F4F8F4F9F4F0895AA1BBE\r
-:10A69000BB1B51E107C0AA1FBB1FA617B70710F0CD\r
-:10A6A000A61BB70B881F991F5A95A9F780959095FF\r
-:10A6B000BC01CD010895EE0FFF1F0590F491E02D30\r
-:10A6C0000994A1E0B0E0E6E6F3E576C55B0161152B\r
-:10A6D000710521F0DB018C9311969C93482F592F23\r
-:10A6E0006A01F601E1906F018F018E2D90E080D21A\r
-:10A6F0000097B9F7FE2DFD3229F4D601ED908D01BA\r
-:10A7000021E007C0BE2DBB3219F4F601E1908F01A4\r
-:10A7100020E068010894C108D108C60163EA7FE01F\r
-:10A7200043E050E029836CD22981009709F572E05B\r
-:10A73000E72EF12CE00EF11EC70166EA7FE045E04E\r
-:10A7400050E05ED22981009729F467E0E62EF12CD3\r
-:10A75000E00EF11EA114B10421F0D5011196FC9276\r
-:10A76000EE9220FF0AC130E020E090E88FEF0DC1AB\r
-:10A77000C6016BEA7FE043E050E0298341D22981A2\r
-:10A78000009731F060E070E0CB01662477240AC0C6\r
-:10A79000A114B10409F4F5C00E5F1F4FF501118338\r
-:10A7A0000083EFC03E2D30533A30A0F52260E22FF7\r
-:10A7B000F0E0AF014870507022FF07C0411551050D\r
-:10A7C00071F50894611C711C2AC04115510519F0DE\r
-:10A7D0000894610871086B017C0152E0CC0CDD1C0F\r
-:10A7E000EE1CFF1C5A95D1F76C0D7D1D8E1D9F1D13\r
-:10A7F000660F771F881F991F630F711D811D911DA3\r
-:10A800006839F9E97F07F9E98F07F9E19F0738F01F\r
-:10A81000246005C03E3F39F423FD3FC02860D801C5\r
-:10A82000ED908D01BFCF353311F03531B1F5F80121\r
-:10A8300031913D3211F4206102C03B3241F4D80124\r
-:10A8400011963C911197319642E050E002C041E0F0\r
-:10A8500050E030533A3020F08F01041B150B1DC01F\r
-:10A8600040E050E0BCE040385B075CF4DA01AA0F3E\r
-:10A87000BB1FAA0FBB1F4A0F5B1F440F551F430F7F\r
-:10A88000511D319130538F013A3060F324FF03C0E2\r
-:10A89000509541955F4F640E751EC22EDD2421FF39\r
-:10A8A00008C0A114B10429F001501040F501118332\r
-:10A8B000008383DB7B018C01F3E0CF22DD2433E0D6\r
-:10A8C000C316D10421F417FB109517F91095C80190\r
-:10A8D000B70120E030E0A901D0DA882309F448C0AC\r
-:10A8E00077FE09C042ECC42E4FE0D42E70946194E0\r
-:10A8F0007108739404C03AEDC32E3FE0D32E26E0D6\r
-:10A90000822E912C90E2A92EB12C0EC0F601259139\r
-:10A91000359145915491C801B70184DDE62EF72E9B\r
-:10A92000082F192F6A187B086A147B047CF7B594EA\r
-:10A93000A7940894810891088114910429F08CEF60\r
-:10A940009FEFC80ED91EF0CFB701C801282F220FE4\r
-:10A95000292F221F2F3F31F020E030E0A9018DDAAE\r
-:10A96000882331F482E290E09093F60A8093F50A0E\r
-:10A970003E2D2F2D902F812F08C030E020E090E851\r
-:10A9800003C030E020E090EC8FE7F901AC016F2FBD\r
-:10A99000722F852F942F2196EEE02AC42F923F929A\r
-:10A9A0004F925F927F928F929F92AF92BF92CF927F\r
-:10A9B000DF92EF92FF920F931F93CF93DF934B01A0\r
-:10A9C000EA016115710519F0FB01808391832097DD\r
-:10A9D00039F09E01225030402332310508F0F1C099\r
-:10A9E000A82EB92EF50111915F017F01812F90E012\r
-:10A9F000FFD00097B9F71D3229F4F50111917F01BD\r
-:10AA000001E006C01B3219F4F50111917F0100E04D\r
-:10AA1000209719F0C031D105B9F4103381F4F70152\r
-:10AA20008081883711F0883551F4F701118182E077\r
-:10AA300090E0E80EF91E0260C0E1D0E005C020976A\r
-:10AA400019F41033C1F422C0C830D105F9F0C9306F\r
-:10AA5000D10524F4C230D10509F507C0CA30D105AB\r
-:10AA600051F0C031D105D1F426C0A12CB12CC12C9C\r
-:10AA7000F0E4DF2E25C0CAE0D0E0ECECAE2EECEC2A\r
-:10AA8000BE2EECECCE2EECE0DE2E1AC0C8E0D0E0FC\r
-:10AA9000A12CB12CC12C70E1D72E12C09E014427ED\r
-:10AAA00037FD4095542F60E070E080E090E8B2DD23\r
-:10AAB00059016A0105C0A12CB12CC12C68E0D62E29\r
-:10AAC00040E060E070E0CB011E01442437FC40947C\r
-:10AAD000542C50ED752E710EE72DEA3070F0212FB9\r
-:10AAE00021542A3118F439EC732E06C0212F215637\r
-:10AAF0002A3128F529EA722E710E272D30E02C1705\r
-:10AB00003D07ECF447FD17C0A616B706C806D906E0\r
-:10AB100078F0A20191014CDD670D711D811D911D21\r
-:10AB20006130F0E07F07F0E08F07F0E89F0710F05A\r
-:10AB30004FEF01C041E0F70111917F01CACF8114AD\r
-:10AB4000910491F0442339F00894E108F108F401EC\r
-:10AB5000F182E08209C001FF1BC097012250304002\r
-:10AB6000F4013183208314C047FF12C000FF05C0E9\r
-:10AB700060E070E080E090E804C06FEF7FEF8FEF5F\r
-:10AB80009FE722E230E03093F60A2093F50A16C0E0\r
-:10AB900000FF08C090958095709561957F4F8F4F0D\r
-:10ABA0009F4F0CC097FF0AC082E290E09093F60A94\r
-:10ABB0008093F50A6FEF7FEF8FEF9FE79B01AC016A\r
-:10ABC00003C020E030E0A901B901CA01DF91CF91B3\r
-:10ABD0001F910F91FF90EF90DF90CF90BF90AF90BB\r
-:10ABE0009F908F907F905F904F903F902F9008950F\r
-:10ABF00091113BC2803219F089508550D0F70895E9\r
-:10AC0000FB01DC014150504088F08D9181341CF0F3\r
-:10AC10008B350CF4805E659161341CF06B350CF45F\r
-:10AC2000605E861B611171F3990B0895881BFCCF40\r
-:10AC3000FC018191861721F08823D9F7992708957F\r
-:10AC40003197CF010895FB0151915523A9F0BF0120\r
-:10AC5000DC014D9145174111E1F759F4CD01019007\r
-:10AC6000002049F04D9140154111C9F3FB014111FC\r
-:10AC7000EFCF81E090E001970895AEE0B0E0E2E42C\r
-:10AC8000F6E5A4C20D891E8986E08C831A830983A8\r
-:10AC90008FEF9FE79E838D839E01275E3F4FCE01FE\r
-:10ACA00001966F89788DA90108D0EF81F885E00FB2\r
-:10ACB000F11F10822E96E4E0A5C2ACE0B0E0E2E61F\r
-:10ACC000F6E576C26C011B018A01FC01178216822F\r
-:10ACD000838181FFC4C12E010894411C511CF601DF\r
-:10ACE0009381F10193FD859193FF81911F01882349\r
-:10ACF00009F4B1C1853239F493FD859193FF8191B7\r
-:10AD00001F01853221F490E0B601C8D1E8CFEE24CE\r
-:10AD1000FF2420E02032B0F48B3269F08C3228F42A\r
-:10AD2000803251F0833271F40BC08D3239F08033B0\r
-:10AD300049F421602CC02260246029C0286027C00B\r
-:10AD4000206125C027FD2CC0382F30533A3098F4AD\r
-:10AD500026FF08C08E2D880FE82EEE0CEE0CE80EB4\r
-:10AD6000E30E15C08F2D880FF82EFF0CFF0CF80E88\r
-:10AD7000F30E20620CC08E3221F426FD6CC12064DB\r
-:10AD800006C08C3611F4206802C0883649F4F101FF\r
-:10AD900093FD859193FF81911F01882309F0BACF1C\r
-:10ADA000982F9554933018F09052933028F40C5FFC\r
-:10ADB0001F4FFFE3F9830DC0833631F0833771F005\r
-:10ADC000833509F05CC021C0F801808189830E5F62\r
-:10ADD0001F4F420171E0A72EB12C15C062E0662E14\r
-:10ADE000712C600E711EF8018080918026FF03C0D7\r
-:10ADF0006E2D70E002C06FEF7FEFC4012C8743D14E\r
-:10AE00005C0183012C852F7716C052E0652E712CD2\r
-:10AE1000600E711EF8018080918026FF03C06E2DA8\r
-:10AE200070E002C06FEF7FEFC4012C8721D15C017D\r
-:10AE30002C852068830123FD1EC007C080E290E0BE\r
-:10AE4000B6012C872BD1FA942C858F2D90E0A81673\r
-:10AE5000B906A0F310C0F40127FD859127FF819169\r
-:10AE60004F0190E0B6012C8719D12C85F110FA948E\r
-:10AE70000894A108B108A114B10469F7E9C08436A7\r
-:10AE800011F0893641F527FF08C0F8016081718112\r
-:10AE9000828193810C5F1F4F09C0F801608171812D\r
-:10AEA000882777FD8095982F0E5F1F4F4FE6B42EB1\r
-:10AEB000B22297FF09C090958095709561957F4F5C\r
-:10AEC0008F4F9F4FF0E8BF2AA2012AE030E012D155\r
-:10AED000782E741844C0853731F43FEEB32EB22279\r
-:10AEE0002AE030E025C099EFB92EB2228F36C1F0AA\r
-:10AEF000803720F4883509F0AEC00DC0803721F0CE\r
-:10AF0000883709F0A8C002C020E1B22AB4FE0BC005\r
-:10AF100084E0B82A08C0B4FE09C0E6E0BE2A06C034\r
-:10AF200028E030E005C020E130E002C020E132E05E\r
-:10AF3000B7FE08C0F80160817181828193810C5F46\r
-:10AF40001F4F07C0F8016081718180E090E00E5FC3\r
-:10AF50001F4FA201CFD0782E7418FFE7BF22B6FE94\r
-:10AF60000BC02EEFB2227E1438F4B4FE07C0B2FC40\r
-:10AF700005C08FEEB82202C0A72C01C0AE2C8B2DCD\r
-:10AF800090E0B4FE0DC0FE01E70DF11D20812033DD\r
-:10AF900019F4E9EEBE2209C0A394B2FE06C004C0B3\r
-:10AFA00086789070009709F0A3948B2C9924B3FCB9\r
-:10AFB00013C0B0FE0EC0AF1428F4E72CEF0CEA1853\r
-:10AFC000AF2C07C0E72C05C080E290E0B60166D048\r
-:10AFD000A394AF14C8F304C0AF1410F4FA1801C05E\r
-:10AFE000FF2484FE0EC080E390E0B60157D082FEBD\r
-:10AFF0001DC081FE03C088E590E010C088E790E0A6\r
-:10B000000DC0C40186789070009781F081FC02C069\r
-:10B0100080E201C08BE2B7FC8DE290E0B6013ED049\r
-:10B0200005C080E390E0B60139D0EA947E14C8F3FD\r
-:10B030007A94F201E70DF11D808190E0B6012ED0E7\r
-:10B040007720B1F705C080E290E0B60127D0FA94EE\r
-:10B05000FF20C9F744CEF6012681378102C02FEFC9\r
-:10B060003FEFC9012C96E2E1BFC0992788270895D8\r
-:10B07000FC010590615070400110D8F780959095C3\r
-:10B080008E0F9F1F0895FC016150704001900110C8\r
-:10B09000D8F7809590958E0F9F1F08950F931F935B\r
-:10B0A000CF93DF938C01EB018B8181FF1BC082FF6B\r
-:10B0B0000DC02E813F818C819D812817390764F452\r
-:10B0C000E881F9810193F983E88306C0E885F98571\r
-:10B0D000802F0995009731F48E819F8101969F837F\r
-:10B0E0008E8302C00FEF1FEFC801DF91CF911F9138\r
-:10B0F0000F910895FA01AA27283051F1203181F1EA\r
-:10B10000E8946F936E7F6E5F7F4F8F4F9F4FAF4F6F\r
-:10B11000B1E03ED0B4E03CD0670F781F891F9A1F82\r
-:10B12000A11D680F791F8A1F911DA11D6A0F711D36\r
-:10B13000811D911DA11D20D009F468943F912AE042\r
-:10B14000269F11243019305D3193DEF6CF0108952A\r
-:10B15000462F4770405D4193B3E00FD0C9F7F6CF5B\r
-:10B16000462F4F70405D4A3318F0495D31FD405223\r
-:10B17000419302D0A9F7EACFB4E0A69597958795B9\r
-:10B1800077956795BA95C9F7009761057105089598\r
-:10B190009B01AC010A2E0694579547953795279544\r
-:10B1A000BA95C9F7620F731F841F951FA01D0895DC\r
-:10B1B0002F923F924F925F926F927F928F929F92C7\r
-:10B1C000AF92BF92CF92DF92EF92FF920F931F93B5\r
-:10B1D000CF93DF93CDB7DEB7CA1BDB0B0FB6F89466\r
-:10B1E000DEBF0FBECDBF09942A88398848885F84A6\r
-:10B1F0006E847D848C849B84AA84B984C884DF8017\r
-:10B20000EE80FD800C811B81AA81B981CE0FD11DFA\r
-:10B210000FB6F894DEBF0FBECDBFED010895F894D0\r
-:02B22000FFCF5E\r
-:10B222005573696E672044656661756C7420736539\r
-:10B232007474696E67733A004D31313000482000F2\r
-:10B242004C20002569206D696E2C202569207365CC\r
-:10B2520063004D31303420496E76616C696420653B\r
-:10B262007874727564657220004D31303520496EF4\r
-:10B2720076616C6964206578747275646572200009\r
-:10B282004D31303920496E76616C6964206578747D\r
-:10B29200727564657220003F006F6B0020703A0087\r
-:10B2A20020693A0020643A0020633A005400496E53\r
-:10B2B20076616C69642065787472756465720041A8\r
-:10B2C20063746976652045787472756465723A2094\r
-:10B2D200002E00537465707261746520746F20686B\r
-:10B2E200696768203A2000504944204175746F74A0\r
-:10B2F200756E652073746172740000803B45008036\r
-:10B302003B4500007043000000006400640060EAF6\r
-:10B3120000000080BB44010101010101713DE841CF\r
-:10B32200A97E443E756089440000803FFF3FFF3F95\r
-:10B332000158595A45000001001A0019000A00007C\r
-:10B3420000FFFF1C001B000A000100FFFF17001690\r
-:10B35200000A000200FFFFFFFFFFFF04000E0018BB\r
-:10B362000015000A0003000000010002000200288C\r
-:10B3720023000028230000640000001027000000C2\r
-:10B3820000FA430000FA430000A0400000344200EB\r
-:10B3920000A04214AE9F4200002045F6C8154403A7\r
-:06B3A20000480D3D000013\r
+:1014B0008111F6CFB6DE4AE050E0BC0181E894E04D\r
+:1014C0000E943C24EEE5F1E007C09091C00095FF3A\r
+:1014D000FCCF8093C600319684918111F6CF4AE00B\r
+:1014E00050E060ED74E081E894E00E943C2480913B\r
+:1014F000C00085FFFCCF8AE08093C60010922A04CA\r
+:1015000010922B0410922C0410922D0480E094DD94\r
+:1015100025E1C22E2AE0D22E35E2E32E3AE0F32E68\r
+:1015200009EE19E0F60161917191819191916F013C\r
+:10153000F70121913191419151917F0129833A83A2\r
+:101540004B835C830E94744C29813A814B815C817E\r
+:101550000E94A94E0E94484CF801619371938193B7\r
+:1015600091938F01F5E2CF16FAE0DF06D9F60E94DB\r
+:101570005E440E94FD2C0F900F900F900F90DF9112\r
+:10158000CF911F910F91FF90EF90DF90CF900C942F\r
+:10159000773F809134049091350460E070E00196CB\r
+:1015A0000C94FE4F80913404909135044AE050E051\r
+:1015B00060E070E001960C944A5140912E045091E5\r
+:1015C0002F0490E6949F9001959F300D1124682F71\r
+:1015D00070E0C90186559D4F0E947C52909335045E\r
+:1015E0008093340421E0892B09F420E0822F0895B0\r
+:1015F0000E94782160933E0470933F0480934004DE\r
+:1016000090934104EBEAF3E007C09091C00095FF8E\r
+:10161000FCCF8093C600319684918111F6CF8091E2\r
+:10162000C00085FFFCCF8AE08093C600089581E862\r
+:1016300094E00E945B23E3EAF3E007C09091C000CE\r
+:1016400095FFFCCF8093C600319684918111F6CF2F\r
+:1016500040913A0450913B0460913C0470913D04E8\r
+:101660004F5F5F4F6F4F7F4F2AE030E081E894E09B\r
+:101670000E9406248091C00085FFFCCF8AE0809301\r
+:10168000C600B6CF4F925F927F928F929F92AF9299\r
+:10169000BF92CF92DF92EF92FF920F931F93CF935F\r
+:1016A000DF9340E6742E54E0452E512CE1E2F2E047\r
+:1016B00084906AE0B62EEEE1F2E0A490992493942F\r
+:1016C0008091020590910305209104053091050554\r
+:1016D000821B930B8F779927892B09F0FEC111C2CA\r
+:1016E0008D3051F08A3321F490913104992321F007\r
+:1016F0002F3531050CF4D4C12115310519F41092A0\r
+:101700003104FFC18091A8029091A902789EE00166\r
+:10171000799ED00D1124FE01E20FF31FE655FD4F17\r
+:101720001082209131042111B6C110923104FC01C4\r
+:10173000E65DFB4F10828E0106551D4F6EE470E092\r
+:10174000C8010E947C52009709F403C190933504AC\r
+:1017500080933404801B910B8C0F9D1F4AE050E056\r
+:1017600060E070E085559D4F0E944A5160933604B9\r
+:10177000709337048093380490933904C0903A04EE\r
+:10178000D0903B04E0903C04F0903D04970186012A\r
+:101790000F5F1F4F2F4F3F4F60177107820793074F\r
+:1017A000C1F12091A8023091A902729EC001739EDE\r
+:1017B000900D11246FE771E086559D4F0E9487526E\r
+:1017C000892B39F5E5E7F1E007C09091C00095FF5E\r
+:1017D000FCCF8093C600319684918111F6CFECE75F\r
+:1017E000F1E007C09091C00095FFFCCF8093C60048\r
+:1017F000319684918111F6CF2AE030E0B701A6013D\r
+:1018000081E894E00E9406248091C00085FFFCCF0F\r
+:101810008AC08091A8029091A902789E8001799E49\r
+:10182000100D1124E801C655DD4F6AE270E0CE01CB\r
+:101830000E947C52009721F450C0F3262F5F02C013\r
+:1018400020E0F12CF801E20FF11DE655FD4F30814B\r
+:101850003A3299F790933504809334048C1B9D0B96\r
+:10186000800F911F60E070E085559D4F0E94FE4FF4\r
+:101870000E94434C2F2D30E02617370709F458C03B\r
+:10188000E5E7F1E007C09091C00095FFFCCF8093A1\r
+:10189000C600319684918111F6CFEEEAF1E007C0DF\r
+:1018A0009091C00095FFFCCF8093C6003196849143\r
+:1018B0008111F6CF40913A0450913B0460913C0471\r
+:1018C00070913D042AE030E081E894E00E94062413\r
+:1018D0008091C00085FFFCCF26C0E5E7F1E007C09E\r
+:1018E0009091C00095FFFCCF8093C6003196849103\r
+:1018F0008111F6CFECECF1E007C09091C00095FFAC\r
+:10190000FCCF8093C600319684918111F6CF2AE0F6\r
+:1019100030E0B701A60181E894E00E94062480919E\r
+:10192000C00085FFFCCF8AE08093C60080DE47C000\r
+:101930008091360490913704A0913804B091390415\r
+:1019400080933A0490933B04A0933C04B0933D04ED\r
+:101950003BC06AE270E0C8010E947C52892BA1F171\r
+:10196000E5E7F1E007C09091C00095FFFCCF8093C0\r
+:10197000C600319684918111F6CFE5EFF1E007C002\r
+:101980009091C00095FFFCCF8093C6003196849162\r
+:101990008111F6CF40913A0450913B0460913C0490\r
+:1019A00070913D042AE030E081E894E00E94062432\r
+:1019B0008091C00085FFFCCF8AE08093C600109222\r
+:1019C0003304109232049DC08091A8029091A90224\r
+:1019D000789EE001799ED00D11248E0106551D4F91\r
+:1019E00067E470E0C8010E947C52009709F43EC091\r
+:1019F0009093350480933404801B910B8C0F9D1FB2\r
+:101A000060E070E085559D4F0E94FE4F0E94434C60\r
+:101A10006430710558F580918002811113C08A2DC0\r
+:101A2000EEE1F2E008C09091C00095FFFCCF8093FA\r
+:101A3000C600319684918111F6CF8091C00085FF58\r
+:101A4000FCCF12C0882DE1E2F2E008C09091C00006\r
+:101A500095FFFCCF8093C600319684918111F6CF1B\r
+:101A60008091C00085FFFCCFB092C6008091A80293\r
+:101A70009091A9020196B2010E948E4F9093A90203\r
+:101A80008093A8028091A6029091A702019690935C\r
+:101A9000A7028093A602109233041092320410CE53\r
+:101AA0008B3311F49092310490913104911108CE4E\r
+:101AB0004091A8025091A902749ED001759EB00D6C\r
+:101AC0001124A20FB31FA655BD4F8C932F5F3F4F1C\r
+:101AD0003093330420933204F3CD8091A602909189\r
+:101AE000A702049774F481E894E00E943F23809356\r
+:101AF000300420913204309133048A3009F0F0CD63\r
+:101B0000FBCDDF91CF911F910F91FF90EF90DF9070\r
+:101B1000CF90BF90AF909F908F907F905F904F90AD\r
+:101B200008958F929F92AF92BF92CF92DF92EF92E1\r
+:101B3000FF920F931F93CF93DF9378E1A72E72E06C\r
+:101B4000B72E0FE812E0C6E4D4E0E2EA8E2EE2E01F\r
+:101B50009E2EF50181915F0130DD882311F119DDA1\r
+:101B60006B017C01F4018081811103C060915604F6\r
+:101B700001C061E070E080E090E00E94764CF801E6\r
+:101B800020813181428153810E94A94E9B01AC0189\r
+:101B9000C701B6010E94FB4A688379838A839B83CD\r
+:101BA00009C0F80180819181A281B38188839983E2\r
+:101BB000AA83BB830C5F1F4F2496FFEF8F1A9F0AE7\r
+:101BC0008CE1A81682E0B80621F686E4F6DC8823CC\r
+:101BD000D1F0DFDC6B017C016093680470936904D1\r
+:101BE00080936A0490936B0420E030E0A9010E9486\r
+:101BF000D74D181644F4C0921401D0921501E0920A\r
+:101C00001601F0921701DF91CF911F910F91FF9074\r
+:101C1000EF90DF90CF90BF90AF909F908F900895FE\r
+:101C200080DF89E4CADC882351F0B3DC60936C0464\r
+:101C300070936D0480936E0490936F0408C01092AB\r
+:101C40006C0410926D0410926E0410926F048AE47A\r
+:101C5000B4DC882351F09DDC6093700470937104B0\r
+:101C600080937204909373040895109270041092FC\r
+:101C7000710410927204109273040895CF92DF924F\r
+:101C8000EF92FF920F931F9320E030E0A901609143\r
+:101C900046047091470480914804909149040E9441\r
+:101CA000D44B87FF08C0109246041092470410924C\r
+:101CB00048041092490420E030E0A90160914A04F0\r
+:101CC00070914B0480914C0490914D040E94D44B30\r
+:101CD00087FF08C010924A0410924B0410924C04E3\r
+:101CE00010924D0420E030E0A90160914E04709103\r
+:101CF0004F0480915004909151040E94D44B87FF6F\r
+:101D000008C010924E0410924F041092500410928A\r
+:101D1000510420E030E04DE453E4609146047091BA\r
+:101D2000470480914804909149040E94D74D1816A9\r
+:101D300064F480E090E0ADE4B3E4809346049093D3\r
+:101D40004704A0934804B093490420E030E04DE4F8\r
+:101D500053E460914A0470914B0480914C0490913B\r
+:101D60004D040E94D74D181664F480E090E0ADE475\r
+:101D7000B3E480934A0490934B04A0934C04B09333\r
+:101D80004D0420E030E040EF52E460914E04709149\r
+:101D90004F0480915004909151040E94D74D181621\r
+:101DA00064F480E090E0A0EFB2E480934E0490935E\r
+:101DB0004F04A0935004B09351040E947821609383\r
+:101DC0003E0470933F0480934004909341046091DB\r
+:101DD000020170910301882777FD8095982F0E945A\r
+:101DE000764C2091140130911501409116015091CB\r
+:101DF00017010E94A94E20E030E040E752E40E9423\r
+:101E0000DB4B20E030E048EC52E40E94DB4BF2E890\r
+:101E1000CF2EF2E0DF2E7B018C0122E534E04EE490\r
+:101E200054E06AE474E086E494E00E947C2D8091A2\r
+:101E3000460490914704A0914804B09149048093CE\r
+:101E40008F0290939002A0939102B093920280919E\r
+:101E50004A0490914B04A0914C04B0914D0480939E\r
+:101E6000930290939402A0939502B093960280916E\r
+:101E70004E0490914F04A0915004B091510480936E\r
+:101E8000970290939802A0939902B0939A0280913E\r
+:101E9000520490915304A0915404B091550480933E\r
+:101EA0009B0290939C02A0939D02B0939E021F916F\r
+:101EB0000F91FF90EF90DF90CF900895AF92BF9277\r
+:101EC000CF92DF92EF92FF920F931F93CF93DF9306\r
+:101ED000182F209170043091710440917204509138\r
+:101EE000730460916C0470916D0480916E04909104\r
+:101EF0006F040E94E44DEB01082FF92E609102015E\r
+:101F000070910301882777FD8095982F0E94764C69\r
+:101F10002091140130911501409116015091170143\r
+:101F20000E94A94E20E030E040E752E40E94DB4BE3\r
+:101F300020E030E048EC52E40E94DB4B209182022A\r
+:101F40002F931F93FF920F93DF93CF935B016C014D\r
+:101F5000A2E0EA2E01E020E04CE654E066E474E002\r
+:101F60008FE892E00E9400258091460490914704FA\r
+:101F7000A0914804B091490480938F0290939002FD\r
+:101F8000A0939102B093920280914A0490914B04E5\r
+:101F9000A0914C04B0914D048093930290939402CD\r
+:101FA000A0939502B093960280914E0490914F04B5\r
+:101FB000A0915004B091510480939702909398029D\r
+:101FC000A0939902B0939A02809152049091530485\r
+:101FD000A0915404B091550480939B0290939C026D\r
+:101FE000A0939D02B0939E020E94782160933E04CC\r
+:101FF00070933F0480934004909341040F900F909E\r
+:102000000F900F900F900F90DF91CF911F910F9134\r
+:10201000FF90EF90DF90CF90BF90AF900895F8942D\r
+:102020000E94BB445A985A985A985A98E5E7F1E0AA\r
+:1020300007C09091C00095FFFCCF8093C6003196F9\r
+:1020400084918111F6CFEEEAF3E007C09091C000D1\r
+:1020500095FFFCCF8093C600319684918111F6CF15\r
+:102060008091C00085FFFCCF8AE08093C600FFCF3F\r
+:10207000CF92DF92EF92FF920F931F930E947821ED\r
+:102080000091600410916104209162043091630416\r
+:10209000C0903E04D0903F04E0904004F090410492\r
+:1020A0006C197D098E099F0906171707280739073C\r
+:1020B00028F4012B022B032B09F0B1DF80911901C9\r
+:1020C00090911A01A0911B01B0911C01892B8A2BC0\r
+:1020D0008B2B09F10E94782100913E0410913F045E\r
+:1020E0002091400430914104601B710B820B930BD3\r
+:1020F0000091190110911A0120911B0130911C01CE\r
+:10210000061717072807390730F4909108058091C2\r
+:102110000705981721F00E94312D1EBA05C05A9864\r
+:102120005A985A985A98F7CF1F910F91FF90EF90B5\r
+:10213000DF90CF9008952F923F924F925F926F92CF\r
+:102140007F928F929F92AF92BF92CF92DF92EF9247\r
+:10215000FF920F931F93CF93DF93CDB7DEB7A69770\r
+:102160000FB6F894DEBF0FBECDBF87E426DA882312\r
+:1021700009F489C20EDA0E94434C64307105B1F152\r
+:1021800044F46230710511F144F577FF17C00C94E7\r
+:10219000501D6A35710509F422C234F46C317105A1\r
+:1021A00011F00C94501D60C06B35710509F41BC211\r
+:1021B0006C35710511F00C94501D1AC2809180028B\r
+:1021C000811104C0AEDC5ADD0C9495208091800210\r
+:1021D000811103C025DD81E006C08091800281115C\r
+:1021E00005C01EDD80E06ADE0C94952080E5E5D90F\r
+:1021F000882331F0CED90E94484C6B017C0103C08A\r
+:10220000C12CD12C760183E5D8D9882359F0C1D9C6\r
+:1022100020E030E04AE754E40E94A94E0E94484C76\r
+:102220006B017C010E94B63F0E9478214B015C014A\r
+:102230008C0C9D1CAE1CBF1C0E94782160933E0438\r
+:1022400070933F04809340049093410404C00E9423\r
+:10225000E24181E00DDF0E947821681579058A0549\r
+:102260009B05A8F30C94501D8091140190911501C9\r
+:10227000A0911601B09117018093420490934304FA\r
+:10228000A0934404B093450480910201909103010E\r
+:102290009093A1028093A00284E690E090930301C2\r
+:1022A000809302010E94782160933E0470933F0462\r
+:1022B000809340049093410481E00E94763980919C\r
+:1022C0008F0290919002A0919102B091920280931E\r
+:1022D000460490934704A0934804B0934904809126\r
+:1022E000930290919402A0919502B09196028093EE\r
+:1022F0004A0490934B04A0934C04B0934D048091F6\r
+:10230000970290919802A0919902B0919A028093BD\r
+:102310004E0490934F04A0935004B09351048091C5\r
+:102320009B0290919C02A0919D02B0919E0280938D\r
+:10233000520490935304A0935404B0935504109204\r
+:10234000140110921501109216011092170188E5E0\r
+:1023500034D9882311F090E008C089E52ED9811185\r
+:10236000FACF8AE52AD991E0982790931801911124\r
+:102370000C94531D88E521D9882309F48EC089E582\r
+:102380001CD981110C94531D88C0C0921401D092A5\r
+:102390001501E0921601F092170120E030E040E7CD\r
+:1023A00052E4609114017091150180911601909191\r
+:1023B00017010E94DB4BE2E8CE2EE2E0DE2E7B012D\r
+:1023C0008C0122E534E04EE454E06AE474E086E4F3\r
+:1023D00094E00E947C2D0E94B63F10928F021092D2\r
+:1023E0009002109291021092920210929302109217\r
+:1023F000940210929502109296022BE932E047E97E\r
+:1024000052E063E972E08FE892E00E94FC3780912D\r
+:102410008F0290919002A0919102B09192028093CC\r
+:10242000460490934704A0934804B09349048091D4\r
+:10243000930290919402A0919502B091960280939C\r
+:102440004A0490934B04A0934C04B0934D0420E0B5\r
+:1024500030E040E752E460911401709115018091E1\r
+:102460001601909117010E94DB4B7B018C0122E544\r
+:1024700034E04EE454E06AE474E086E494E00E94C0\r
+:102480007C2D1092140110921501109216011092D9\r
+:1024900017010E94B63F0E946F3980911801811187\r
+:1024A0000C94A31D88E589D881110C94A31D8091FB\r
+:1024B000180181110C947B1E89E57FD881110C9441\r
+:1024C0007B1E8091180181110C94531F8AE575D8E9\r
+:1024D00081110C94531F88E570D88823C1F062D80D\r
+:1024E000672B682B692B99F054D820918302309187\r
+:1024F000840240918502509186020E94FB4A6093BB\r
+:102500008F0270939002809391029093920289E5DA\r
+:1025100054D88823C1F046D8672B682B692B99F0D3\r
+:1025200038D82091870230918802409189025091D9\r
+:102530008A020E94FB4A60939302709394028093F4\r
+:102540009502909396028AE538D88823C1F02AD85C\r
+:10255000672B682B692B99F01CD820918B02309146\r
+:102560008C0240918D0250918E020E94FB4A609332\r
+:102570009702709398028093990290939A022BE9A4\r
+:1025800032E047E952E063E972E08FE892E00E94AE\r
+:10259000FC378091420490914304A0914404B0918F\r
+:1025A00045048093140190931501A0931601B093F4\r
+:1025B00017018091A0029091A10290930301809352\r
+:1025C00002010E94782160933E0470933F0480933F\r
+:1025D0004004909341040E946F390C94501D109256\r
+:1025E00056040C94501D81E0809356040C94501DA9\r
+:1025F00085E40E94DD0A811102C00E94B63F48E1D5\r
+:10260000C42E42E0D42E53E8E52E52E0F52E0FE81A\r
+:1026100012E0B12CF60181916F010E94DD0A88233E\r
+:1026200039F1F3E0BF120CC00E94C90AF8016083BF\r
+:102630007183828393838BE992E00E94973818C05C\r
+:102640000E94C90AF70120813181428153810E9491\r
+:10265000FB4AF80160837183828393832BE932E024\r
+:1026600047E952E063E972E08FE892E00E94FC37AC\r
+:10267000B394F4E0EF0EF11C0C5F1F4F24E0B21294\r
+:10268000C9CF0C94501D8DE40E94DD0A882311F4FB\r
+:102690000C94A51C0E94C90A0E94434C683771051E\r
+:1026A00009F4D1C60CF053C06C35710509F44FC55F\r
+:1026B00044F56A32710509F406C174F4623171059A\r
+:1026C00009F4F4C46F31710509F4A4C061317105D6\r
+:1026D00011F00C94501D98C06335710509F4E2C4E3\r
+:1026E00034F46235710511F00C94501DD8C4643572\r
+:1026F000710509F4DBC46535710511F00C94501DAA\r
+:1027000010C56B36710509F4C7C464F469367105E8\r
+:1027100009F48FC10CF099C46836710511F00C945E\r
+:10272000501D11C16237710509F4B1C534F46D361D\r
+:10273000710511F00C94501D4DC26337710509F4F9\r
+:1027400098C56737710511F00C94501D82C66C3D19\r
+:10275000710509F4CDC744F5693C710509F4D8C683\r
+:1027600074F46C38710509F450C16E3B710509F4BD\r
+:10277000D0C36937710511F00C94501D66C66C3CCE\r
+:10278000710509F41BC734F46B3C710511F00C940E\r
+:10279000501DF8C66D3C710509F430C76E3C7105DB\r
+:1027A00011F00C94501D88C76F3231E0730711F49B\r
+:1027B0000C94781C74F46D3291E0790709F4B9C770\r
+:1027C00014F00C94741C6D3D710511F00C94501DA7\r
+:1027D000A1C7653FF1E07F0711F40C948A1C3CF41B\r
+:1027E0006039714011F00C94501D0C94871C663FA9\r
+:1027F00081E0780711F40C948C1C673E734011F053\r
+:102800000C94501D0C94901C5A9A5A9A5A9A5A9A9F\r
+:102810000C94501D0E9478216093570470935804C3\r
+:102820008093590490935A0400915B0410915C04C6\r
+:1028300020915D0430915E04601B710B820B930B41\r
+:1028400028EE33E040E050E00E94A14FCA01B901F8\r
+:102850002CE330E040E050E00E94A14F7F936F9363\r
+:102860003F932F938AE891E09F938F93CE01019637\r
+:102870009F938F930E94A152EBEBF0E084910FB6EF\r
+:10288000F894DEBF0FBECDBFEBEBF0E008C0909137\r
+:10289000C00095FFFCCF8093C600319684918111D2\r
+:1028A000F6CFFE01319606C09091C00095FFFCCF97\r
+:1028B0008093C60081918111F7CF8091C00085FF80\r
+:1028C000FCCF0C944D1D83E50E94DD0A882311F492\r
+:1028D0000C94501D0E94C90A6B017C0180E50E9486\r
+:1028E000DD0A882311F40C94501DC701B6010E9423\r
+:1028F000434C7B0177FF02C00C94501D6F3F710564\r
+:1029000009F014F40C942B200C94501D819191919A\r
+:102910008017910711F40C94501D22E0E039F20762\r
+:10292000A9F717FF02C00C94501D61E0802F0E9490\r
+:1029300092226E2D802F0E94AE22B701802F0E941E\r
+:1029400009220C94501D8091820280935F0484E5DB\r
+:102950000E94DD0A882379F10E94C90A0E94484C2E\r
+:1029600060935F04662339F1EBEBF0E007C09091D0\r
+:10297000C00095FFFCCF8093C600319684918111F1\r
+:10298000F6CFE9E9F1E006C09091C00095FFFCCFD9\r
+:102990008093C60081918111F7CF40E050E06091B3\r
+:1029A0005F0481E894E00E9400248091C00085FFCC\r
+:1029B000FCCF0C944D1D83E50E94DD0A882309F1AC\r
+:1029C000B0905F040E94C90A6B017C010B2D10E0DE\r
+:1029D0000E94434CDC01CB016B2D0E944640F80164\r
+:1029E000EE0FFF1FE255F54F91838083F801EE0F44\r
+:1029F000FF1FEE0FFF1FEC55F54FC082D182E28220\r
+:102A0000F3820E94BA440C94501D83E50E94DD0AB3\r
+:102A1000882311F40C94501D0E94C90A0E94434C53\r
+:102A2000CB010E94CA409093AD0A8093AC0A0C94EB\r
+:102A3000501D8091820280935F0484E50E94DD0A2C\r
+:102A4000882371F10E94C90A0E94484C60935F0478\r
+:102A5000662331F1EBEBF0E007C09091C00095FFE9\r
+:102A6000FCCF8093C600319684918111F6CFE0EBC4\r
+:102A7000F1E006C09091C00095FFFCCF8093C600A6\r
+:102A800081918111F7CF40E050E060915F0481E8CF\r
+:102A900094E00E9400248091C00085FFFCCFFDC718\r
+:102AA000E9E9F2E007C09091C00095FFFCCF809368\r
+:102AB000C600319684918111F6CF60915F04E62FB4\r
+:102AC000F0E0EE0FFF1FE655F54F808191810E94E7\r
+:102AD0001641AB01BC0121E030E081E894E00E94A6\r
+:102AE000FF24EFE9F2E007C09091C00095FFFCCF12\r
+:102AF0008093C600319684918111F6CF60915F0476\r
+:102B0000E62FF0E0EE0FFF1FE255F54F8081918137\r
+:102B10000E941641AB01BC0121E030E081E894E065\r
+:102B20000E94FF24E2EAF2E007C09091C00095FF06\r
+:102B3000FCCF8093C600319684918111F6CF8091AD\r
+:102B4000A80A9091A90A0E94C943AB01BC0121E0E7\r
+:102B500030E081E894E00E94FF24E6EAF2E007C05A\r
+:102B60009091C00095FFFCCF8093C6003196849170\r
+:102B70008111F6CF8091AC0A9091AD0A0E94C943B1\r
+:102B8000AB01BC0121E030E081E894E00E94FF2429\r
+:102B9000E9EAF2E007C09091C00095FFFCCF809376\r
+:102BA000C600319684918111F6CF80915F0490E048\r
+:102BB0000E9440404AE050E0BC0181E894E00E945D\r
+:102BC0003C248091C00085FFFCCF8AE08093C60042\r
+:102BD0000C9495208091820280935F0484E50E948A\r
+:102BE000DD0A882371F10E94C90A0E94484C609353\r
+:102BF0005F04662331F1EBEBF0E007C09091C00079\r
+:102C000095FFFCCF8093C600319684918111F6CF59\r
+:102C1000E7ECF1E006C09091C00095FFFCCF8093F7\r
+:102C2000C60081918111F7CF40E050E060915F04D0\r
+:102C300081E894E00E9400248091C00085FFFCCFD1\r
+:102C40002CC783E50E94DD0A882309F1B0905F0458\r
+:102C50000E94C90A6B017C010B2D10E00E94434CBD\r
+:102C6000DC01CB016B2D0E944640F801EE0FFF1FE7\r
+:102C7000E255F54F91838083F801EE0FFF1FEE0FB1\r
+:102C8000FF1FEC55F54FC082D182E282F3820E9491\r
+:102C9000BA440E9478214B015C0180915F0490E06E\r
+:102CA000880F991FFC01E255F54F2081318138A32F\r
+:102CB0002F8FFC01E655F54F808191819EA38DA356\r
+:102CC000CC24CA94DC2C7601EDEAF2E02490E0EB0F\r
+:102CD000F2E03490E4EBF2E0049178EE472E73E0FA\r
+:102CE000572E612C712C1AE00C944C20822DEDEAA9\r
+:102CF000F2E008C09091C00095FFFCCF8093C60021\r
+:102D0000319684918111F6CF60915F04E62FF0E057\r
+:102D1000EE0FFF1FE655F54F808191810E9416410D\r
+:102D2000AB01BC0121E030E081E894E00E94FF2487\r
+:102D3000832DE0EBF2E008C09091C00095FFFCCF3E\r
+:102D40008093C600319684918111F6CF60915F0423\r
+:102D50004AE050E070E081E894E00E943C24802F3B\r
+:102D6000E4EBF2E008C09091C00095FFFCCF8093A7\r
+:102D7000C600319684918111F6CFF7FE03C0EEEDC7\r
+:102D8000F1E027C00E9478214B015C01C701B60128\r
+:102D9000605F784D8F4F9F4F681979098A099B09A9\r
+:102DA000A30192010E94A14F49015A012AE030E09B\r
+:102DB000B501A40181E894E00E94F0238091C00055\r
+:102DC00085FFFCCF0DC09091C00095FFFCCF809394\r
+:102DD000C60081918111F7CF8091C00085FFFCCFA3\r
+:102DE0001093C6000E9478214B015C010E94E241D1\r
+:102DF00081E03ED99FEFC916D906E906F906C1F56B\r
+:102E000060915F04EF8DF8A12DA13EA12E173F0721\r
+:102E100014F00C946820E62FF0E0EE0FFF1FE6554B\r
+:102E2000F54F808191810E94164169A37AA38BA3FB\r
+:102E30009CA360915F04E62FF0E0EE0FFF1FE255C8\r
+:102E4000F54F808191810E94164120E030E040E8FA\r
+:102E50005FE30E94FA4A9B01AC0169A17AA18BA1B0\r
+:102E60009CA10E94D74D87FD02C00C9434203AC02B\r
+:102E7000F7FC38C060915F04E62FF0E0EE0FFF1F13\r
+:102E8000E655F54F808191810E94164169A37AA38E\r
+:102E90008BA39CA360915F04E62FF0E0EE0FFF1F71\r
+:102EA000E255F54F808191810E9416419B01AC0152\r
+:102EB00069A17AA18BA19CA10E94FA4A0E94434C6D\r
+:102EC000AB01BC0177FF07C07095609550954195A7\r
+:102ED0005F4F6F4F7F4F443051056105710514F00E\r
+:102EE0000C9434203FEFC316D306E306F30611F427\r
+:102EF0000C944C20F7FE02C00C9439200E947821DB\r
+:102F00006C197D096031774210F40C944C200C94BC\r
+:102F1000392083E50E94DD0A882359F00E94C90AFE\r
+:102F20000E94434CCB010E94CA409093AD0A80930B\r
+:102F3000AC0A0E9478216B017C01E8EBF2E0A490DE\r
+:102F4000EBEBF2E0B490EFEBF2E014910AE06FC02B\r
+:102F50000E9478216C197D098E099F09693E734092\r
+:102F60008105910508F45FC060918202A62FB0E050\r
+:102F7000AA0FBB1FA655B54F8D919C910E9416417B\r
+:102F8000AB01BC018A2DE8EBF2E008C09091C000D3\r
+:102F900095FFFCCF8093C600319684918111F6CFC6\r
+:102FA00022E030E081E894E00E94FF248B2DEBEBDF\r
+:102FB000F2E008C09091C00095FFFCCF8093C6005E\r
+:102FC000319684918111F6CF609182024AE050E0FF\r
+:102FD00070E081E894E00E943C24812FEFEBF2E066\r
+:102FE00008C09091C00095FFFCCF8093C600319639\r
+:102FF00084918111F6CF8091A80A9091A90A0E942C\r
+:10300000C943AB01BC0121E030E081E894E00E94BB\r
+:10301000FF248091C00085FFFCCF0093C6000E9472\r
+:1030200078216B017C010E94E24181E021D820914E\r
+:10303000AC0A3091AD0A8091A80A9091A90A821732\r
+:1030400093070CF485CF0C94422083E50E94DD0A9F\r
+:103050008823F1F00E94C90A20E030E0A9010E9413\r
+:10306000D44B87FD0FC00E94C90A20E030E04FE733\r
+:1030700053E40E94D74D18163CF00E94C90A0E94E2\r
+:10308000484C03C060E001C06FEF6093810208C547\r
+:103090008FEF8093810204C51092810201C51092C6\r
+:1030A000A502FEC481E08093A502FAC483E50E94D4\r
+:1030B000DD0A882399F00E94C90A20E030E04AE73F\r
+:1030C00054E40E94A94E0E94484C609319017093E9\r
+:1030D0001A0180931B0190931C01E2C488E50E94B1\r
+:1030E000DD0A8111EDC789E50E94DD0A8111E8C77B\r
+:1030F0008AE50E94DD0A8111E3C785E40E94DD0AAA\r
+:103100008111DEC7D7C75A9889E50E94DD0A81116F\r
+:103110005A988AE50E94DD0A882309F4C1C45A98A6\r
+:10312000BFC483E50E94DD0A0E94C90A20E030E0A6\r
+:103130004AE754E40E94A94E0E94484C6093600400\r
+:10314000709361048093620490936304A9C428E19E\r
+:1031500032E03EA32DA3B5E22B2EBAE03B2E85E351\r
+:103160009AE098A38F8F19EE812E19E0912E10E02E\r
+:10317000EDA1FEA18191FEA3EDA30E94DD0A8823AB\r
+:1031800009F466C0133009F05CC00E94C90A6B01E3\r
+:103190007C0120E030E040EA51E40E94D44B87FFFC\r
+:1031A0004AC0A7019601F1016081718182819381FA\r
+:1031B0000E94DB4B762EA72EB82E092F762F272FB5\r
+:1031C0003A2D4B2D502F6091FD097091FE09809191\r
+:1031D000FF099091000A0E94A94E6093FD09709327\r
+:1031E000FE098093FF099093000A272D3A2D4B2D5D\r
+:1031F000502FEF8DF8A160817181828193810E94AF\r
+:10320000A94EEF8DF8A16083718382839383F401CB\r
+:1032100060817181828193810E94744C272D3A2DA7\r
+:103220004B2D502F0E94A94E0E94484CF401608300\r
+:10323000718382839383F101C082D182E282F3821F\r
+:1032400007C00E94C90AF10160837183828393835E\r
+:103250001F5FF4E02F0E311C2F8D38A12C5F3F4FE4\r
+:1032600038A32F8F34E0830E911C143009F080CFE7\r
+:1032700017C4E3ECF2E007C09091C00095FFFCCFCB\r
+:103280008093C600319684918111F6CF09C4EEE592\r
+:10329000F3E007C09091C00095FFFCCF8093C6007B\r
+:1032A000319684918111F6CF40918F025091900216\r
+:1032B000609191027091920222E030E081E894E006\r
+:1032C0000E94FF24E1E6F3E007C09091C00095FF63\r
+:1032D000FCCF8093C600319684918111F6CF409146\r
+:1032E000930250919402609195027091960222E0AF\r
+:1032F00030E081E894E00E94FF24E4E6F3E007C0B8\r
+:103300009091C00095FFFCCF8093C60031968491C8\r
+:103310008111F6CF409197025091980260919902E5\r
+:1033200070919A0222E030E081E894E00E94FF244C\r
+:10333000E7E6F3E007C09091C00095FFFCCF8093D3\r
+:10334000C600319684918111F6CF40919B02509135\r
+:103350009C0260919D0270919E0222E030E081E823\r
+:1033600094E00E94FF24EAE6F3E007C09091C000D9\r
+:1033700095FFFCCF8093C600319684918111F6CFE2\r
+:103380000E940F400E94764C2091250A3091260A17\r
+:103390004091270A5091280A0E94DB4BAB01BC01E7\r
+:1033A00022E030E081E894E00E94FF24E4E7F3E0CB\r
+:1033B00007C09091C00095FFFCCF8093C600319666\r
+:1033C00084918111F6CF81E00E940F400E94764CDB\r
+:1033D0002091290A30912A0A40912B0A50912C0AF7\r
+:1033E0000E94DB4BAB01BC0122E030E081E894E0BD\r
+:1033F0000E94FF24E7E7F3E007C09091C00095FF2B\r
+:10340000FCCF8093C600319684918111F6CF82E083\r
+:103410000E940F400E94764C20912D0A30912E0A76\r
+:1034200040912F0A5091300A0E94DB4BAB01BC0146\r
+:1034300022E030E081E894E00E94FF248091C00007\r
+:1034400085FFFCCF2AC380E001C081E00E9476396D\r
+:1034500027C3EAE7F3E007C09091C00095FFFCCFD7\r
+:103460008093C600319684918111F6CF189903C0DC\r
+:10347000E4E8F1E009C0E7E8F1E006C09091C0009F\r
+:1034800095FFFCCF8093C60081918111F7CFE1E8D1\r
+:10349000F3E007C09091C00095FFFCCF8093C60079\r
+:1034A000319684918111F6CF199903C0E4E8F1E0D7\r
+:1034B00009C0E7E8F1E006C09091C00095FFFCCF9D\r
+:1034C0008093C60081918111F7CFE8E8F3E007C04F\r
+:1034D0009091C00095FFFCCF8093C60031968491F7\r
+:1034E0008111F6CF1A9903C0E4E8F1E009C0E7E8DA\r
+:1034F000F1E006C09091C00095FFFCCF8093C6001C\r
+:1035000081918111F7CF8091C00085FFFCCFC5C2AA\r
+:10351000A8E1EA2EA2E0FA2E00E010E0F701819186\r
+:103520007F010E94DD0A882339F10E94C90AE5E182\r
+:10353000CE2EEAE0DE2EC00ED11E0E94484CF601CF\r
+:1035400060837183828393830E94C90AF9EECF2E30\r
+:10355000F9E0DF2EC00ED11EF801EB5DF54F2081A2\r
+:103560003181428153810E94A94E0E94484CF6014C\r
+:1035700060837183828393830C5F1F4F0031110539\r
+:1035800069F68EC208E112E065E3E62E6AE0F62EE7\r
+:10359000F80181918F010E94DD0A882339F00E9491\r
+:1035A000C90AF7016083718382839383F4E0EF0E8D\r
+:1035B000F11C22E00C31120759F772C283E50E9418\r
+:1035C000DD0A882351F00E94C90A60930D0A7093A6\r
+:1035D0000E0A80930F0A9093100A84E50E94DD0A78\r
+:1035E000882309F45DC20E94C90A6093090A709396\r
+:1035F0000A0A80930B0A90930C0A52C283E50E9438\r
+:10360000DD0A882351F00E94C90A6093110A709361\r
+:10361000120A8093130A9093140A84E50E94DD0A2B\r
+:10362000882351F00E94C90A6093F9097093FA093E\r
+:103630008093FB099093FC0982E40E94DD0A8823B1\r
+:1036400061F00E94C90A0E94484C6093450A709339\r
+:10365000460A8093470A9093480A88E50E94DD0A4B\r
+:10366000882351F00E94C90A6093050A7093060AE4\r
+:103670008093070A9093080A8AE50E94DD0A88234E\r
+:1036800051F00E94C90A6093010A7093020A809364\r
+:10369000030A9093040A85E40E94DD0A882309F452\r
+:1036A000FFC10E94C90A6093FD097093FE098093CF\r
+:1036B000FF099093000AF4C108E112E053E8E52EF7\r
+:1036C00052E0F52EF80181918F010E94DD0A8823D6\r
+:1036D00039F00E94C90AF701608371838283938362\r
+:1036E000F4E0EF0EF11C22E00B31120759F7D8C1BC\r
+:1036F00083E50E94DD0A882309F4D2C10E94C90A29\r
+:103700000E94434C709303016093020181E0809317\r
+:103710009F02C6C183E50E94DD0A882309F4C0C167\r
+:103720000E94C90A0E94434C7093010160930001FA\r
+:10373000B7C180E50E94DD0A882351F00E94C90AC2\r
+:1037400060932E0170932F0180933001909331018B\r
+:1037500089E40E94DD0A882381F00E94C90A25E9D4\r
+:103760003FEB46ED5DE30E94A94E60932A01709302\r
+:103770002B0180932C0190932D0184E40E94DD0A9B\r
+:10378000882381F00E94C90A25E93FEB46ED5DE3FD\r
+:103790000E94DB4B609326017093270180932801E0\r
+:1037A0009093290183E40E94DD0A882351F00E944E\r
+:1037B000C90A60932201709323018093240190939E\r
+:1037C00025010E942940E0EEF1E006C09091C00082\r
+:1037D00095FFFCCF8093C60081918111F7CFE3EE76\r
+:1037E000F1E006C09091C00095FFFCCF8093C60029\r
+:1037F00081918111F7CF40912E0150912F0160915D\r
+:1038000030017091310122E030E081E894E00E94C3\r
+:10381000FF24E7EEF1E006C09091C00095FFFCCFD9\r
+:103820008093C60081918111F7CF25E93FEB46EDEA\r
+:103830005DE360912A0170912B0180912C019091A0\r
+:103840002D010E94DB4BAB01BC0122E030E081E89E\r
+:1038500094E00E94FF24EBEEF1E006C09091C000DE\r
+:1038600095FFFCCF8093C60081918111F7CF25E9A8\r
+:103870003FEB46ED5DE36091260170912701809159\r
+:103880002801909129010E94A94EAB01BC0122E0C0\r
+:1038900030E081E894E00E94FF24EFEEF1E006C002\r
+:1038A0009091C00095FFFCCF8093C600819181115B\r
+:1038B000F7CF25E93FEB46ED5DE360912201709182\r
+:1038C000230180912401909125010E94A94EAB0112\r
+:1038D000BC0122E030E081E894E00E94FF24809166\r
+:1038E000C00085FFFCCFD9C081E00E94B038D8C0AD\r
+:1038F00083E50E94DD0A882319F00E94C90A04C0EA\r
+:1039000060E070E086E193E40E94E744C9C00E9451\r
+:10391000B63FC6C080E001C081E00E941C08C0C064\r
+:10392000109280028091640490916504A0916604D5\r
+:10393000B091670480933A0490933B04A0933C04B5\r
+:10394000B0933D040E94170BABC084E50E94DD0AD2\r
+:10395000882309F461C00E94C90A0E94484C609300\r
+:103960005F04662389F1EBEBF0E007C09091C000A3\r
+:1039700095FFFCCF8093C600319684918111F6CFDC\r
+:10398000E3EFF1E006C09091C00095FFFCCF80937B\r
+:10399000C60081918111F7CF40E050E060915F0453\r
+:1039A00081E894E02DD7E5EFF1E006C09091C000EA\r
+:1039B00095FFFCCF8093C60081918111F7CF809154\r
+:1039C000C00085FFFCCF69C010928202EBEBF0E0F3\r
+:1039D00007C09091C00095FFFCCF8093C600319640\r
+:1039E00084918111F6CFE6E0F2E006C09091C0002C\r
+:1039F00095FFFCCF8093C60081918111F7CF609134\r
+:103A000082024AE050E070E081E894E035D780918E\r
+:103A1000C00085FFFCCF41C0EBEBF0E007C0909108\r
+:103A2000C00095FFFCCF8093C60031968491811130\r
+:103A3000F6CFEFE8F3E007C09091C00095FFFCCF10\r
+:103A40008093C600319684918111F6CF80912E0427\r
+:103A500090912F0420E6289FF001299FF00D11245A\r
+:103A6000E655FD4F06C09091C00095FFFCCF8093B6\r
+:103A7000C60081918111F7CFE1EAF3E007C0909190\r
+:103A8000C00095FFFCCF8093C600319684918111D0\r
+:103A9000F6CF8091C00085FFFCCF8AE08093C600FE\r
+:103AA0000E94F80A42C310928F0210929002109264\r
+:103AB000910210929202109293021092940210922C\r
+:103AC0009502109296022BE932E047E952E063E951\r
+:103AD00072E08FE892E00E94FC3780E090ECA9E968\r
+:103AE000B3EC8093460490934704A0934804B093AA\r
+:103AF000490480934A0490934B04A0934C04B093E0\r
+:103B00004D0420910401309105014091060150912E\r
+:103B1000070120931401309315014093160150932F\r
+:103B20001701C0900801D0900901E0900A01F090BF\r
+:103B30000B01C701B6010E94D44B87FF02C00C9451\r
+:103B4000C5110C94CD1110928F0210929002109218\r
+:103B50009102109292022BE932E047E952E063E9C8\r
+:103B600072E08FE892E00E94FC3780E090ECA9E9D7\r
+:103B7000B3EC8093460490934704A0934804B09319\r
+:103B800049046091040170910501809106019091B2\r
+:103B900007016093140170931501809316019093AF\r
+:103BA000170120E030E040E752E40E94DB4B42E89E\r
+:103BB000C42E42E0D42E7B018C0122E534E04EE499\r
+:103BC00054E06AE474E086E494E00E947C2D0E9454\r
+:103BD000B63F10928F0210929002109291021092B2\r
+:103BE00092022BE932E047E952E063E972E08FE8A4\r
+:103BF00092E00E94FC3780E090E0A0EAB0E480937D\r
+:103C0000460490934704A0934804B093490420E0ED\r
+:103C100030E040E752E46091140170911501809109\r
+:103C20001601909117010E94DB4B7B018C0122E56C\r
+:103C300034E04EE454E06AE474E086E494E00E94E8\r
+:103C40007C2D0E94B63F80E090E0A0E2B1EC809332\r
+:103C5000460490934704A0934804B093490420E09D\r
+:103C600030E040E05FE360910401709105018091D4\r
+:103C70000601909107010E94A94EFB01462F5F2F7C\r
+:103C8000682F792F4093140150931501609316010A\r
+:103C90007093170120E030E040E752E4BF010E943A\r
+:103CA000DB4B7B018C0122E534E04EE454E06AE416\r
+:103CB00074E086E494E00E947C2D0E94B63F10924E\r
+:103CC0008F02109290021092910210929202109222\r
+:103CD000460410924704109248041092490410922E\r
+:103CE00014011092150110921601109217010E94F2\r
+:103CF0006F390C9457121092930210929402109202\r
+:103D00009502109296022BE932E047E952E063E90E\r
+:103D100072E08FE892E00E94FC3780E090ECA9E925\r
+:103D2000B3EC80934A0490934B04A0934C04B0935B\r
+:103D30004D04609108017091090180910A019091F0\r
+:103D40000B016093140170931501809316019093F9\r
+:103D5000170120E030E040E752E40E94DB4B32E8FC\r
+:103D6000C32E32E0D32E7B018C0122E534E04EE4F9\r
+:103D700054E06AE474E086E494E00E947C2D0E94A2\r
+:103D8000B63F1092930210929402109295021092F4\r
+:103D900096022BE932E047E952E063E972E08FE8EE\r
+:103DA00092E00E94FC3780E090E0A0EAB0E48093CB\r
+:103DB0004A0490934B04A0934C04B0934D0420E02C\r
+:103DC00030E040E752E46091140170911501809158\r
+:103DD0001601909117010E94DB4B7B018C0122E5BB\r
+:103DE00034E04EE454E06AE474E086E494E00E9437\r
+:103DF0007C2D0E94B63F80E090E0A0E2B1EC809381\r
+:103E00004A0490934B04A0934C04B0934D0420E0DB\r
+:103E100030E040E05FE3609108017091090180911A\r
+:103E20000A0190910B010E94A94EFB01462F5F2FC2\r
+:103E3000682F792F40931401509315016093160158\r
+:103E40007093170120E030E040E752E4BF010E9488\r
+:103E5000DB4B7B018C0122E534E04EE454E06AE464\r
+:103E600074E086E494E00E947C2D0E94B63F10929C\r
+:103E70009302109294021092950210929602109260\r
+:103E80004A0410924B0410924C0410924D0410926C\r
+:103E900014011092150110921601109217010E9440\r
+:103EA0006F390C946112109297021092980210923E\r
+:103EB000990210929A022BE932E047E952E063E955\r
+:103EC00072E08FE892E00E94FC3780E090E0A4E38B\r
+:103ED000B3EC80934E0490934F04A0935004B0939E\r
+:103EE000510460910C0170910D0180910E0190912F\r
+:103EF0000F01609314017093150180931601909344\r
+:103F0000170120E030E040E752E40E94DB4B22E85A\r
+:103F1000C22E22E0D22E7B018C0122E534E04EE459\r
+:103F200054E06AE474E086E494E00E947C2D0E94F0\r
+:103F3000B63F109297021092980210929902109236\r
+:103F40009A022BE932E047E952E063E972E08FE838\r
+:103F500092E00E94FC3780E090E0A0E8BFE380930D\r
+:103F60004E0490934F04A0935004B093510420E06A\r
+:103F700030E040E752E460911401709115018091A6\r
+:103F80001601909117010E94DB4B7B018C0122E509\r
+:103F900034E04EE454E06AE474E086E494E00E9485\r
+:103FA0007C2D0E94B63F80E090E0A0E0B0EC8093D2\r
+:103FB0004E0490934F04A0935004B093510420E01A\r
+:103FC00030E040E05FE360910C0170910D01809161\r
+:103FD0000E0190910F010E94A94EFB01462F5F2F09\r
+:103FE000682F792F409314015093150160931601A7\r
+:103FF0007093170120E030E040E752E4BF010E94D7\r
+:10400000DB4B7B018C0122E534E04EE454E06AE4B2\r
+:1040100074E086E494E00E947C2D0E94B63F1092EA\r
+:104020009702109298021092990210929A0210929E\r
+:104030004E0410924F0410925004109251041092AA\r
+:1040400014011092150110921601109217010E948E\r
+:104050006F390C946B120E94C90A0E94434C8B0169\r
+:10406000ECE1F2E00C94861443D16B017C010C94DA\r
+:1040700072173ED160935B0470935C0480935D047F\r
+:1040800090935E0435D160933E0470933F04809317\r
+:1040900040049093410404CD2BD1681979098A0911\r
+:1040A0009B09693E73408105910510F00C947616CA\r
+:1040B0000C94F6160E94B63F5A980E942340F0CC0A\r
+:1040C0000E94B63F88E50E94DD0A81111CC81CC809\r
+:1040D000E62FF0E0EE0FFF1FE655F54F808191814E\r
+:1040E0000E94164169A37AA38BA39CA360915F04ED\r
+:1040F000E62FF0E0EE0FFF1FE255F54F8081918132\r
+:104100000E94164120E030E040E85FE30E94FB4A55\r
+:104110009B01AC0169A17AA18BA19CA10E94D44B07\r
+:1041200018160CF0A1CF0C947217A6960FB6F8943F\r
+:10413000DEBF0FBECDBFDF91CF911F910F91FF90DA\r
+:10414000EF90DF90CF90BF90AF909F908F907F9037\r
+:104150006F905F904F903F902F9008958091A602AE\r
+:104160009091A702039714F40E94420B8091A6023B\r
+:104170009091A702892BC1F00E949B108091A6020A\r
+:104180009091A70201979093A7028093A602809135\r
+:104190002E0490912F04019664E070E00E948E4FEF\r
+:1041A00090932F0480932E040E94E24181E00E94AC\r
+:1041B00038100C94B3380E94BB4480918002811166\r
+:1041C00034C081E08093800280913A0490913B0456\r
+:1041D000A0913C04B0913D048093640490936504E5\r
+:1041E000A0936604B0936704E5E7F1E007C09091FF\r
+:1041F000C00095FFFCCF8093C60031968491811159\r
+:10420000F6CFEFECF3E007C09091C00095FFFCCF34\r
+:104210008093C600319684918111F6CF8091C000C1\r
+:1042200085FFFCCF8AE08093C600089580918002CC\r
+:104230000895E82FF0E0E95BFB4FE491E650E230AF\r
+:1042400060F48091B1008C7F8093B1008091B100C7\r
+:1042500067707727862B8093B10008959FD00E94C6\r
+:104260002D097CDFFECF1F920F920FB60F92112403\r
+:104270002F933F938F939F93AF93BF938091780435\r
+:1042800090917904A0917A04B0917B0430918004DC\r
+:10429000232F2A592D3720F02D570196A11DB11D2E\r
+:1042A000209380048093780490937904A0937A04F7\r
+:1042B000B0937B0480917C0490917D04A0917E0456\r
+:1042C000B0917F040196A11DB11D80937C04909351\r
+:1042D0007D04A0937E04B0937F04BF91AF919F9122\r
+:1042E0008F913F912F910F900FBE0F901F901895B7\r
+:1042F0000F931F938FB7F89400917804109179046D\r
+:1043000020917A0430917B048FBFB801C9011F91BD\r
+:104310000F9108959FB7F89440917C0450917D04CB\r
+:1043200060917E0470917F0486B5A89B06C08F3F84\r
+:1043300021F04F5F5F4F6F4F7F4F9FBF2227342F7A\r
+:10434000452F562F280F311D411D511DA3E0B0E010\r
+:104350000C946F4FCF92DF92EF92FF92CF93DF9347\r
+:104360006B017C01D7DFEB010DC0D4DF6C1B7D0B33\r
+:10437000683E734038F081E0C81AD108E108F108BE\r
+:10438000C851DC4FC114D104E104F10471F7DF918D\r
+:10439000CF91FF90EF90DF90CF900895789484B5FF\r
+:1043A000826084BD84B5816084BD85B5826085BD31\r
+:1043B00085B5816085BDEEE6F0E080818160808317\r
+:1043C000E1E8F0E0108280818260808380818160FA\r
+:1043D0008083E0E8F0E0808181608083E1EBF0E0C1\r
+:1043E000808184608083E0EBF0E080818160808365\r
+:1043F000EAE7F0E08081846080838081826080834E\r
+:104400008081816080838081806880831092C10078\r
+:1044100008951F93CF93DF93182FEB0161E082D0B3\r
+:10442000209711F460E004C0CF3FD10531F461E082\r
+:10443000812FDF91CF911F9191C0E12FF0E0E95BD7\r
+:10444000FB4FE491E330B9F028F4E13051F0E23071\r
+:10445000B1F50CC0E63019F1E73049F1E43079F5F7\r
+:1044600014C084B5806884BDC7BD2EC084B5806289\r
+:1044700084BDC8BD29C08091800080688093800081\r
+:10448000D0938900C09388001FC080918000806213\r
+:1044900080938000D0938B00C0938A0015C08091D8\r
+:1044A000B00080688093B000C093B3000DC08091CD\r
+:1044B000B00080628093B000C093B40005C0C038E3\r
+:1044C000D1050CF0B4CFAECFDF91CF911F910895FD\r
+:1044D000833069F028F48130A1F0823011F514C0E6\r
+:1044E0008630B1F08730C1F08430D9F404C08091B7\r
+:1044F00080008F7703C0809180008F7D8093800043\r
+:10450000089584B58F7702C084B58F7D84BD0895EA\r
+:104510008091B0008F7703C08091B0008F7D809331\r
+:10452000B000089590E0FC01E959FB4F2491FC0193\r
+:10453000E957FB4FE491EE2381F0F0E0E455FB4FA7\r
+:10454000A491B0E09FB7F8948C91611103C02095BD\r
+:10455000822301C0822B8C939FBF08950F931F93DA\r
+:10456000CF93DF931F92CDB7DEB7A82FB0E0FD0148\r
+:10457000E95BFB4F8491FD01E959FB4F1491FD016B\r
+:10458000E957FB4F04910023B1F0882319F06983A8\r
+:104590009FDF6981E02FF0E0E955FB4FA491B0E087\r
+:1045A0009FB7F8948C91611103C01095812301C0CD\r
+:1045B000812B8C939FBF0F90DF91CF911F910F9113\r
+:1045C00008951F920F920FB60F9211242F933F93CD\r
+:1045D0004F935F936F938F939F93EF93FF936091AC\r
+:1045E000C6002091020530910305C90101968F771D\r
+:1045F000992740910405509105058417950741F0CE\r
+:10460000F901EE57FB4F60839093030580930205F9\r
+:10461000FF91EF919F918F916F915F914F913F919A\r
+:104620002F910F900FBE0F901F9018959A01AB011C\r
+:1046300082E08093C00060E47BE48CE490E00E9420\r
+:10464000C34F2150310941095109CA01B90122E082\r
+:1046500030E040E050E00E94C34F832F99278093C1\r
+:10466000C5002093C400E1ECF0E08081806180838C\r
+:1046700080818860808380818068808308958091B4\r
+:104680000405909105052091020530910305281736\r
+:10469000390769F0FC01EE57FB4F208101968F77B7\r
+:1046A0009927909305058093040530E002C02FEF11\r
+:1046B0003FEFC901089580910405909105059093FD\r
+:1046C00003058093020508956F927F928F929F92C7\r
+:1046D000AF92BF92CF92DF92EF92FF920F931F9310\r
+:1046E000CF93DF93CDB7DEB7A0970FB6F894DEBFB8\r
+:1046F0000FBECDBF8C014115510561057105C1F497\r
+:1047000040E050E060E3A0960FB6F894DEBF0FBE25\r
+:10471000CDBFDF91CF911F910F91FF90EF90DF9070\r
+:10472000CF90BF90AF909F908F907F906F90ABC0D5\r
+:1047300066246394712C6C0E7D1EC12CD12C7601E5\r
+:10474000822E912CA12CB12CCB01BA01A501940190\r
+:104750000E94A14FFA01D3016D933D01BFEFCB1A27\r
+:10476000DB0AEB0AFB0AA901BF01411551056105EE\r
+:10477000710551F781E0C81AD108E108F10815C0A8\r
+:10478000E1E0F0E0EC0FFD1FEC0DFD1D60816A30F3\r
+:1047900010F4605D01C0695C40E050E0C80173D076\r
+:1047A000A1E0CA1AD108E108F108BFEFCB16DB0679\r
+:1047B000EB06FB0629F7A0960FB6F894DEBF0FBEF6\r
+:1047C000CDBFDF91CF911F910F91FF90EF90DF90C0\r
+:1047D000CF90BF90AF909F908F907F906F900895F3\r
+:1047E0002115310539F48091C00085FFFCCF40933D\r
+:1047F000C600089569CF9A01AB0160E070E0F0CF88\r
+:104800009A01462F50E060E070E0EACFCF92DF924D\r
+:10481000EF92FF92CF93DF93EC016A017B012115A8\r
+:10482000310539F48091C00085FFFCCFC092C600ED\r
+:104830001CC02A30310579F477FF0CC040E050E00D\r
+:104840006DE221D0F094E094D094C094C11CD11CAE\r
+:10485000E11CF11C2AE0B701A601CE01DF91CF9146\r
+:10486000FF90EF90DF90CF902FCFDF91CF91FF900F\r
+:10487000EF90DF90CF9008959A01AB01662757FD26\r
+:104880006095762FC3CF9A01462F50E060E070E02C\r
+:10489000BDCFCF93DF93EC0140E050E06DE0F3DF5C\r
+:1048A00040E050E06AE0CE01DF91CF91ECCFCF93B2\r
+:1048B000DF93EC01A0DFCE01DF91CF91EACF8F92A1\r
+:1048C0009F92AF92BF92CF92DF92EF92FF920F939F\r
+:1048D0001F93CF93DF938C014A015B01C22F20E02D\r
+:1048E00030E0A901C501B4010E94D44B87FF09C083\r
+:1048F00040E050E06DE2C801C6DFB7FAB094B7F807\r
+:10490000B094D0E060E070E080E09FE307C020E07A\r
+:1049100030E040E251E40E94DB4BDF5FDC13F7CF75\r
+:10492000262F372F482F592FC501B4010E94FB4A6B\r
+:10493000D62EE72EF82ED92F0E94484C962EA72E61\r
+:10494000B82EC92E0E94744C9B01AC016D2D7E2D9A\r
+:104950008F2D9D2F0E94FA4AD62FF72EE82ED92EA2\r
+:104960002AE030E0492D5A2D6B2D7C2DC80138DF0F\r
+:10497000CC23B1F1E6E5F2E006C09091C00095FFCE\r
+:10498000FCCF8093C60081918111F7CF29C020E030\r
+:1049900030E040E251E46D2F7F2D8E2D9D2D0E9441\r
+:1049A000A94E6B017C017D2D9F2D0E94434C5B0124\r
+:1049B0004AE050E0C80160DFB501882777FD8095A7\r
+:1049C000982F0E94764C9B01AC016C2D7D2D8E2D75\r
+:1049D0009F2D0E94FA4AD62FF72EE82ED92EC150CD\r
+:1049E000C111D5CFDF91CF911F910F91FF90EF9023\r
+:1049F000DF90CF90BF90AF909F908F9008955FCF42\r
+:104A00002F923F924F925F926F927F928F929F92DE\r
+:104A1000AF92BF92CF92DF92EF92FF920F931F93CC\r
+:104A2000CF93DF93CDB7DEB7CA54D1090FB6F89450\r
+:104A3000DEBF0FBECDBF1C017E8B6D8B3A012BA359\r
+:104A40000EA3E8A6AEAABFAAC8AED9AE34E0239F93\r
+:104A500080011124400F511F5BAB4AABDA018D90EE\r
+:104A60009D90AD90BC90FC01E00FF11F2081318141\r
+:104A700042815381C501B4010E94FB4A6AAF7BAFFA\r
+:104A80008CAF9DAFEEA1B4E0EB9F700111249301B8\r
+:104A90002E0D3F1D3DAB2CABD9014D905D906D901F\r
+:104AA0007C90F101EE0DFF1D208131814281538107\r
+:104AB000C301B2010E94FB4A6EAF7FAF21968FAF58\r
+:104AC000219722969FAF2297E8A5B4E0EB9FC00103\r
+:104AD0001124F101E80FF91F2081318142815381B6\r
+:104AE0002B8F3C8F4D8F5E8FED89FE89E80FF91F6C\r
+:104AF00060817181828193810E94FA4A462F572FEB\r
+:104B0000682F792F498B5A8B6B8B7C8BAD89BE8933\r
+:104B10001C968D919D910D90BC91A02D8AA79BA76D\r
+:104B2000ACA7BDA7D1011C962D913D914D915C91F3\r
+:104B30001F972F8F38A349A35AA3B7FAB094B7F899\r
+:104B4000B09477FA709477F87094ED89FE89E00F4D\r
+:104B5000F11F7AAD6BAD9CAD8DAD272F362F492F50\r
+:104B6000582F60817181828193810E94FA4A6F8BF4\r
+:104B7000788F898F9DA3ED89FE89EE0DFF1D7EAD97\r
+:104B80006FAD21969FAD219722968FAD2297272F4B\r
+:104B9000362F492F582F60817181828193810E9425\r
+:104BA000FA4A162F072F382E292E7F89688D998D66\r
+:104BB0008DA1272F362F492F582FC501B4010E94F0\r
+:104BC000A94E6B017C01B801C101272F362F492F57\r
+:104BD000582FC301B2010E94A94E9B01AC01C7012D\r
+:104BE000B6010E94FB4A6B017C01B801C101272F6D\r
+:104BF000362F492F582FC501B4010E94A94E6EA728\r
+:104C00007FA788AB99AB7F89688D998D8DA1272F60\r
+:104C1000362F492F582FC301B2010E94A94E9B0184\r
+:104C2000AC016EA57FA588A999A90E94FA4AA7019F\r
+:104C300096010E946E4B362E272E182F092F20E04A\r
+:104C400030E0A901D101F8016B2F7A2F8F2F9E2F11\r
+:104C50000E94D44B87FF10C02BED3FE049EC50E49D\r
+:104C6000D101F8016B2F7A2F8F2F9E2F0E94FB4AC4\r
+:104C7000362E272E182F092FA4968FADA4978823A0\r
+:104C800081F02BED3FE049EC50E4D101F8016B2FAE\r
+:104C9000722D8F2F902F0E94FA4A362E272E182F12\r
+:104CA000092FC988DA88EB88FC88E894F7F8A3967E\r
+:104CB0002CAD3DAD4EAD5FADA397D101F8016B2F8B\r
+:104CC000722D8F2F902F0E94A94EA70196010E944E\r
+:104CD000E44D6B017C012FE632E143E85AE30E9488\r
+:104CE000D44B87FD79C2C701B6010E94B14C0E9426\r
+:104CF000484C7A8F698FFB01EF2B21F421E030E0E3\r
+:104D00003A8F298F498D5A8DBA0180E090E00E9438\r
+:104D1000744C6B017C019B01AC01D101F8016B2F3C\r
+:104D2000722D8F2F902F0E94DB4B6F8B788F1C0181\r
+:104D3000A701960169897A898B899C890E94DB4B3E\r
+:104D400024966FAF249725967FAF259726968FAF31\r
+:104D5000269727969FAF27972F8D38A149A15AA153\r
+:104D60006AA57BA58CA59DA50E94FA4AA70196017C\r
+:104D70000E94DB4B28966FAF289729967FAF299723\r
+:104D80002A968FAF2A972B969FAF2B9720E030E083\r
+:104D900040E05FE3BF89A88D6B2F7A2F822D932D82\r
+:104DA0000E94A94EBF89A88D2B2F3A2F422D532D3B\r
+:104DB0000E94A94E9B01AC0160E070E080E89FE397\r
+:104DC0000E94FA4A6DA37AA78EA723969FAF2397D6\r
+:104DD000CE010196FC01A8A554E0A59FE00DF11DB0\r
+:104DE00011242B8D3C8D4D8D5E8D2083318342832C\r
+:104DF00053832F8D38A149A15AA12D873E874F8714\r
+:104E0000588B198A41E050E05C8F4B8F81E090E035\r
+:104E10008C0F9D1FBBA1A4E0BA9F800D911D112492\r
+:104E200099A788A721E030E02C0F3D1F5EA144E048\r
+:104E3000549F200D311D11243FA32EA3FCA3EBA3EF\r
+:104E4000ABC1898989310CF050C07F89688D272FCB\r
+:104E5000362F422D532DC501B4010E94A94E6B017E\r
+:104E60007C017DA16AA59EA523968FAD2397272F50\r
+:104E7000362F492F582FC301B2010E94A94E9B0122\r
+:104E8000AC01C701B6010E94FB4A7B018C017DA1E8\r
+:104E90006AA59EA523968FAD2397272F362F492FDE\r
+:104EA000582FC501B4010E94A94E5B016C017F8996\r
+:104EB000688D272F362F422D532DC301B2010E943A\r
+:104EC000A94E9B01AC016A2D7B2D8C2D9D2D0E943E\r
+:104ED000FA4A862E972EA82EB92E99899F5F998B14\r
+:104EE0004E2C5F2C602E712E72C0AB8DBC8DBD011F\r
+:104EF00080E090E00E94744CBF89A88D2B2F3A2F40\r
+:104F0000422D532D0E94A94E7B018C017F2D802FB5\r
+:104F1000912F0E94D84B2B013C016E2D7F2D802FAD\r
+:104F2000912F0E940C4F698B7A8B8B8B9C8BEAA9FB\r
+:104F3000FBA980819181A281B3819C01AD01505870\r
+:104F40002F8F38A349A35AA3ACA9BDA9CD90DD905A\r
+:104F5000ED90FC90A30192016F8D78A189A19AA197\r
+:104F60000E94A94E4B015C0129893A894B895C89D1\r
+:104F7000C701B6010E94A94E9B01AC01C501B40155\r
+:104F80000E94FB4A862E972EA82EB92E29893A898F\r
+:104F90004B895C896F8D78A189A19AA10E94A94E45\r
+:104FA000698B7A8B8B8B9C8BA3019201C701B60115\r
+:104FB0000E94A94E9B01AC0169897A898B899C89E1\r
+:104FC0000E94FA4A462E572E682E792E198AA5017C\r
+:104FD0009401BAADABADFCADEDAD6B2F7A2F8F2F39\r
+:104FE0009E2F0E94FB4AE8A5F9A560837183828306\r
+:104FF0009383A3019201BEADAFAD2196FFAD219782\r
+:105000002296EFAD22976B2F7A2F8F2F9E2F0E9423\r
+:10501000FB4AAEA1BFA16D937D938D939C93139793\r
+:1050200024967FAD249725966FAD259726969FAD44\r
+:10503000269727968FAD2797272F362F492F582F42\r
+:10504000EBA1FCA160817181828193810E94FB4A66\r
+:10505000ABA1BCA16D937D938D939C9313972896E0\r
+:105060007FAD289729966FAD29972A969FAD2A97ED\r
+:105070002B968FAD2B97272F362F492F582F6D85C5\r
+:105080007E858F8598890E94FB4A6D877E878F87F2\r
+:10509000988B20E030E0A90169817A818B819C8125\r
+:1050A0000E94D44B87FF04C019821A821B821C8283\r
+:1050B00020E030E0A9016D817E818F8198850E947A\r
+:1050C000D44B87FF04C01D821E821F82188620E0F9\r
+:1050D00030E0A90169857A858B859C850E94D44B37\r
+:1050E00087FF04C019861A861B861C8620E030E0E4\r
+:1050F0004DE453E469817A818B819C810E94D74D74\r
+:10510000181644F480E090E0ADE4B3E489839A8318\r
+:10511000AB83BC8320E030E04DE453E46D817E81BD\r
+:105120008F8198850E94D74D181644F480E090E056\r
+:10513000ADE4B3E48D839E83AF83B88720E030E095\r
+:1051400040EF52E469857A858B859C850E94D74D16\r
+:10515000181644F480E090E0A0EFB2E489879A87C3\r
+:10516000AB87BC8794E6C92ED12CCC0EDD1EEEA8F1\r
+:10517000FFA808AD19AD9E01235F3F4FAE01475F09\r
+:105180005F4FBE016B5F7F4FCE010196B5D4EB8DB3\r
+:10519000FC8D3196FC8FEB8F2B8D3C8D498D5A8D7C\r
+:1051A0002417350708F44DCE2D893E89245F3F4FE3\r
+:1051B0004D895E89485F5F4F6D897E896C5F7F4F47\r
+:1051C00084E6C82ED12CCC0EDD1EEEA8FFA808ADBB\r
+:1051D00019AD8D899E8990D4C65BDF4F0FB6F894C8\r
+:1051E000DEBF0FBECDBFDF91CF911F910F91FF901A\r
+:1051F000EF90DF90CF90BF90AF909F908F907F9077\r
+:105200006F905F904F903F902F9008958F5F803107\r
+:1052100009F480E008952F923F924F925F926F922F\r
+:105220007F928F929F92AF92BF92CF92DF92EF9236\r
+:10523000FF920F931F93CF93DF93CDB7DEB768979D\r
+:105240000FB6F894DEBF0FBECDBF1C014A015B0153\r
+:1052500068017901DC01D8966D917D918D919C91C9\r
+:10526000DB970E94744C69837A838B839C83A501AE\r
+:1052700094010E94A94E0E94C14B0E94484C6D832C\r
+:105280007E838F839887A701960169817A818B81BC\r
+:105290009C810E94A94E0E94C14B0E94484C698784\r
+:1052A0007A878B879C872D813E814F81588528374F\r
+:1052B00031054105510540F488E790E0A0E0B0E0F9\r
+:1052C0008D839E83AF83B88729853A854B855C851E\r
+:1052D000283731054105510540F488E790E0A0E00A\r
+:1052E000B0E089879A87AB87BC87F101EC5BFF4F01\r
+:1052F0004080518062807380C301B2010E94764C6D\r
+:105300006B017C01D101DC966D917D918D919C9119\r
+:10531000DF970E94744C6D877E878F87988B20E083\r
+:1053200030E0A901C701B6010E94D44B882339F1AE\r
+:1053300029813A814B815C81CA01B9010E94A94E41\r
+:105340004B015C012D853E854F855889CA01B90105\r
+:105350000E94A94E9B01AC01C501B4010E94FA4A0A\r
+:105360004B015C01A7019601C701B6010E94FB4AEF\r
+:105370009B01AC01C501B4010E94DB4B04C060E09D\r
+:1053800070E080E090E00E94C14B0E94434C4B01D2\r
+:105390005C0166277727CB0164197509860997098F\r
+:1053A0000E94764C2B013C01F101E05CFF4F6081D3\r
+:1053B0007181828193810E94744C698B7A8B8B8B73\r
+:1053C0009C8B20E030E0A901C301B2010E94D44BC4\r
+:1053D000882379F129893A894B895C89CA01B90105\r
+:1053E0000E94A94E6D8B7E8B8F8B988F29813A817D\r
+:1053F0004B815C81CA01B9010E94A94E9B01AC019D\r
+:105400006D897E898F89988D0E94FA4A69837A8393\r
+:105410008B839C83A3019201C301B2010E94FB4ACA\r
+:105420009B01AC0169817A818B819C810E94DB4B5D\r
+:1054300004C060E070E080E090E00E94B14CD101D7\r
+:1054400050962D913D914D915C91539729833A83CC\r
+:105450004B835C8329013A01481859086A087B0884\r
+:105460000E94434C461A570A680A790A77FE6CC0B4\r
+:1054700020E030E0A901C701B6010E94D44B882387\r
+:1054800009F445C0A7019601C701B6010E94FB4A75\r
+:105490002B013C0169817A818B819C810E94744C33\r
+:1054A0009B01AC01C301B2010E94A94E2B013C013A\r
+:1054B0002D853E854F855889CA01B9010E94A94EA4\r
+:1054C0009B01AC01C301B2010E94FA4A2B013C01CD\r
+:1054D00029893A894B895C89CA01B9010E94A94E80\r
+:1054E0009B01AC01C301B2010E94FB4A4B015C016C\r
+:1054F00020E030E040E850E4C701B6010E94A94E28\r
+:105500009B01AC01C501B4010E94DB4B04C060E00B\r
+:1055100070E080E090E00E94C14B0E94434C4B0140\r
+:105520005C01B7FE03C0812C912C540129813A8182\r
+:105530004B815C8182169306A406B50610F04901E2\r
+:105540005A01412C512C32018FB7F894F101E45BE0\r
+:10555000FF4F9081911125C0D10154968D929D925B\r
+:10556000AD92BC925797480C591C6A1C7B1CF101E8\r
+:10557000408E518E628E738E2D813E814F81588573\r
+:10558000DC962D933D934D935C93DF97A05CBF4FCA\r
+:1055900029853A854B855C852D933D934D935C938E\r
+:1055A00013978FBF68960FB6F894DEBF0FBECDBFBE\r
+:1055B000DF91CF911F910F91FF90EF90DF90CF90EF\r
+:1055C000BF90AF909F908F907F906F905F904F9023\r
+:1055D0003F902F900895AF92BF92CF92DF92EF92BB\r
+:1055E000FF920F931F93CF93DF935B017A016115B5\r
+:1055F000710509F475C04115510509F471C0FB012D\r
+:1056000002A513A5D4A5C5A5CE01202F312F492F62\r
+:10561000582F66A177A180A591A50E94D44B88231D\r
+:1056200009F45EC0F50187A981114BC0F701C6A03E\r
+:10563000D7A0E0A4F1A4A7019601DE01602F712F8D\r
+:105640008B2F9A2F0E94D74D1816DCF5A7019601D3\r
+:10565000C701B6010E94A94E6B017C01F50182A928\r
+:1056600093A9A4A9B5A9BC01CD0190589B01AC0197\r
+:105670000E94FB4AF50126A537A540A951A90E9421\r
+:10568000A94E9B01AC01C701B6010E94FA4A0E94D3\r
+:10569000164F6B017C01762F272F3D2D4E2D5F2D50\r
+:1056A000FE01602F712F8F2F9E2F0E94D44B87FFFA\r
+:1056B00003C06801ED2EFC2E5C2D4D2D3E2D2F2DAF\r
+:1056C00003C0502F412F9E01852F942FA32FB22F5F\r
+:1056D000F50186A397A3A0A7B1A781E0F50186AB4A\r
+:1056E000DF91CF911F910F91FF90EF90DF90CF90BE\r
+:1056F000BF90AF900895CF92DF92FF920F931F93C8\r
+:10570000CF93DF931F92CDB7DEB7809108058091CC\r
+:1057100008052091070590E0821B91098F70992759\r
+:1057200004970CF12091080523502F7040E050E0C1\r
+:1057300000E010E08DE4F82E12C0211101C020E13C\r
+:105740002150F29E6001112489E095E0C80ED91E17\r
+:10575000B801C60129833FDFA80186012981809114\r
+:1057600007052813EACF0F90DF91CF911F910F917A\r
+:10577000FF90DF90CF9008952F923F924F925F92CB\r
+:105780006F927F928F929F92AF92BF92CF92DF9251\r
+:10579000EF92FF920F931F93CF93DF93EC011B01C6\r
+:1057A000009709F464C08FA9811161C08EA09FA0E9\r
+:1057B000A8A4B9A4FB01C6A0D7A0E0A4F1A42C2DF5\r
+:1057C0003D2D4E2D5F2DC501B4010E94D44B87FFA6\r
+:1057D0004EC0A5019401C501B4010E94A94E2B0140\r
+:1057E0003C018AA89BA8ACA8BDA8C501B4019058EB\r
+:1057F0009B01AC010E94FB4A2EA53FA548A959A9CF\r
+:105800000E94A94E9B01AC01C301B2010E94FA4A59\r
+:105810000E94164F8B01D82FC92F762FCE01272F2C\r
+:10582000312F492F582F6C2D7D2D8E2D9F2D0E94AD\r
+:10583000D44B87FF03C08601DE2DCF2DCE01202F54\r
+:10584000312F492F5C2F6C2D7D2D8E2D9F2D0E9489\r
+:10585000D44B882361F09E01802F912FA32FBC2F62\r
+:10586000F10186A397A3A0A7B1A781E086ABDF9142\r
+:10587000CF911F910F91FF90EF90DF90CF90BF904D\r
+:10588000AF909F908F907F906F905F904F903F90E0\r
+:105890002F900895EF92FF920F931F93CF93DF9372\r
+:1058A000F0900705C0E0D0E080E090E02DE4E22E2B\r
+:1058B0000DC0EF9C80011124075F1A4FA801BE01A3\r
+:1058C0005BDF8F2DA3DCF82ECE01E80120910805C7\r
+:1058D000F212EFCF40E050E0BE01DF91CF911F9177\r
+:1058E0000F91FF90EF9048CF4F925F926F927F920F\r
+:1058F0008F929F92AF92BF92CF92DF92EF92FF92E0\r
+:105900000F931F93CF93DF9350900705C0E0D0E033\r
+:105910003DE4432E34C0429E3001439E700C11245E\r
+:1059200089E095E0680E791E209729F18EA98111F2\r
+:1059300004C0F30186A98823F1F0CAA0DBA0ECA083\r
+:10594000FDA0A7019601F30166A177A180A591A50D\r
+:105950000E94DB4B4B015C01A70196016EA17FA168\r
+:1059600088A599A50E94DB4BAB01BC019501840180\r
+:10597000CE0151DC1EAA852D49DC582EE301252DD0\r
+:10598000332727FD30958091080590E028173907C7\r
+:1059900009F0C1CF2097E9F0CAA0DBA0ECA0FDA0E0\r
+:1059A000A70196016DEC7CEC8CE49DE30E94DB4B3F\r
+:1059B0004B015C01A70196016EA17FA188A599A565\r
+:1059C0000E94DB4BAB01BC0195018401CE0123DCBD\r
+:1059D0001EAADF91CF911F910F91FF90EF90DF9062\r
+:1059E000CF90BF90AF909F908F907F906F905F907F\r
+:1059F0004F90089580DE4EDF77CF10920805109209\r
+:105A0000070580E1E9EDF9E0DF011D928A95E9F7EC\r
+:105A10001092490A10924A0A10924B0A10924C0AAC\r
+:105A200010924D0A10924E0A10924F0A1092500A8C\r
+:105A30001092510A1092520A1092530A1092540A6C\r
+:105A40001092550A1092560A1092570A1092580A4C\r
+:105A50001092590A10925A0A10925B0A10925C0A2C\r
+:105A60000895CF939091070580910805981709F143\r
+:105A7000209107058DE4289FF0011124EF5AFA4F79\r
+:105A8000C08130E04DE410C0429FF0011124EF5A74\r
+:105A9000FA4F80819181A281B381892B8A2B8B2B34\r
+:105AA00009F03F5F2F5F2F70809108052813ECCF1E\r
+:105AB0000AC060918102662321F070E08EE00E94AE\r
+:105AC0000922C0E030E080918102811107C03111CC\r
+:105AD00005C060E070E08EE00E94092280918102A2\r
+:105AE000882341F0CC2331F06C2F70E08EE0CF9111\r
+:105AF0000C940922CF9108952F923F924F925F927A\r
+:105B00006F927F928F929F92AF92BF92CF92DF92CD\r
+:105B1000EF92FF920F931F93CF93DF93CDB7DEB732\r
+:105B2000CD56D1090FB6F894DEBF0FBECDBF2C0104\r
+:105B30003B014A015901EFA6FBAA0CAB19AFDEAE3F\r
+:105B4000CDAE8091080562DBAA968FAFAA97082F89\r
+:105B5000112707FD109505C00E94E24181E00E94D7\r
+:105B600038108091070590E080179107A9F32091E4\r
+:105B7000250A3091260A4091270A5091280AD2011D\r
+:105B80006D917D918D919C910E94A94E0E94794EBC\r
+:105B900060966FAF609761967FAF619762968FAFA7\r
+:105BA000629763969FAF63972091290A30912A0AE2\r
+:105BB00040912B0A50912C0AF301608171818281FE\r
+:105BC00093810E94A94E0E94794E64966FAF6497AC\r
+:105BD00065967FAF659766968FAF669767969FAF1E\r
+:105BE000679720912D0A30912E0A40912F0A5091EB\r
+:105BF000300AD4016D917D918D919C910E94A94EA6\r
+:105C00000E94794E68966FAF689769967FAF6997E3\r
+:105C10006A968FAF6A976B969FAF6B972091310A08\r
+:105C20003091320A4091330A5091340AF501608173\r
+:105C30007181828193810E94A94E0E94794E2296A1\r
+:105C40006FAF229723967FAF239724968FAF249729\r
+:105C500025969FAF25978091E5099091E609A0913F\r
+:105C6000E709B091E80925962CAD3DAD4EAD5FAD8D\r
+:105C70002597281739074A075B07C1F1609182020F\r
+:105C8000E62FF0E0EE0FFF1FE655F54F8081918182\r
+:105C90000E94164120E030E046E153E40E94D44BDC\r
+:105CA00087FF24C080910605811120C00C94D03755\r
+:105CB0009091C00095FFFCCF8093C60031968491EF\r
+:105CC0008111F6CFE7EBF4E007C09091C00095FF9B\r
+:105CD000FCCF8093C600319684918111F6CF8091DC\r
+:105CE000C00085FFFCCF8AE08093C6008091E50963\r
+:105CF0009091E609A091E709B091E80925962CADAD\r
+:105D00003DAD4EAD5FAD2597281B390B4A0B5B0BA4\r
+:105D1000CA01B90157FF07C09095809570956195AC\r
+:105D20007F4F8F4F9F4F0E94764C4B015C0120E0CC\r
+:105D300030E04DEC53E46091310A7091320A809169\r
+:105D4000330A9091340A0E94A94E9B01AC01C5010F\r
+:105D5000B4010E94D74D18167CF525968CAD9DADEB\r
+:105D6000AEADBFAD25978093E5099093E609A0936A\r
+:105D7000E709B093E809E1EBF4E007C09091C000B7\r
+:105D800095FFFCCF8093C600319684918111F6CFA8\r
+:105D9000E1EDF4E007C09091C00095FFFCCF809347\r
+:105DA000C600319684918111F6CF8091C00085FFA5\r
+:105DB000FCCF8AE08093C600809108059DE4899F0E\r
+:105DC00010011124A9E0B5E02A0E3B1EF101E45BAD\r
+:105DD000FF4F10822091D9093091DA094091DB09F7\r
+:105DE0005091DC092BA33CA34DA35EA363964CAC5E\r
+:105DF0005DAC6EAC7FAC6397421A530A640A750AB5\r
+:105E000077FE08C07094609450944094411C511CDB\r
+:105E1000611C711CD1014D925D926D927C92139721\r
+:105E20002091DD093091DE094091DF095091E009B0\r
+:105E30002FA338A749A75AA767968CAC9DACAEACE8\r
+:105E4000BFAC6797821A930AA40AB50AB7FE08C0C6\r
+:105E5000B094A09490948094811C911CA11CB11CBE\r
+:105E6000D10114968D929D92AD92BC92179720917C\r
+:105E7000E1093091E2094091E3095091E4092BA72F\r
+:105E80003CA74DA75EA76B964CAD5DAD6EAD7FADEB\r
+:105E90006B978BA59CA5ADA5BEA5481B590B6A0B9E\r
+:105EA0007B0B77FF07C070956095509541955F4FCC\r
+:105EB0006F4F7F4F142F052F26966FAF26977DAB20\r
+:105EC000D10118964C93189719965C9319971A96C6\r
+:105ED0006C931A971B967C93C090E509D090E609C5\r
+:105EE000E090E709F090E809A0910001B09101016C\r
+:105EF00025962CAD3DAD4EAD5FAD25972C193D09D6\r
+:105F00004E095F0957FF07C0509540953095219580\r
+:105F10003F4F4F4F5F4F0E94794F24E630E040E003\r
+:105F200050E00E94C34FF101248735874687578789\r
+:105F3000812F902F2696AFAD2697BDA9881599057C\r
+:105F4000AA05BB0514F4D501C40182179307A40761\r
+:105F5000B50714F4DA01C901930182014816590604\r
+:105F60006A067B0614F48C019D01D10150960D93B5\r
+:105F70001D932D933C935397063011052105310550\r
+:105F800010F40C94E237F101E85BFF4F809181023D\r
+:105F900090E0A0E0B0E080839183A283B383639616\r
+:105FA0002CAD3DAD4EAD5FAD63978BA19CA1ADA176\r
+:105FB000BEA1281739074A075B0724F0D101909644\r
+:105FC0001C9203C081E0F10180A367962CAD3DAD2A\r
+:105FD0004EAD5FAD67978FA198A5A9A5BAA5281763\r
+:105FE00039074A075B073CF4D10190968C91909752\r
+:105FF000826090968C936B962CAD3DAD4EAD5FADAF\r
+:106000006B978BA59CA5ADA5BEA5281739074A0798\r
+:106010005B073CF4D10190968C91909784609096A8\r
+:106020008C9325962CAD3DAD4EAD5FAD25972C15CF\r
+:106030003D054E055F053CF4D10190968C919097FB\r
+:10604000886090968C93EDADFEAD8081D1019196E4\r
+:106050008C9345284628472809F05A9AF1018481F3\r
+:106060009581A681B781892B8A2B8B2B09F05A9AAF\r
+:10607000F10180859185A285B385892B8A2B8B2B95\r
+:1060800009F05A9AF10184859585A685B785892BF3\r
+:106090008A2B8B2B09F05A9AD1011C962D913D9198\r
+:1060A0004D915C911F972F962CAF3DAF4EAF5FAFD8\r
+:1060B0002F97232B242B252BE9F44090F90950909E\r
+:1060C000FA096090FB097090FC09242D352D462DAE\r
+:1060D000572DBFA5ABA9FCA9E9AD6B2F7A2F8F2F48\r
+:1060E0009E2F0E94D44B87FD0EC04FA45BA86CA8C6\r
+:1060F00079AC09C04090110A5090120A6090130ABE\r
+:106100007090140AE2CF63966CAD7DAD8EAD9FADFD\r
+:1061100063972BA13CA14DA15EA1621B730B840B65\r
+:10612000950B0E94764C2091250A3091260A4091C9\r
+:10613000270A5091280A0E94DB4B6BA37FA78BABE9\r
+:106140009CAB362F272F982F8CA9432F522F692FC6\r
+:10615000782F498B5A8B6B8B7C8B67966CAD7DADA2\r
+:106160008EAD9FAD67972FA138A549A55AA5621B93\r
+:10617000730B840B950B0E94764C2091290A309169\r
+:106180002A0A40912B0A50912C0A0E94DB4B162FB1\r
+:10619000072F8FA399AF9801982F89AD432F522FC6\r
+:1061A000692F782F4D8B5E8B6F8B788F6B966CADD4\r
+:1061B0007DAD8EAD9FAD6B972BA53CA54DA55EA586\r
+:1061C000621B730B840B950B0E94764C20912D0A59\r
+:1061D00030912E0A40912F0A5091300A0E94DB4BD9\r
+:1061E0006BA77DAF26968FAF26979DAB362F272FB7\r
+:1061F000982F8DA9432F522F692F782F498F5A8FAF\r
+:106200006B8F7C8FA0900001B090010125966CAD42\r
+:106210007DAD8EAD9FAD25976C197D098E099F09C7\r
+:106220000E94764C2091310A3091320A4091330A13\r
+:106230005091340A0E94DB4B6B017C01B501882729\r
+:1062400077FD8095982F0E94764C9B01AC01C70189\r
+:10625000B6010E94A94E20E030E048EC52E40E94D2\r
+:10626000DB4B462F572F682F792FDB01CA014D8F4B\r
+:106270005E8F6F8F78A3F10180809180A280B380C0\r
+:10628000F6E08F169104A104B104DCF4F10144811D\r
+:1062900055816681778146305105610571058CF421\r
+:1062A00040855185628573854630510561057105CC\r
+:1062B00044F4AC01BD017F7746A757A760AB71AB33\r
+:1062C0003CC05BA14FA53BA92CA9652F742F832F40\r
+:1062D000922F0E94544F6B017C01A8013FA129AD70\r
+:1062E000652F702F832F922F0E94544F9B01AC017A\r
+:1062F000C701B6010E94FB4A162F072FF82EE92E80\r
+:106300005BA54DAD26963FAD26972DA9652F742F21\r
+:10631000832F922F0E94544F9B01AC01D801F701AB\r
+:106320006B2F7A2F8F2F9E2F0E94FB4A0E94164FB1\r
+:10633000F10166A777A780AB91ABD1019E962D9115\r
+:106340003D914D915C91D19729962CAF3DAF4EAFC9\r
+:106350005FAF299760E070E080E89FE30E94DB4B2D\r
+:106360009B01AC01642D752D862D972D0E94A94EA1\r
+:106370006FA77BAB8CAB9DAF909108058091070513\r
+:10638000E92FF0E0E81BF109EF70FF27FAAFE9AF62\r
+:10639000762F6BA99CA98DAD272F362F492F582F0B\r
+:1063A00060E074E284E799E40E94DB4B0E94794E3E\r
+:1063B0006BA37FA38C0129AD3AAD223031050CF4DB\r
+:1063C0004BC06901EE24D7FCE094FE2CC701B60156\r
+:1063D0000E94764C20E030E040E051E40E94D44B33\r
+:1063E00087FF3AC04BA05FA038018091450A909189\r
+:1063F000460AA091470AB091480A481659066A060B\r
+:106400007B0650F5BC01CD01641975098609970911\r
+:10641000660F771F881F991FA70196010E94A14F41\r
+:10642000CA01B9010E94744C0E94794EAB01BC01B3\r
+:10643000CB01BA01640D751D861D971D0E94744C19\r
+:106440009B01AC0160E074E284E799E40E94DB4BBD\r
+:106450006FA77BAB8CAB9DAF7FA56BA99CA98DADC6\r
+:10646000272F362F492F582F29966CAD7DAD8EAD35\r
+:106470009FAD29970E94A94EA6966FAFA697A796A3\r
+:106480007FAFA797A8968FAFA897A9969FAFA99718\r
+:10649000362F272F982FA9968FADA997432F522FCC\r
+:1064A000692F782FD10192964D935D936D937C93D4\r
+:1064B000959750966D917D918D919C9153970E94E7\r
+:1064C000744C6B017C017FA56BA99CA98DAD272F16\r
+:1064D000362F492F582FC701B6010E94A94E0E949E\r
+:1064E000C14B0E94484C6F966CAF7DAF8EAF9FAF93\r
+:1064F0006F97F10160AF71AF82AF93AF9E012F5ED6\r
+:106500003F4F3EAB2DABAE014F5F5F4F5CA74BA73C\r
+:1065100085E39AE0A5969FAF8EAFA597DE01919691\r
+:10652000BAA3A9A32B965FAF4EAF2B971BA21FA2B6\r
+:1065300000E81FE3EDA9FEA961917191819191910C\r
+:10654000FEABEDABBFA5ABA9FCA9EDAD2B2F3A2F50\r
+:106550004F2F5E2F0E94A94EAB01BC012B96AEAD12\r
+:10656000BFAD2B974D935D936D937D932B96BFAFEE\r
+:10657000AEAF2B97DB01CA01BF77A3968CAF9DAF5F\r
+:10658000AEAFBFAFA397A596AEADBFADA5974D90EB\r
+:106590005D906D907D90A596BFAFAEAFA597A3011E\r
+:1065A0009201A3966CAD7DAD8EAD9FADA3970E9479\r
+:1065B000D74D18160CF5A3962CAD3DAD4EAD5FAD85\r
+:1065C000A397C301B2010E94DB4B2B01782E692EE9\r
+:1065D000762FC301272F352D492F582FBBA1AFA1EF\r
+:1065E0006B2F7A2F802F912F0E94D44B87FD04C0F0\r
+:1065F0004BA25FA2072D162DEDA9FEA929A13AA154\r
+:10660000E217F30709F096CF20E030E040E85FE3BF\r
+:10661000BBA1AFA16B2F7A2F802F912F0E94D44B5B\r
+:1066200087FF53C03E0131E1630E711C7BA16FA156\r
+:10663000272F362F402F512FABA5BCA56D917D91F3\r
+:106640008D919C910E94A94EEBA5FCA5619371933D\r
+:1066500081939193FCA7EBA7E615F70539F77BA18A\r
+:106660006FA1272F362F402F512FA696BFADA6978B\r
+:10667000A796AFADA797A896FFADA897A996EFAD3F\r
+:10668000A9976B2F7A2F8F2F9E2F0E94A94ED10191\r
+:1066900092966D937D938D939C9395976F966CAD29\r
+:1066A0007DAD8EAD9FAD6F970E94744CBBA1AFA125\r
+:1066B0002B2F3A2F402F512F0E94A94E0E94484C59\r
+:1066C000F10160AF71AF82AF93AF29962CAD3DADB4\r
+:1066D0004EAD5FAD2997C701B6010E94DB4B162F67\r
+:1066E000072F8FA39BA781149104A104B10489F5FE\r
+:1066F000F10184819581A681B781892B8A2B8B2B0F\r
+:1067000041F580859185A285B385892B8A2B8B2BBA\r
+:1067100001F52091090A30910A0A40910B0A509123\r
+:106720000C0AD801FFA1EBA56B2F7A2F8F2F9E2F7C\r
+:106730000E94A94E0E94C14B7101F4E4EF0EF11CBE\r
+:106740000E94484CD7016D937D938D939C93139732\r
+:10675000FDC020910D0A30910E0A40910F0A509110\r
+:10676000100AD801FFA1EBA56B2F702F8F2F9E2F42\r
+:106770000E94A94E0E94C14B0E94484CF101EC5B63\r
+:10678000FF4FFCA3EBA360837183828393834090CC\r
+:10679000E9095090EA096090EB097090EC090E94B9\r
+:1067A000744C6FA778AB89AB9AABC501B4010E945A\r
+:1067B000764C9B01AC016FA578A989A99AA90E9482\r
+:1067C000A94EA70196010E94DB4B4B015C01C3015E\r
+:1067D000B2010E94744C9B01AC01C501B4010E943E\r
+:1067E000D74D181634F4EBA1FCA14082518262828D\r
+:1067F00073824090ED095090EE096090EF0970901F\r
+:10680000F009ABA1BCA16D917D918D919C910E94ED\r
+:10681000744C4B015C01F101648175818681978123\r
+:106820000E94764C9B01AC01C501B4010E94A94EA7\r
+:10683000A70196010E94DB4B4B015C01C301B20131\r
+:106840000E94744C9B01AC01C501B4010E94D74D5C\r
+:1068500018163CF4ABA1BCA14D925D926D927C9256\r
+:1068600013974090F5095090F6096090F7097090E1\r
+:10687000F809F101EC5BFF4FFCA3EBA36081718190\r
+:10688000828193810E94744C4B015C012F966CAD08\r
+:106890007DAD8EAD9FAD2F970E94764C9B01AC01D4\r
+:1068A000C501B4010E94A94EA70196010E94DB4BCD\r
+:1068B0004B015C01C301B2010E94744C9B01AC010D\r
+:1068C000C501B4010E94D74D18163CF4ABA1BCA180\r
+:1068D0004D925D926D927C9213974090F109509089\r
+:1068E000F2096090F3097090F409EBA1FCA16081BA\r
+:1068F0007181828193810E94744C4B015C01D101B2\r
+:1069000018966D917D918D919C911B970E94764C6C\r
+:106910009B01AC01C501B4010E94A94EA7019601DB\r
+:106920000E94DB4B6B017C01C301B2010E94744CDD\r
+:106930009B01AC01C701B6010E94D74D181634F473\r
+:10694000EBA1FCA14082518262827382F101EC5B77\r
+:10695000FF4F60817181828193810E94744C6B0131\r
+:106960007C01B8019FA18BA5272F302F492F582FCD\r
+:10697000C701B6010E94DB4B462F572F682F792F96\r
+:10698000AE964CAF5DAF6EAF7FAFAE97D101D296F2\r
+:106990004D935D936D937C93D5972DEB37E346E054\r
+:1069A00051E4C701B6010E94A94E0E94434CF10177\r
+:1069B000648F758F868F978F4090050A5090060AD6\r
+:1069C0006090070A7090080A29853A854B855C8596\r
+:1069D0006F962CAF3DAF4EAF5FAF6F978090010ABF\r
+:1069E0009090020AA090030AB090040A20E030E0E0\r
+:1069F00040E05FE3C501B4010E94A94E6BA37FA3F1\r
+:106A00008C016F966CAD7DAD8EAD9FAD6F979F770E\r
+:106A1000BBA1AFA12B2F3A2F402F512F0E94D74D52\r
+:106A200018165CF020E030E040E05FE3C301B20103\r
+:106A30000E94A94E6BA37FA38C01D1019296BC91B9\r
+:106A4000BBA7F101F3A1FFA7D1019496BC91BBAB09\r
+:106A5000F101F5A1FCAB7BA56FA5272F362F4B2F9E\r
+:106A60005F2FBBA1AFA16B2F7A2F802F912F0E9498\r
+:106A7000D44B87FD06C02BA52BA33FA53FA30BA995\r
+:106A80001CA98D859E85AF85B889A3968CAF9DAFD7\r
+:106A9000AEAFBFAFA397C090FD09D090FE09E090C4\r
+:106AA000FF09F090000A20E030E040E05FE3C7011A\r
+:106AB000B6010E94A94E6DAF7DAB2A968FAF2A9783\r
+:106AC0002C969FAF2C97A3966CAD7DAD8EAD9FADF0\r
+:106AD000A3979F77BDADADA92A96FFAD2A972C96B7\r
+:106AE000EFAD2C972B2F3A2F4F2F5E2F0E94D74DB3\r
+:106AF000181604F57DAD6DA92A969FAD2A972C96A0\r
+:106B00008FAD2C97272F362F492F582FBBA1AFA120\r
+:106B10006B2F7A2F802F912F0E94D44B87FD0AC0B4\r
+:106B20009DAD9BA3ADA9AFA32A960FAD2A972C9636\r
+:106B30001FAD2C97E9ADFAAD32970CF434C127E1C3\r
+:106B400037EB41ED58E36091590A70915A0A8091F0\r
+:106B50005B0A90915C0A0E94D74D18160CF023C175\r
+:106B60002091490A30914A0A40914B0A50914C0AAF\r
+:106B700029AF3AAF4BAF5CAF69817A818B819C8141\r
+:106B80000E94FA4A6DAB2A967FAF2A972C968FAF58\r
+:106B90002C97A4969FAFA49780914D0A90914E0A8E\r
+:106BA000A0914F0AB091500A21968CAF9DAFAEAF25\r
+:106BB000BFAF21979C01AD016D817E818F8198854A\r
+:106BC0000E94FA4AA6966FAFA697A7967FAFA7979F\r
+:106BD000A8968FAFA897A9969FAFA9977DA92A9647\r
+:106BE0006FAD2A972C969FAD2C97A4968FADA49746\r
+:106BF000272F362F492F582FDB01FC016B2F7A2FBF\r
+:106C00008F2F9E2F0E94A94E6DAB7EAB8FAB98AF9E\r
+:106C1000A6967FADA697A7966FADA797A8969FADAE\r
+:106C2000A897A9968FADA997272F362F492F582FB0\r
+:106C3000DB01FC016B2F7A2F8F2F9E2F0E94A94E14\r
+:106C40009B01AC016DA97EA98FA998AD0E94FB4A5A\r
+:106C50000E94164F6DAB7EAB8FAB98AF69AD7AAD2E\r
+:106C60008BAD9CAD9F7727E137EB41ED58E30E9458\r
+:106C7000D74D181684F021966CAD7DAD8EAD9FADCD\r
+:106C800021979F7727E137EB41ED58E30E94D74DDD\r
+:106C9000181634F00BC09BA59BA3AFA5AFA304C0EF\r
+:106CA000BBA5BBA3EFA5EFA30BA91CA9A301920150\r
+:106CB0006DA97EA98FA998AD0E94D74D1816ACF486\r
+:106CC0002DA93EA94FA958ADC301B2010E94DB4BCB\r
+:106CD0009B01AC01BBA1AFA16B2F7A2F802F912F0D\r
+:106CE0000E94A94E6BA37FA38C012091510A309181\r
+:106CF000520A4091530A5091540A6F966CAD7DAD83\r
+:106D00008EAD9FAD6F970E94FA4A2B013C01E8942B\r
+:106D100077F8A5019401C301B2010E94D74D18165E\r
+:106D20009CF4A3019201C501B4010E94DB4B9B01BD\r
+:106D3000AC01BBA1AFA16B2F7A2F802F912F0E94A6\r
+:106D4000A94E6BA37FA38C012091550A3091560A5E\r
+:106D50004091570A5091580AA3966CAD7DAD8EAD07\r
+:106D60009FADA3970E94FA4A4B015C01E894B7F8E3\r
+:106D7000A7019601C501B4010E94D74D18169CF4D5\r
+:106D8000A5019401C701B6010E94DB4B9B01AC0138\r
+:106D9000BBA1AFA16B2F7A2F802F912F0E94A94EFC\r
+:106DA0006BA37FA38C013BA12FA1432F522F602FF8\r
+:106DB000712FD1019A964D935D936D937C939D971E\r
+:106DC000AE966CAD7DAD8EAD9FADAE9790589B01EC\r
+:106DD000AC010E94FB4A29962CAD3DAD4EAD5FAD96\r
+:106DE00029970E94A94E9B01AC016BE077ED83E2ED\r
+:106DF0009BE30E94FA4A0E94164F6B01F82EE92E7F\r
+:106E0000762FC701272F3D2D492F582FBBA1AFA1AA\r
+:106E10006B2F7A2F802F912F0E94D44B87FD04C0B7\r
+:106E2000CBA2DFA20F2D1E2D3BA12FA1432F522F4E\r
+:106E3000602F712FF10146A357A360A771A7C70167\r
+:106E40002C2D3D2D492F5E2DBBA5AFA5FBA9ECA98F\r
+:106E50006B2F7A2F8F2F9E2F0E94D44B18162CF059\r
+:106E600081E0D101D7968C9302C0F10117AA81E08D\r
+:106E7000D101D6968C9380E1FE013196A9E4BAE067\r
+:106E800001900D928A95E1F73BA52FA59BA98CA9AE\r
+:106E9000432F522F692F782F4093590A50935A0A43\r
+:106EA00060935B0A70935C0A232F352F492F582F6C\r
+:106EB0006DEC7CEC8CE49DE30E94DB4B6B017C0170\r
+:106EC0007BA56FA59BA98CA9272F362F492F582F5B\r
+:106ED000BBA1AFA16B2F7A2F802F912F0E94DB4B8C\r
+:106EE000AB01BC0197018601C1010E940B29AA9642\r
+:106EF000BFADAA97B093080563962CAD3DAD4EADDE\r
+:106F00005FAD63972093D9093093DA094093DB0989\r
+:106F10005093DC0967968CAD9DADAEADBFAD679764\r
+:106F20008093DD099093DE09A093DF09B093E00917\r
+:106F30006B962CAD3DAD4EAD5FAD6B972093E109E7\r
+:106F40003093E2094093E3095093E40925968CAD10\r
+:106F50009DADAEADBFAD25978093E5099093E60951\r
+:106F6000A093E709B093E8090E94FA2CC359DF4FB8\r
+:106F70000FB6F894DEBF0FBECDBFDF91CF911F914A\r
+:106F80000F91FF90EF90DF90CF90BF90AF909F90C8\r
+:106F90008F907F906F905F904F903F902F90A9C1FE\r
+:106FA00025962CAD3DAD4EAD5FAD25972093E509FF\r
+:106FB0003093E6094093E7095093E809E1EBF4E0E8\r
+:106FC0000C945F2EC359DF4F0FB6F894DEBF0FBE8F\r
+:106FD000CDBFDF91CF911F910F91FF90EF90DF9088\r
+:106FE000CF90BF90AF909F908F907F906F905F9069\r
+:106FF0004F903F902F900895EF92FF920F931F9321\r
+:10700000CF93DF937B018A01E9012091250A30911A\r
+:10701000260A4091270A5091280AFC01608171815B\r
+:10702000828193810E94A94E0E94794EE9EDF9E098\r
+:1070300060837183828393832091290A30912A0A85\r
+:1070400040912B0A50912C0AF70160817181828155\r
+:1070500093810E94A94E0E94794EEDEDF9E0608384\r
+:1070600071838283938320912D0A30912E0A40915F\r
+:107070002F0A5091300AF8016081718182819381D9\r
+:107080000E94A94E0E94794EE1EEF9E0608371837F\r
+:10709000828393832091310A3091320A4091330ADE\r
+:1070A0005091340A688179818A819B810E94A94E1E\r
+:1070B0000E94794EE5EEF9E06083718382839383C9\r
+:1070C0009F0141EE59E06DED79E089ED99E05AD7E5\r
+:1070D0001092590A10925A0A10925B0A10925C0A96\r
+:1070E0001092490A10924A0A10924B0A10924C0AC6\r
+:1070F00010924D0A10924E0A10924F0A1092500AA6\r
+:107100001092510A1092520A1092530A1092540A85\r
+:107110001092550A1092560A1092570A1092580A65\r
+:10712000DF91CF911F910F91FF90EF9008952091E3\r
+:10713000310A3091320A4091330A5091340AFC01ED\r
+:1071400060817181828193810E94A94E0E94794E53\r
+:10715000E5EEF9E06083718382839383CF014EC7AC\r
+:1071600080930605089580916F0A8111B5C08091C2\r
+:107170006E0A8111B1C080916D0A8111ADC0089570\r
+:107180009091C00095FFFCCF8093C600319684910A\r
+:107190008111F6CFE5EFF4E007C09091C00095FFB4\r
+:1071A000FCCF8093C600319684918111F6CF8091F7\r
+:1071B0006F0A882349F1E4E0F5E007C09091C00030\r
+:1071C00095FFFCCF8093C600319684918111F6CF54\r
+:1071D0006091700A7091710A8091720A9091730A9D\r
+:1071E0000E94764C2091250A3091260A4091270A68\r
+:1071F0005091280A0E94DB4BAB01BC0122E030E039\r
+:1072000081E894E00E94FF2480916E0A882349F16E\r
+:10721000E8E0F5E007C09091C00095FFFCCF8093B7\r
+:10722000C600319684918111F6CF6091740A7091F5\r
+:10723000750A8091760A9091770A0E94764C209187\r
+:10724000290A30912A0A40912B0A50912C0A0E9457\r
+:10725000DB4BAB01BC0122E030E081E894E00E940E\r
+:10726000FF2480916D0A882349F1ECE0F5E007C026\r
+:107270009091C00095FFFCCF8093C6003196849119\r
+:107280008111F6CF6091780A7091790A80917A0A1B\r
+:1072900090917B0A0E94764C20912D0A30912E0A03\r
+:1072A00040912F0A5091300A0E94DB4BAB01BC0188\r
+:1072B00022E030E081E894E00E94FF248091C00049\r
+:1072C00085FFFCCF8AE08093C60010926F0A10926F\r
+:1072D0006E0A10926D0A0895EFEEF4E058CF109206\r
+:1072E0006F0A10926E0A10926D0A08958093210120\r
+:1072F0000895EFE6F0E080818260808308951F9218\r
+:107300000F920FB60F9211240F931F932F933F9359\r
+:107310004F935F936F937F938F939F93AF93BF939D\r
+:10732000EF93FF938091800A9091810A892B09F055\r
+:1073300056C19091080580910705981771F0E0916A\r
+:1073400007058DE4E89FF0011124E75FFA4FDF01A4\r
+:10735000A45BBF4F81E08C9302C0E0E0F0E0F093CB\r
+:10736000810AE093800A309709F433C1DF01A45BFE\r
+:10737000BF4F81E08C931092820A1092830A109280\r
+:10738000840A1092850A94AD85AD9093860A809305\r
+:10739000870A692F782F613187E2780710F060E162\r
+:1073A00077E281E08093880A6832710510F468E220\r
+:1073B00070E068527109611588E07807E0F0872F66\r
+:1073C0009927880F991F880F991F805F9A4FFC019A\r
+:1073D000329625913491AA27639FA001629F410DA7\r
+:1073E0005A1F06944A1F5A1F1124FC0125913491FB\r
+:1073F000241B350B1EC0CB01969587958C7F805F33\r
+:10740000964FFC01259134910296FC0145915491CF\r
+:10741000FB01E770FF274E9FC0014F9F900D5E9FBD\r
+:10742000900D1124A3E096958795AA95E1F7281B66\r
+:10743000390B24363105A0F4E8E5F2E006C090915E\r
+:10744000C00095FFFCCF8093C60081918111F7CFDA\r
+:107450004AE050E081E894E00E94572424E630E0BE\r
+:10746000C901A0E0B0E08093890A90938A0AA093B2\r
+:107470008B0AB0938C0A3093890020938800E091A6\r
+:10748000800AF091810A60AD71AD613187E27807C1\r
+:1074900010F060E177E281E08093880A683271053C\r
+:1074A00010F468E270E068527109611588E07807AD\r
+:1074B000D0F0872F9927880F991F880F991F805F19\r
+:1074C0009A4FFC01329645915491AA27659F9001ED\r
+:1074D000649F210D3A1F06942A1F3A1F1124FC01B4\r
+:1074E000859194911DC09B01369527952C7F205F37\r
+:1074F000364FF901859194912E5F3F4FF9014591E7\r
+:107500005491FB01E770FF274E9F90014F9F300D74\r
+:107510005E9F300D112443E0369527954A95E1F79B\r
+:10752000821B930B84369105A0F4E8E5F2E006C0D7\r
+:107530009091C00095FFFCCF8093C600819181118E\r
+:10754000F7CF4AE050E081E894E00E94572484E6B7\r
+:1075500090E090938E0A80938D0AE091800AF091DA\r
+:10756000810A80899189A289B389B695A795979553\r
+:107570008795B095A095909581959F4FAF4FBF4F40\r
+:1075800080938F0A9093900AA093910AB093920AE5\r
+:107590008093930A9093940AA093950AB093960AC5\r
+:1075A0008093970A9093980AA093990AB0939A0AA5\r
+:1075B00080939B0A90939C0AA0939D0AB0939E0A85\r
+:1075C00010927C0A10927D0A10927E0A10927F0A15\r
+:1075D00006C080ED97E09093890080938800E09149\r
+:1075E000800AF091810A309709F46EC480A18093DB\r
+:1075F0009F0A80FF3BC016988FEF80931D018091FA\r
+:1076000021018823B9F123B1217031E0232759F1F9\r
+:107610008091A00A882339F180819181A281B38170\r
+:10762000181619061A061B06F4F480915D0A90914B\r
+:107630005E0AA0915F0AB091600A8093700A9093ED\r
+:10764000710AA093720AB093730A30936F0A80890B\r
+:107650009189A289B38980937C0A90937D0AA09333\r
+:107660007E0AB0937F0A2093A00A04C0169A81E094\r
+:1076700080931D0180919F0A81FF40C0149A8FEF73\r
+:1076800080931E01809121018823E1F123B131E033\r
+:1076900026952170232779F18091A10A882359F139\r
+:1076A000E091800AF091810A84819581A681B78159\r
+:1076B000181619061A061B06F4F48091610A9091B7\r
+:1076C000620AA091630AB091640A8093740A90934D\r
+:1076D000750AA093760AB093770A30936E0A808970\r
+:1076E0009189A289B38980937C0A90937D0AA093A3\r
+:1076F0007E0AB0937F0A2093A10A04C0149881E007\r
+:1077000080931E0180919F0A82FF41C046988FEFAF\r
+:1077100080931F01809121018823E9F123B131E099\r
+:1077200022FB222720F9232779F18091A20A8823BE\r
+:1077300059F1E091800AF091810A80859185A285B6\r
+:10774000B385181619061A061B06F4F48091650A0B\r
+:107750009091660AA091670AB091680A8093780AAE\r
+:107760009093790AA0937A0AB0937B0A30936D0ABA\r
+:1077700080899189A289B38980937C0A90937D0A3C\r
+:10778000A0937E0AB0937F0A2093A20A04C0469A6F\r
+:1077900081E080931F0180919F0A83FF03C0459879\r
+:1077A0008FEF02C0459A81E08093200120E030E015\r
+:1077B000BDC18091C00087FF19C0E091C600409113\r
+:1077C000020550910305CA0101968F7799276091B0\r
+:1077D0000405709105058617970741F0DA01AE5749\r
+:1077E000BB4FEC939093030580930205E091800AD0\r
+:1077F000F091810A80918F0A9091900AA091910A4C\r
+:10780000B091920A4081518162817381840F951FEA\r
+:10781000A61FB71F80938F0A9093900AA093910A96\r
+:10782000B093920A181619061A061B060CF4159A3C\r
+:107830008091930A9091940AA091950AB091960A2A\r
+:107840004481558166817781840F951FA61FB71FDC\r
+:107850008093930A9093940AA093950AB093960A02\r
+:10786000181619061A061B060CF4139AE091800AE2\r
+:10787000F091810A8091970A9091980AA091990AB3\r
+:10788000B0919A0A4085518562857385840F951F52\r
+:10789000A61FB71F8093970A9093980AA093990AFE\r
+:1078A000B0939A0A181619061A061B060CF4479A82\r
+:1078B00080919B0A90919C0AA0919D0AB0919E0A8A\r
+:1078C0004485558566857785840F951FA61FB71F4C\r
+:1078D00080939B0A90939C0AA0939D0AB0939E0A62\r
+:1078E000181619061A061B060CF4179A80918F0AAF\r
+:1078F0009091900AA091910AB091920A18161906D7\r
+:107900001A061B065CF5E091800AF091810A408915\r
+:10791000518962897389841B950BA60BB70B8093E1\r
+:107920008F0A9093900AA093910AB093920A409183\r
+:107930001D0180915D0A90915E0AA0915F0AB0914D\r
+:10794000600A840F911DA11DB11D80935D0A909363\r
+:107950005E0AA0935F0AB093600A15988091930A1B\r
+:107960009091940AA091950AB091960A181619065A\r
+:107970001A061B065CF5E091800AF091810A4089A5\r
+:10798000518962897389841B950BA60BB70B809371\r
+:10799000930A9093940AA093950AB093960A409103\r
+:1079A0001E018091610A9091620AA091630AB091D0\r
+:1079B000640A840F911DA11DB11D8093610A9093EB\r
+:1079C000620AA093630AB093640A13988091970A9D\r
+:1079D0009091980AA091990AB0919A0A18161906DE\r
+:1079E0001A061B065CF5E091800AF091810A408935\r
+:1079F000518962897389841B950BA60BB70B809301\r
+:107A0000970A9093980AA093990AB0939A0A409182\r
+:107A10001F018091650A9091660AA091670AB09152\r
+:107A2000680A840F911DA11DB11D8093650A909372\r
+:107A3000660AA093670AB093680A479880919B0AE8\r
+:107A400090919C0AA0919D0AB0919E0A1816190661\r
+:107A50001A061B065CF5E091800AF091810A4089C4\r
+:107A6000518962897389841B950BA60BB70B809390\r
+:107A70009B0A90939C0AA0939D0AB0939E0A409102\r
+:107A800020018091690A90916A0AA0916B0AB091D5\r
+:107A90006C0A840F911DA11DB11D8093690A9093FA\r
+:107AA0006A0AA0936B0AB0936C0A179880917C0ABB\r
+:107AB00090917D0AA0917E0AB0917F0A0196A11D46\r
+:107AC000B11D80937C0A90937D0AA0937E0AB093A7\r
+:107AD0007F0A40917C0A50917D0A60917E0A7091E4\r
+:107AE0007F0A2F5F3F4FE091800AF091810A8089E1\r
+:107AF0009189A289B389481759076A077B07B0F0B3\r
+:107B000040917C0A50917D0A60917E0A70917F0AB3\r
+:107B1000E091800AF091810A84899589A689B789C4\r
+:107B200084179507A607B70748F4CBC08091880A49\r
+:107B300090E0281739070CF43CCEE2CF4091890A37\r
+:107B400050918A0A60918B0A70918C0A048D158D70\r
+:107B5000268D378DAA27419FB12D529FC001629F6C\r
+:107B6000900D619F800D911D429FB00D811D9A1F48\r
+:107B7000519FB00D811D9A1F609FB00D811D9A1FEE\r
+:107B8000509FB10D8A1F9A1FB6958A1F9A1F112404\r
+:107B900044AD55AD480F591F5093870A4093860A4C\r
+:107BA00080AD91ADA2ADB3AD60E070E084179507F4\r
+:107BB000A607B70720F49093870A8093860A6091FE\r
+:107BC000860A7091870A613187E2780710F060E1D8\r
+:107BD00077E281E08093880A6832710510F468E2E8\r
+:107BE00070E068527109611588E07807E0F0872F2E\r
+:107BF0009927880F991F880F991F805F9A4FFC0162\r
+:107C0000329625913491AA27639FA001629F410D6E\r
+:107C10005A1F06944A1F5A1F1124FC0125913491C2\r
+:107C2000241B350B1EC0CB01969587958C7F805FFA\r
+:107C3000964FFC01259134910296FC014591549197\r
+:107C4000FB01E770FF274E9FC0014F9F900D5E9F85\r
+:107C5000900D1124A3E096958795AA95E1F7281B2E\r
+:107C6000390B24363105A0F4E8E5F2E006C0909126\r
+:107C7000C00095FFFCCF8093C60081918111F7CFA2\r
+:107C80004AE050E081E894E00E94572424E630E086\r
+:107C900030938900209388008091890A90918A0A04\r
+:107CA000A0918B0AB0918C0A820F931FA11DB11D68\r
+:107CB0008093890A90938A0AA0938B0AB0938C0AC6\r
+:107CC000DEC040917C0A50917D0A60917E0A7091DD\r
+:107CD0007F0A808D918DA28DB38D84179507A6079D\r
+:107CE000B70708F0C4C04091820A5091830A60919E\r
+:107CF000840A7091850A048D158D268D378DAA27EB\r
+:107D0000419FB12D529FC001629F900D619F800DD8\r
+:107D1000911D429FB00D811D9A1F519FB00D811D75\r
+:107D20009A1F609FB00D811D9A1F509FB10D8A1F31\r
+:107D30009A1FB6958A1F9A1F11242091860A3091A6\r
+:107D4000870AE05CFF4F2817390718F4208131813A\r
+:107D500002C0281B390B80819181A281B381A901C6\r
+:107D600060E070E0481759076A077B0708F49C0138\r
+:107D7000B901213187E2380710F060E177E281E054\r
+:107D80008093880A6832710510F468E270E06852E6\r
+:107D90007109611588E07807E0F0872F9927880F2F\r
+:107DA000991F880F991F805F9A4FFC013296259189\r
+:107DB0003491AA27639FA001629F410D5A1F069428\r
+:107DC0004A1F5A1F1124FC0125913491241B350BA5\r
+:107DD0001EC0CB01969587958C7F805F964FFC01E6\r
+:107DE000259134910296FC0145915491FB01E77075\r
+:107DF000FF274E9FC0014F9F900D5E9F900D112455\r
+:107E000043E0969587954A95E1F7281B390B243670\r
+:107E10003105A0F4E8E5F2E006C09091C00095FFBE\r
+:107E2000FCCF8093C60081918111F7CF4AE050E0EA\r
+:107E300081E894E00E94572424E630E030938900E2\r
+:107E4000209388008091820A9091830AA091840AED\r
+:107E5000B091850A820F931FA11DB11D8093820AE4\r
+:107E60009093830AA093840AB093850A08C08091F6\r
+:107E70008D0A90918E0A909389008093880040919A\r
+:107E80007C0A50917D0A60917E0A70917F0AE09190\r
+:107E9000800AF091810A80899189A289B389481763\r
+:107EA00059076A077B0780F01092810A1092800AB6\r
+:107EB0009091080580910705981731F0809107058A\r
+:107EC0008F5F8F7080930705FF91EF91BF91AF9106\r
+:107ED0009F918F917F916F915F914F913F912F91E2\r
+:107EE0001F910F910F900FBE0F901F9018950E9A33\r
+:107EF0000C9A3E9A3D9A529A529A529A529A2098C5\r
+:107F0000289A2198299A22982A9A0D9A0B9A3F9A90\r
+:107F10000F9AA1E8B0E08C918F7E8C938C91886051\r
+:107F20008C93E0E8F0E080818D7F808380818E7F7C\r
+:107F3000808380818F73808380818F7C80838C910C\r
+:107F4000887F82608C9380E090E490938900809396\r
+:107F500088001092850010928400EFE6F0E08081A6\r
+:107F60008260808381E0C2D9789408959091080559\r
+:107F700080910705981729F025D281E00E943810DA\r
+:107F8000F5CF0895CF93DF93EFB7F894EC01888194\r
+:107F90009981AA81BB8180935D0A90935E0AA09328\r
+:107FA0005F0AB093600AEB0188819981AA81BB8145\r
+:107FB0008093610A9093620AA093630AB093640A63\r
+:107FC000EA0188819981AA81BB818093650A909397\r
+:107FD000660AA093670AB093680AE90188819981CB\r
+:107FE000AA81BB818093690A90936A0AA0936B0A65\r
+:107FF000B0936C0AEFBFDF91CF9108952FB7F8943B\r
+:10800000FC0180819181A281B3818093690A909360\r
+:108010006A0AA0936B0AB0936C0A2FBF08950F935E\r
+:108020001F939FB7F89424E0829FF0011124E35A34\r
+:10803000F54F00811181228133819FBFB801C901B1\r
+:108040001F910F91089592DF5A985A985A985A980A\r
+:10805000089520912A0130912B0140912C015091DB\r
+:108060002D0160E070E08FE793E40E94DB4B6093AA\r
+:10807000B10A7093B20A8093B30A9093B40A089538\r
+:108080008055954FFC01808190E008950F931F93D8\r
+:10809000CF93DF93EC01662309F461C0E7EFFDE0C5\r
+:1080A00007C09091C00095FFFCCF8093C600319629\r
+:1080B00084918111F6CF4AE050E070E081E894E0CD\r
+:1080C0000E943C24EEEFFDE007C09091C00095FFB8\r
+:1080D000FCCF8093C600319684918111F6CF8091B8\r
+:1080E000C00085FFFCCF8AE08093C6000E940F107D\r
+:1080F00036C0C901880F991F880F991FFC01E45EE3\r
+:10810000F14F659174916C177D073CF52150310951\r
+:10811000220F331F220F331FF901E65EF14F059145\r
+:108120001491245E314FF90145915491FC01E65EB2\r
+:10813000F14F25913491C41BD50B201B310BC29FED\r
+:10814000C001C39F900DD29F900D1124641B750B2D\r
+:108150000E948E4F600F711F13C04F5F01C041E03E\r
+:10816000242F30E04D3309F0C4CF2D33310531F4E5\r
+:10817000EAE0FFE085919491BC0102C060E070E00C\r
+:1081800020EF3FE3261B370BC901DF91CF911F91F1\r
+:108190000F910895CF93DF9321E030E0D901AA0F2A\r
+:1081A000BB1FAA0FBB1FFD01E45EF14F65917491E7\r
+:1081B0006817790744F521503109220F331F220F28\r
+:1081C000331FF901E65EF14FC591D491245E314F22\r
+:1081D000F90145915491FD01E65EF14F25913491ED\r
+:1081E000FC01E41BF50B2C1B3D0BE29FC001E39F40\r
+:1081F000900DF29F900D1124641B750B0E948E4F01\r
+:108200006C0F7D1F0BC02F5F3F4F2D33310509F0E1\r
+:10821000C5CFEAE0FFE085919491BC0120EF3FE3F8\r
+:10822000261B370BC901DF91CF9108952F923F9202\r
+:108230004F925F926F927F928F929F92AF92BF9276\r
+:10824000CF92DF92EF92FF920F931F93CF93DF9322\r
+:108250008C01662351F1E7EFFDE007C09091C0006B\r
+:1082600095FFFCCF8093C600319684918111F6CFA3\r
+:108270004AE050E070E081E894E00E943C24EEE0A7\r
+:10828000FFE007C09091C00095FFFCCF8093C6002F\r
+:10829000319684918111F6CF8091C00085FFFCCF8B\r
+:1082A0008AE08093C6000E940F10C0EFDFE3C01B7E\r
+:1082B000D10B41E05EC09C01220F331F220F331F00\r
+:1082C000F901E65EF14F65907490C615D7050CF084\r
+:1082D0004FC00197880F991F880F991FFC01E45E1A\r
+:1082E000F14F25903490865E914FFC0105911491D9\r
+:1082F000F901E45EF14F45905490B101882777FD74\r
+:108300008095982F0E94764C6B017C01BE01601B0A\r
+:10831000710B882777FD8095982F0E94764C4B0132\r
+:108320005C01B20162197309882777FD8095982F47\r
+:108330000E94764C9B01AC01C501B4010E94A94E7C\r
+:108340004B015C01B301601B710B882777FD8095A1\r
+:10835000982F0E94764C9B01AC01C501B4010E948C\r
+:10836000DB4B9B01AC01C701B6010E94FB4A17C061\r
+:108370004F5F842F90E04D3309F09DCFCD9759F496\r
+:10838000ECE0FFE065917491882777FD8095982F48\r
+:108390000E94764C04C060E070E080E090E0DF91E5\r
+:1083A000CF911F910F91FF90EF90DF90CF90BF90F2\r
+:1083B000AF909F908F907F906F905F904F903F9085\r
+:1083C0002F9008952F923F924F925F926F927F92DB\r
+:1083D0008F929F92AF92BF92CF92DF92EF92FF92D5\r
+:1083E0000F931F93CF93DF9300D0CDB7DEB780916B\r
+:1083F000A30A882309F4B8C18FB7F8941092A30A8E\r
+:108400008FBF60E08091AA0A9091AB0A0FDF6B01E9\r
+:108410007C019B01AC016091A40A7091A50A809136\r
+:10842000A60A9091A70A0E94FA4AB62EA72E182FE4\r
+:10843000092FA5019801852F942FA32FB22F809388\r
+:10844000B50A9093B60AA093B70AB093B80A20E091\r
+:1084500030E040E251E4D501F8016B2F7A2F8F2FE5\r
+:108460009E2F0E94D74D18160CF41BC120E030E05F\r
+:1084700040E251ECD501F8016B2F7A2F8F2F9E2F00\r
+:108480000E94D44B87FD09C18091B90A8111FAC0BD\r
+:1084900020912E0130912F014091300150913101F6\r
+:1084A000D501F8016B2F7A2D8F2F902F0E94A94EA6\r
+:1084B000762E672E89839A83A301382F292F852F43\r
+:1084C000942FA32FB22F8093BE0A9093BF0AA0933C\r
+:1084D000C00AB093C10A2091BA0A3091BB0A4091F8\r
+:1084E000BC0A5091BD0AD501F8016B2F7A2D8F2F50\r
+:1084F000902F0E94FB4A8B012C018090C20A909021\r
+:10850000C30AA090C40AB090C50A282D392D4A2D5F\r
+:108510005B2D602F712F842D952D0E94D44B87FFEA\r
+:108520009BC084012501802F912FA42DB52D809310\r
+:10853000BA0A9093BB0AA093BC0AB093BD0A2091DB\r
+:108540002A0130912B0140912C0150912D01602F77\r
+:10855000712F842D952D0E94A94E4B015C01862F11\r
+:10856000992DAA2DBB2D8093C60A9093C70AA0937C\r
+:10857000C80AB093C90A2091CA0A3091CB0A409127\r
+:10858000CC0A5091CD0AC701B6010E94FA4A209147\r
+:1085900026013091270140912801509129010E9424\r
+:1085A000A94E20ED3CEC4CE45DE30E94A94E1B017A\r
+:1085B0002C0123E333E343E75FE36091CE0A70913C\r
+:1085C000CF0A8091D00A9091D10A0E94A94E9B01B6\r
+:1085D000AC01C201B1010E94FB4A8B012C01862F24\r
+:1085E000912FA42DB52D8093CE0A9093CF0AA093FE\r
+:1085F000D00AB093D10AC092CA0AD092CB0AE092B4\r
+:10860000CC0AF092CD0A282D392D4A2D5B2DD301AD\r
+:10861000F980EA806B2F762D8F2D9E2DECD7202FA1\r
+:10862000312F442D552DE6D78B017C0120E030E021\r
+:10863000A901712F9F2D0E94D44B87FD3CC020E0E3\r
+:1086400030E04FE753E4602F712F8E2D9F2D0E9455\r
+:10865000D74D1816A4F528C08090B10A9090B20AA0\r
+:10866000A090B30AB090B40A282D392D4A2D5B2D65\r
+:10867000602F712F842D952D0E94D74D18160CF068\r
+:1086800052CF4FCF1092BA0A1092BB0A1092BC0A76\r
+:108690001092BD0A1092B90AFBCE81E08093B90A0C\r
+:1086A0000AC081E08093B90A00E010E08FE7E82E6D\r
+:1086B00093E4F92E04C000E010E0E12CF12C2091AD\r
+:1086C000AA0A3091AB0A4091D20A5091D30A4217BC\r
+:1086D00053071CF01092B00A11C040913201509122\r
+:1086E000330124173507B4F7602F712F8E2D9F2D7E\r
+:1086F0000E94434C759567956093B00A0E9478215B\r
+:108700000091D40A1091D50A2091D60A3091D70A47\r
+:10871000601B710B820B930B6838734181059105C7\r
+:1087200018F10E9478216093D40A7093D50A80933F\r
+:10873000D60A9093D70A8091A80A9091A90A181690\r
+:1087400019068CF42091340130913501821793077A\r
+:1087500054F42091AC0A3091AD0A821793070CF0C3\r
+:1087600002C02C9A01C02C980F900F90DF91CF91EE\r
+:108770001F910F91FF90EF90DF90CF90BF90AF903F\r
+:108780009F908F907F906F905F904F903F902F9031\r
+:1087900008952F923F924F925F926F927F928F92A5\r
+:1087A0009F92AF92BF92CF92DF92EF92FF920F9380\r
+:1087B0001F93CF93DF93C0EFDFE3C81BD90B81E09A\r
+:1087C00090E09C01220F331F220F331FF901E65E58\r
+:1087D000F14F65907490C615D7050CF04DC0019708\r
+:1087E000880F991F880F991FFC01E45EF14F2590B7\r
+:1087F0003490865E914FFC0105911491F901E45E7D\r
+:10880000F14F45905490B101882777FD8095982FBE\r
+:108810000E94764C6B017C01BE01601B710B8827A6\r
+:1088200077FD8095982F0E94764C4B015C01B20138\r
+:1088300062197309882777FD8095982F0E94764CDE\r
+:108840009B01AC01C501B4010E94A94E4B015C0122\r
+:10885000B301601B710B882777FD8095982F0E94CC\r
+:10886000764C9B01AC01C501B401A5D79B01AC01BD\r
+:10887000C701B601C0D60FC001968D33910509F02E\r
+:10888000A0CFECE0FFE065917491882777FD80959B\r
+:10889000982F0E94764CDF91CF911F910F91FF90FE\r
+:1088A000EF90DF90CF90BF90AF909F908F907F9090\r
+:1088B0006F905F904F903F902F9008951092C20A52\r
+:1088C0001092C30A1092C40A1092C50A20912A017C\r
+:1088D00030912B0140912C0150912D0160E070E00E\r
+:1088E0008FE793E468D76093B10A7093B20A8093DC\r
+:1088F000B30A9093B40A239A249A569A61E070E0DE\r
+:108900008EE00E94192187ED80937A00EEE7F0E077\r
+:1089100010828081816080838081826080838081F9\r
+:108920008460808380818460808380E888BDEEE6F7\r
+:10893000F0E08081846080836AEF70E080E090E006\r
+:108940000E94AA2160E085E090E0A0DB9093D30A2A\r
+:108950008093D20A60E083E191E098DB9093330149\r
+:108960008093320186E990E015DC90933501809385\r
+:1089700034010895089560E080E090E087DB109274\r
+:10898000A40A1092A50A1092A60A1092A70A80E0E3\r
+:1089900090E000DC9093AD0A8093AC0A1092AF0A8D\r
+:1089A0001092AE0A1092B00A2B981092B10A10924F\r
+:1089B000B00A1092B10A1092B30A1092B20A109241\r
+:1089C000B20A1092AD0A1092AC0A2C9808952F9218\r
+:1089D0003F924F925F926F927F928F929F92AF924F\r
+:1089E000BF92CF92DF92EF92FF920F931F93CF939C\r
+:1089F000DF93CDB7DEB7E1970FB6F894DEBF0FBEB9\r
+:108A0000CDBF688B798B8A8B9B8B0E9478216C8B76\r
+:108A10007D8B8E8B9F8BECE6F2E006C09091C000C0\r
+:108A200095FFFCCF8093C60081918111F7CF809193\r
+:108A3000C00085FFFCCF8AE08093C6009CDF8FE7F3\r
+:108A40008093B00A4C885D886E887F884C865D86EE\r
+:108A50006E867F86AFE7CA2ED12CE12CF12CBFE7C2\r
+:108A60008B2E912CA12CB12C8EA69FA6A8AAB9AAB8\r
+:108A700021E02CA31B861A86E0E1FDE084908FA202\r
+:108A8000E8E1FDE0949098A6EDE1FDE0A490A9A6B0\r
+:108A9000E4E2FDE0B490BAA6EBE2FDE084908BA6A0\r
+:108AA000E1E3FDE094909CA68091A30A882309F459\r
+:108AB000A9C28FB7F8941092A30A8FBF60E080918B\r
+:108AC000AA0A9091AB0AB2DB6E837F83888799876D\r
+:108AD000762F6F81982F8985272F362F492F582F72\r
+:108AE000B88DA98DEA8DFB8D6B2F7A2FCF010E9457\r
+:108AF000D74D181644F0AE80A88EBF80B98E8884FA\r
+:108B00008A8E99849B8E7E816F8198858985272F97\r
+:108B1000362F492F582F612F722D832D902F44D639\r
+:108B200087FD04C01E812F8038840985ACA0AA204F\r
+:108B300009F42FC3788969899A898B89272F362F61\r
+:108B4000492F582FBE81AF81E885F9856B2F7A2F89\r
+:108B5000CF010E94D74D18160CF054C20E94782104\r
+:108B6000641975098609970969387341810591056A\r
+:108B700008F448C28EA59FA5A8A9B9A98C199D097A\r
+:108B8000AE09BF09B595A795979587958093B00ACB\r
+:108B90000E9478216C877D878E879F874B015C01BF\r
+:108BA00084189508A608B70888A299A2AAA2BBA211\r
+:108BB0009888988EA988A98EBA88BA8E8B888B8E51\r
+:108BC000E8C20E9478218C849D84AE84BF84681999\r
+:108BD00079098A099B09693873418105910508F46F\r
+:108BE00010C20E9478212B013C018A849B84892831\r
+:108BF00009F4EDC1DC01CB018C849D84AE84BF847B\r
+:108C000088199909AA09BB0988A099A0AAA0BBA0A4\r
+:108C1000880E991EAA1EBB1E28A139A14AA15BA1DC\r
+:108C2000281B390B4A0B5B0BCA01B901A70196013E\r
+:108C30000E947F4FA50194010E94C34F8EA59FA55E\r
+:108C4000A8A9B9A9280F391F4A1F5B1F2431310574\r
+:108C50004105510524F12EA73FA748AB59AB2C3E47\r
+:108C600031054105510544F02BEE30E040E050E085\r
+:108C70002EA73FA748AB59AB8EA59FA5A8A9B9A918\r
+:108C800080389105A105B105C4F0EEEFCE2ED12CB0\r
+:108C9000E12CF12CC81AD90AEA0AFB0A12C024E115\r
+:108CA00030E040E050E02EA73FA748AB59AB74E15D\r
+:108CB000C72ED12CE12CF12C04C0CEA4DFA4E8A84F\r
+:108CC000F9A88FA1E0E1FDE008C09091C00095FFF8\r
+:108CD000FCCF8093C600319684918111F6CF2AE0B3\r
+:108CE00030E04EA55FA568A979A981E894E00E94CB\r
+:108CF000062488A5E8E1FDE008C09091C00095FF3A\r
+:108D0000FCCF8093C600319684918111F6CF2AE082\r
+:108D100030E0B701A60181E894E00E94062489A50D\r
+:108D2000EDE1FDE008C09091C00095FFFCCF80937D\r
+:108D3000C600319684918111F6CF22E030E0412FB8\r
+:108D4000522D632D702F81E894E00E94FF248AA5A4\r
+:108D5000E4E2FDE008C09091C00095FFFCCF809355\r
+:108D6000C600319684918111F6CF22E030E0F88D73\r
+:108D7000E98D9A8D8B8D4F2F5E2F692F782F81E88B\r
+:108D800094E00E94FF248091C00085FFFCCF8AE020\r
+:108D90008093C6004A855B85433051050CF417C1AA\r
+:108DA000C701B601A3D520E030E040E850E4D1D7B8\r
+:108DB0006C8F7D8F8E8F9F8F212F322D432D502FC3\r
+:108DC000B88DA98DEA8D1B8D6B2F7A2F8E2F912F49\r
+:108DD00011D420ED3FE049E450E4BBD720E030E07F\r
+:108DE00040E05FE3B6D79B01AC016C8D7D8D8E8D2D\r
+:108DF0009F8DE1D4362E072F182F9C8FC501B4010B\r
+:108E000075D520E030E04AE754E4D5D4A62E972E5D\r
+:108E1000282E892E8BA5EBE2FDE008C09091C000C2\r
+:108E200095FFFCCF8093C600319684918111F6CFD7\r
+:108E300022E030E08C8D432D502F612F782F81E878\r
+:108E400094E00E94FF248CA5E1E3FDE008C090912E\r
+:108E5000C00095FFFCCF8093C600319684918111AC\r
+:108E6000F6CF22E030E04A2D592D622D782D81E891\r
+:108E700094E00E94FF248091C00085FFFCCF8AE02F\r
+:108E80008093C6002AE939E949E15FE3EC8D632D5F\r
+:108E9000702F812F9E2F5DD7362E072F182FB92EBA\r
+:108EA000762F272F302F412F5B2D632D702F812F91\r
+:108EB0009B2DA1D32A2D392D422D582D7CD46C8F7A\r
+:108EC0007CA38DA39EA32A2D392D422D582D632DD1\r
+:108ED000702F812F9B2D3DD720E030E040E05EE3F6\r
+:108EE00038D7A62E972E282E892EE7E3FDE007C05F\r
+:108EF0009091C00095FFFCCF8093C600319684917D\r
+:108F00008111F6CF8091C00085FFFCCF8AE080936D\r
+:108F1000C600E4E4FDE007C09091C00095FFFCCFDF\r
+:108F20008093C600319684918111F6CF22E030E023\r
+:108F3000432D502F612F7B2D81E894E00E94FF2468\r
+:108F40008091C00085FFFCCF8AE08093C600EAE4F0\r
+:108F5000FDE007C09091C00095FFFCCF8093C60054\r
+:108F6000319684918111F6CF22E030E0FC8DECA1A6\r
+:108F70009DA18EA14F2F5E2F692F782F81E894E05D\r
+:108F80000E94FF248091C00085FFFCCF8AE080937F\r
+:108F9000C600E0E5FDE007C09091C00095FFFCCF62\r
+:108FA0008093C600319684918111F6CF22E030E0A3\r
+:108FB0004A2D592D622D782D81E894E00E94FF24DE\r
+:108FC0008091C00085FFFCCF8AE08093C6008EA50B\r
+:108FD0009FA5A8A9B9A98C0D9D1DAE1DBF1DB59556\r
+:108FE000A795979587958093B00A8A859B8501966A\r
+:108FF0009B878A87188929883A880B8991E09CA3E6\r
+:1090000001C01CA220E030E040EA51E4B889A989FF\r
+:10901000EA89FB896B2F7A2FCF01EDD29B01AC013E\r
+:10902000BE81AF81E885F9856B2F7A2FCF01BFD53F\r
+:10903000181694F4E6E5FDE007C09091C00095FF96\r
+:10904000FCCF8093C600319684918111F6CF809138\r
+:10905000C00085FFFCCF99C00E9478218C889D8834\r
+:10906000AE88BF88681979098A099B09613D7740F4\r
+:109070008105910508F440C00E9478216C8B7D8B9E\r
+:109080008E8B9F8BEFE7FDE007C09091C00095FFAE\r
+:10909000FCCF8093C600319684918111F6CF60E0B9\r
+:1090A0008091AA0A9091AB0AC1D8AB01BC0122E021\r
+:1090B00030E081E894E00E94FF24E5E8FDE007C08D\r
+:1090C0009091C00095FFFCCF8093C60031968491AB\r
+:1090D0008111F6CF80E090E00E9440404AE050E0ED\r
+:1090E000BC0181E894E00E943C248091C00085FF8F\r
+:1090F000FCCF8AE08093C6000E9478216A837B833C\r
+:109100008C839D830E9478218C849D84AE84BF844F\r
+:10911000840C951CA61CB71C2A813B814C815D8167\r
+:10912000281939094A095B09260F371F481F591F9B\r
+:1091300021383F444241510590F0E9E8FDE007C085\r
+:109140009091C00095FFFCCF8093C600319684912A\r
+:109150008111F6CF8091C00085FFFCCF16C0AA8593\r
+:10916000BB8516970CF4A0CCE6EAFDE007C0909111\r
+:10917000C00095FFFCCF8093C60031968491811189\r
+:10918000F6CF8091C00085FFFCCF8AE08093C600B7\r
+:1091900013C0788969899A898B89272F362F492F9F\r
+:1091A000582FBE81AF81E885F9856B2F7A2FCF01CB\r
+:1091B000FBD287FD06CD25CFE1960FB6F894DEBF32\r
+:1091C0000FBECDBFDF91CF911F910F91FF90EF9018\r
+:1091D000DF90CF90BF90AF909F908F907F906F90D7\r
+:1091E0005F904F903F902F900895CF93DF931F9201\r
+:1091F000CDB7DEB78983BFDB0E941621698181115B\r
+:109200002FC0E7EFFDE007C08091C00085FFFCCFD5\r
+:109210009093C600319694919111F6CF4AE050E0B8\r
+:1092200070E081E894E00E943C248091C00085FFBA\r
+:10923000FCCF8AE08093C600EBE2FFE007C090918C\r
+:10924000C00095FFFCCF8093C600319684918111B8\r
+:10925000F6CF8091C00085FFFCCF8AE08093C600E6\r
+:109260000F90DF91CF910895CF93DF931F92CDB7E9\r
+:10927000DEB7898380DB0E941621698181112FC0AE\r
+:10928000E7EFFDE007C08091C00085FFFCCF909321\r
+:10929000C600319694919111F6CF4AE050E070E00B\r
+:1092A00081E894E00E943C248091C00085FFFCCFBF\r
+:1092B0008AE08093C600E8E5FFE007C09091C00017\r
+:1092C00095FFFCCF8093C600319684918111F6CF33\r
+:1092D0008091C00085FFFCCF8AE08093C6000F908C\r
+:1092E000DF91CF9108952C980E941621811121C001\r
+:1092F000E7EFFDE007C09091C00095FFFCCF8093A1\r
+:10930000C600319684918111F6CFE5E8FFE007C0F1\r
+:109310009091C00095FFFCCF8093C6003196849158\r
+:109320008111F6CF8091C00085FFFCCF8AE0809349\r
+:10933000C60008951F920F920FB60F9211242F931B\r
+:109340003F934F935F936F937F938F939F93AF93CD\r
+:10935000BF93EF93FF9380913601811106C08091F6\r
+:10936000B00A8093D80A81112B9A9091D80A8091E3\r
+:109370003601891708F02B988F5F8F77809336011D\r
+:109380008091D90A833009F443C020F48130D1F0B0\r
+:10939000A8F50CC0853009F461C008F453C08630CC\r
+:1093A00009F476C0873009F09EC07EC010927B0021\r
+:1093B00080E480937C0080917A00806480937A00BE\r
+:1093C00081E019C020917800309179008091DA0A0B\r
+:1093D0009091DB0AA091DC0AB091DD0A820F931F05\r
+:1093E000A11DB11D8093DA0A9093DB0AA093DC0AD9\r
+:1093F000B093DD0A82E08093D90A75C082E480933D\r
+:109400007C0080917A00806480937A0083E0F3CFBF\r
+:1094100020917800309179008091DE0A9091DF0AE6\r
+:10942000A091E00AB091E10A820F931FA11DB11D26\r
+:109430008093DE0A9093DF0AA093E00AB093E10ADA\r
+:1094400084E0D9CF10927B0081E480937C008091EE\r
+:109450007A00806480937A0085E0CDCF20917800F7\r
+:10946000309179008091E20A9091E30AA091E40A98\r
+:10947000B091E50A820F931FA11DB11D8093E20AEE\r
+:109480009093E30AA093E40AB093E50A86E0B3CF91\r
+:1094900010927B0082E480937C0080917A0080644B\r
+:1094A00080937A0087E0A7CF2091780030917900EF\r
+:1094B0008091E60A9091E70AA091E80AB091E90A42\r
+:1094C000820F931FA11DB11D8093E60A9093E70AB6\r
+:1094D000A093E80AB093E90A1092D90A8091EA0AA7\r
+:1094E0008F5F8093EA0A8091EA0A803108F471C0A4\r
+:1094F0002FEF3FE38091DA0A9091DB0AA901481B24\r
+:10950000590BCA015093AB0A4093AA0A4091DE0A54\r
+:109510005091DF0A241B350B3093A90A2093A80A27\r
+:1095200021E02093A30A1092EA0A1092DA0A10921C\r
+:10953000DB0A1092DC0A1092DD0A1092E20A109205\r
+:10954000E30A1092E40A1092E50A1092E60A1092D9\r
+:10955000E70A1092E80A1092E90A1092DE0A1092C5\r
+:10956000DF0A1092E00A1092E10A20913201309154\r
+:1095700033018217930744F01092AF0A1092AE0A9B\r
+:1095800080E033DE0E94DB202091AA0A3091AB0AF2\r
+:109590008091D20A9091D30A8217930744F01092D7\r
+:1095A000AF0A1092AE0A80E05FDE0E94DB202091BD\r
+:1095B000A80A3091A90A80913401909135012817A9\r
+:1095C00039073CF01092AD0A1092AC0A8CDE0E9472\r
+:1095D000DB20FF91EF91BF91AF919F918F917F9190\r
+:1095E0006F915F914F913F912F910F900FBE0F9010\r
+:1095F0001F9018955058BB27AA270ED076C23FD28D\r
+:1096000030F044D220F031F49F3F11F41EF40FC229\r
+:109610000EF4E095E7FBDCC1E92F89D280F3BA179D\r
+:10962000620773078407950718F071F49EF5B8C2B6\r
+:109630000EF4E0950B2EBA2FA02D0B01B90190016D\r
+:109640000C01CA01A0011124FF27591B99F0593FB1\r
+:1096500050F4503E68F11A16F040A22F232F342FF9\r
+:109660004427585FF3CF469537952795A795F04047\r
+:109670005395C9F77EF41F16BA0B620B730B840B5C\r
+:10968000BAF09150A1F0FF0FBB1F661F771F881F14\r
+:10969000C2F70EC0BA0F621F731F841F48F487956C\r
+:1096A00077956795B795F7959E3F08F0B3CF93955B\r
+:1096B000880F08F09927EE0F979587950895DFD1C9\r
+:1096C00058F080E891E009F49EEFE0D128F040E8FE\r
+:1096D00051E059F45EEF09C0AAC162C2E92FE078F7\r
+:1096E00026D268F3092E052AC1F326173707480743\r
+:1096F000590738F00E2E07F8E02569F0E025E06400\r
+:109700000AC0EF6307F8009407FADB01B9019D0175\r
+:10971000DC01CA01AD01EF935DD0E7D10AD05F91C2\r
+:10972000552331F02BED3FE049E450FD49EC63CF88\r
+:109730000895DF93DD27B92FBF7740E85FE3161662\r
+:10974000170648075B0710F4D92F96D29F938F9383\r
+:109750007F936F93A9D3E0E7F0E06CD1C6D12F914E\r
+:109760003F914F915F9101D3DD2349F09058A2EAD8\r
+:109770002AED3FE049EC5FE3D0785D274DDFDF91D4\r
+:10978000B4C1F7D180F09F3740F491110EF409C2B3\r
+:1097900060E070E080E89FE3089526F01B16611DED\r
+:1097A000711D811D1BC135C1EFD008F481E0089502\r
+:1097B00075D1E395ABC10CD098C168D140F05FD1B1\r
+:1097C00030F021F45F3F19F003C15111EAC12FC1FC\r
+:1097D000AED198F39923C9F35523B1F3951B550BDB\r
+:1097E000BB27AA2762177307840738F09F5F5F4F74\r
+:1097F000220F331F441FAA1FA9F333D00E2E3AF0B5\r
+:10980000E0E830D091505040E695001CCAF729D0CE\r
+:10981000FE2F27D0660F771F881FBB1F261737071D\r
+:109820004807AB07B0E809F0BB0B802DBF01FF274D\r
+:1098300093585F4F2AF09E3F510568F0C9C0B1C1EF\r
+:109840005F3FECF3983EDCF3869577956795B79587\r
+:10985000F7959F5FC9F7880F911D9695879597F9A2\r
+:109860000895E1E0660F771F881FBB1F621773071B\r
+:109870008407BA0720F0621B730B840BBA0BEE1F30\r
+:1098800088F7E095089504D06894B1118AC10895CD\r
+:1098900056D188F09F5790F0B92F9927B751A0F073\r
+:1098A000D1F0660F771F881F991F1AF0BA95C9F774\r
+:1098B00012C0B13081F074D1B1E0089571C1672F49\r
+:1098C000782F8827B85F39F0B93FCCF38695779524\r
+:1098D0006795B395D9F73EF490958095709561950D\r
+:1098E0007F4F8F4F9F4F0895E89409C097FB3EF438\r
+:1098F00090958095709561957F4F8F4F9F4F9923DD\r
+:10990000A9F0F92F96E9BB279395F695879577955A\r
+:109910006795B795F111F8CFFAF4BB0F11F460FF1A\r
+:109920001BC06F5F7F4F8F4F9F4F16C0882311F072\r
+:1099300096E911C0772321F09EE8872F762F05C086\r
+:10994000662371F096E8862F70E060E02AF09A9521\r
+:10995000660F771F881FDAF7880F9695879597F916\r
+:10996000089507D180F09F3740F491110EF019C18E\r
+:1099700060E070E080E89FEB089526F41B16611DFF\r
+:10998000711D811D2BC045C0990F0008550FAA0BF2\r
+:10999000E0E8FEEF16161706E807F907C0F0121602\r
+:1099A0001306E407F50798F0621B730B840B950B05\r
+:1099B00039F40A2661F0232B242B252B21F408955A\r
+:1099C0000A2609F4A140A6958FEF811D811D0895F7\r
+:1099D00097F99F6780E870E060E00895882371F44C\r
+:1099E000772321F09850872B762F07C0662311F438\r
+:1099F00099270DC09051862B70E060E02AF09A956F\r
+:109A0000660F771F881FDAF7880F9695879597F965\r
+:109A100008959F3F31F0915020F487957795679591\r
+:109A2000B795880F911D9695879597F908959FEFA3\r
+:109A300080EC0895DF93CF931F930F93FF92EF92E3\r
+:109A4000DF927B018C01689405C0DA2EEF018DD185\r
+:109A5000FE01E894A5912591359145915591AEF37C\r
+:109A6000EF01DADDFE019701A801DA9479F7DF90C2\r
+:109A7000EF90FF900F911F91CF91DF9108950024F7\r
+:109A80000A941616170618060906089500240A9463\r
+:109A900012161306140605060895C9CF50D0E8F330\r
+:109AA000E894E0E0BB279F57F0F02AED3FE049EC57\r
+:109AB00006C0EE0FBB0F661F771F881F28F0B23A53\r
+:109AC00062077307840728F0B25A620B730B840B8A\r
+:109AD000E3959A9572F7803830F49A95BB0F661F1C\r
+:109AE000771F881FD2F7904896CF092E0394000C59\r
+:109AF00011F4882352F0BB0F40F4BF2B11F460FF28\r
+:109B000004C06F5F7F4F8F4F9F4F0895EF93E0FF2B\r
+:109B100006C0A2EA2AED3FE049EC5FEB7DDDE5DF20\r
+:109B20000F90039401FC9058EDE9F0E0C7C157FD98\r
+:109B30009058440F551F59F05F3F71F04795880FBB\r
+:109B400097FB991F61F09F3F79F087950895121652\r
+:109B500013061406551FF2CF4695F1DF08C01616FE\r
+:109B600017061806991FF1CF8695710561050894AF\r
+:109B70000895E5DFA0F0BEE7B91788F4BB279F384A\r
+:109B800060F41616B11D672F782F8827985FF7CFDE\r
+:109B9000869577956795B11D93959639C8F3089585\r
+:109BA000E894BB2766277727CB0197F90895ECDE69\r
+:109BB00008F48FEF089563DF19F068DF09F037CFFD\r
+:109BC00007CFB901CA0125CF9F775F77B0DF98F340\r
+:109BD0009923B9F35523B9F3FF27951758F4E52FC7\r
+:109BE000E91BED3070F75E3B10F0F1E41CC09034DF\r
+:109BF000E0F40AC0E92FE51BED3028F79E3B10F09A\r
+:109C0000F1E411C0503488F4F9EA88232AF09A95D7\r
+:109C1000660F771F881FDAF744232AF05A95220F20\r
+:109C2000331F441FDAF79F1B5F1BFF931F930F9394\r
+:109C3000FF92EF9279018A01BB27AB2F9B01AC0108\r
+:109C400096D09701A801BF937B018C01AA27BA2F58\r
+:109C5000B901CA018CD0AF919701A801EF90FF9094\r
+:109C60000F911F91D9DC41DFE1D04F9140FF089562\r
+:109C7000552747FD509509C09B01AC0160E070E09D\r
+:109C800080E89FE398CDA4CEC4CE59DFE8F39923B2\r
+:109C9000D9F3940F511DBBF39150504094F059F0FB\r
+:109CA000882332F0660F771F881F91505040C1F70C\r
+:109CB0009E3F510544F7880F911D9695879597F91A\r
+:109CC00008955F3FACF0983E9CF0BB278695779552\r
+:109CD0006795B79508F4B1609395C1F7BB0F58F736\r
+:109CE00011F460FFE8CF6F5F7F4F8F4F9F4FE3CF3F\r
+:109CF00058CF25DF58F19E5758F19851A0F0E9F060\r
+:109D0000983020F5092E9927660F771F881F991F15\r
+:109D10000A94D1F712C0062E672F782F8827985FF4\r
+:109D200011F4000C07C0993FB4F3869577956795B9\r
+:109D30009395D9F7611D711D811D3EF49095809515\r
+:109D4000709561957F4F8F4F9F4F0895689429CFED\r
+:109D500027CF0BD0CACE93DE28F098DE18F09523DB\r
+:109D600009F036CE64CE11241CCFE1DEA0F3959F1E\r
+:109D7000D1F3950F50E0551F629FF001729FBB27F2\r
+:109D8000F00DB11D639FAA27F00DB11DAA1F649F9E\r
+:109D90006627B00DA11D661F829F2227B00DA11D51\r
+:109DA000621F739FB00DA11D621F839FA00D611DD7\r
+:109DB000221F749F3327A00D611D231F849F600DF8\r
+:109DC000211D822F762F6A2F11249F5750408AF031\r
+:109DD000E1F088234AF0EE0FFF1FBB1F661F771FBD\r
+:109DE000881F91505040A9F79E3F510570F0F0CD6B\r
+:109DF000D8CE5F3FECF3983EDCF386957795679578\r
+:109E0000B795F795E7959F5FC1F7FE2B880F911DDA\r
+:109E10009695879597F908959F9340DE0F9007FCDC\r
+:109E2000EE5F74CE11F40EF402CEF3CD88DED0F3E3\r
+:109E30009923D9F3CEF39F57550B87FF38D00024D1\r
+:109E4000A0E640EA900180585695979528F4805CEA\r
+:109E5000660F771F881F20F026173707480730F452\r
+:109E6000621B730B840B202931294A2BA69517946A\r
+:109E70000794202531254A2758F7660F771F881F3A\r
+:109E800020F026173707480730F4620B730B840B5A\r
+:109E9000200D311D411DA09581F7B901842F9158E6\r
+:109EA000880F9695879508959B01AC0152CF9150EC\r
+:109EB0005040660F771F881FD2F708959F938F93A6\r
+:109EC0007F936F93FF93EF939B01AC0142DFEF9180\r
+:109ED000FF91B0DD2F913F914F915F913ACF6ED0BE\r
+:109EE000A59F900DB49F900DA49F800D911D1124EE\r
+:109EF0000895B7FFF4CFF3DF821B930B0895DB01C6\r
+:109F00008F939F93ECDFBF91AF91A29F800D911D26\r
+:109F1000A39F900DB29F900D1124089597FB072EDB\r
+:109F200016F4009406D077FD08D054D007FC05D075\r
+:109F30003EF4909581959F4F0895709561957F4F60\r
+:109F40000895A1E21A2EAA1BBB1BFD010DC0AA1F7A\r
+:109F5000BB1FEE1FFF1FA217B307E407F50720F092\r
+:109F6000A21BB30BE40BF50B661F771F881F991F0D\r
+:109F70001A9469F760957095809590959B01AC0156\r
+:109F8000BD01CF010895052E97FB16F4009406D06D\r
+:109F900057FD0CD0D6DF07FC09D07EF49095809554\r
+:109FA000709561957F4F8F4F9F4F089550954095C5\r
+:109FB000309521953F4F4F4F5F4F0895A29FB001BD\r
+:109FC000B39FC001A39F01D0B29F700D811D1124CA\r
+:109FD000911D0895AA1BBB1B51E107C0AA1FBB1FFF\r
+:109FE000A617B70710F0A61BB70B881F991F5A9525\r
+:109FF000A9F780959095BC01CD010895A0E0B0E04F\r
+:10A00000E3E0F0E536C58B016115710519F0FB0140\r
+:10A01000808391837C01F701C1907F01EF018C2D3A\r
+:10A0200090E04AD2892BB9F7FDE2CF1204C0C99063\r
+:10A03000DD24D39405C02BE2C21201C0C990D12CFB\r
+:10A040007E0141E0E41AF10843E050E06FEB7FE06D\r
+:10A05000C7013AD2892BE1F47E0182E0E80EF11CBF\r
+:10A0600045E050E062EC7FE0C7012ED2892B21F45D\r
+:10A070007E01E7E0EE0EF11C0115110519F0F80163\r
+:10A08000F182E08210E0D0E0C0E8D110F5C0F9C064\r
+:10A0900043E050E067EC7FE0C70116D2892B49F41A\r
+:10A0A0000115110509F4EAC02296F801D183C08395\r
+:10A0B000E5C060E070E0CB01E12CF12CEC2DE05329\r
+:10A0C000EA3040F5FD2DF2602D2D2870D2FE06C03D\r
+:10A0D000211126C02FEFE21AF20A22C0222319F022\r
+:10A0E00041E0E41AF108A5E0B0E09B01AC01F7DE25\r
+:10A0F000660F771F881F991F6E0F711D811D911D9F\r
+:10A100006839E9E97E078E07E9E19E0748F0FD2DF1\r
+:10A11000F66006C0EE3F39F4D3FC3DC0FD2DF8607B\r
+:10A12000C990DF2ECBCFE53311F0E531A1F5A88141\r
+:10A13000AD3219F4F0E1DF2A06C0AB3221F02196EE\r
+:10A1400021E030E004C0A981229622E030E0A05353\r
+:10A15000AA3018F0C21BD30B1EC0FE0120E030E075\r
+:10A1600020384CE034075CF4A901440F551F440F1C\r
+:10A17000551F240F351F220F331F2A0F311DA191A8\r
+:10A18000A053EF01AA3060F3D4FE03C031952195AE\r
+:10A190003109E20EF31ED1FE07C00115110521F0B1\r
+:10A1A0002197F801D183C0839FDB2D2D23702330AD\r
+:10A1B00029F0162FD72FC82F092F07C0DC01CB019C\r
+:10A1C000B058182FD92FCA2F0B2F20E030E0A9014B\r
+:10A1D000612F7D2F8C2F902FE7DA882309F452C04E\r
+:10A1E000F7FE08C0F194E194F10836EFC32E3FE08A\r
+:10A1F000D32E04C02EEDC22E2FE0D22E4601F8E160\r
+:10A200008F1A910890E2A92EB12C14C0F601459145\r
+:10A21000559165917491242F352F462F572F612F1B\r
+:10A220007D2F8C2F902F95DD162FD72FC82F092F1C\r
+:10A23000EA18FB08EA14FB044CF724E0C21AD10820\r
+:10A24000B594A794C814D904A9F7612F7D2F8C2F3A\r
+:10A25000902F282F220F292F221F2F3F31F020E08F\r
+:10A2600030E0A901A1DA81110DC082E290E0909363\r
+:10A27000F00A8093EF0A06C00FEF04C010E0D0E0B0\r
+:10A28000C0EC0FE7612F7D2F8C2F902FCDB7DEB75D\r
+:10A29000ECE00BC4A0E0B0E0EFE4F1E5E6C32B0195\r
+:10A2A0008A016115710519F0FB0180839183011505\r
+:10A2B000110539F09801225031092332310508F097\r
+:10A2C000E3C07C01F701C1917F013F018C2F90E039\r
+:10A2D000F3D0892BB9F7CD3229F4F701C1913F01B1\r
+:10A2E000D1E006C0CB3219F4F701C1913F01D0E0B3\r
+:10A2F0000115110509F4D6C00031110581F4CEC055\r
+:10A30000F3018081883719F0883509F0C1C0F30165\r
+:10A31000C181F2E06F0E711CD26000E110E00830E4\r
+:10A320001105D9F024F402301105F9F407C00A3000\r
+:10A33000110551F000311105C1F424C0C12CD12CFC\r
+:10A34000E12C30E4F32E23C00AE010E02CECC22E06\r
+:10A35000DC2CEC2C2CE0F22E1AC008E010E0C12C12\r
+:10A36000D12CE12C90E1F92E12C09801442737FD41\r
+:10A370004095542F60E070E080E090E8E2DD6901F4\r
+:10A380007A0105C0C12CD12CE12C88E0F82E40E0E8\r
+:10A3900060E070E0CB014801AA2497FCA094BA2C9D\r
+:10A3A000EC2FE053EA3060F02C2F21542A3110F4C6\r
+:10A3B000E75006C02C2F21562A3120F5EC2FE75507\r
+:10A3C0002E2F30E020173107ECF447FD17C0C616DA\r
+:10A3D000D706E806F90678F09B01AC01C501B40187\r
+:10A3E0008EDD6E0F711D811D911D6130710581051E\r
+:10A3F00020E8920710F04FEF01C041E0F301C19156\r
+:10A400003F01CECF4114510491F0442339F0F1E0E3\r
+:10A410006F1A7108F2017182608209C0D1FF1BC0FE\r
+:10A42000F2E06F1A7108F2017182608214C047FF76\r
+:10A4300012C0D0FF05C060E070E080E090E804C08A\r
+:10A440006FEF7FEF8FEF9FE722E230E03093F00A6B\r
+:10A450002093EF0A16C0D0FF08C0909580957095A4\r
+:10A4600061957F4F8F4F9F4F0CC097FF0AC082E2CC\r
+:10A4700090E09093F00A8093EF0A6FEF7FEF8FEFF9\r
+:10A480009FE76B017C0112C0C12CD12C76010EC05C\r
+:10A49000C0E30115110509F460CF41CFC03309F0C5\r
+:10A4A0003ECF2ECFC03309F04FCF2ACFB601C70120\r
+:10A4B000CDB7DEB7E0E1F5C2911132C2803219F0BA\r
+:10A4C00089508550D0F70895FB01DC014150504080\r
+:10A4D00088F08D9181341CF08B350CF4805E659191\r
+:10A4E00061341CF06B350CF4605E861B611171F3F6\r
+:10A4F000990B0895881BFCCFFC018191861721F0F0\r
+:10A500008823D9F7992708953197CF010895FB0142\r
+:10A5100051915523A9F0BF01DC014D91451741111F\r
+:10A52000E1F759F4CD010190002049F04D9140151B\r
+:10A530004111C9F3FB014111EFCF81E090E0019798\r
+:10A540000895A0E1B0E0E6EAF2E59BC20F89188D1C\r
+:10A5500086E08C831A8309838FEF9FE79E838D8328\r
+:10A56000AE01455E5F4F588B4F87698D7A8DCE0166\r
+:10A57000019608D0EF81F885E00FF11F10826096F8\r
+:10A58000E4E09BC2ACE0B0E0E7ECF2E56CC27C0139\r
+:10A590006B018A01FC0117821682838181FFBAC197\r
+:10A5A00088248394912C8C0E9D1EF7019381F601D3\r
+:10A5B00093FD859193FF81916F01882309F4A6C1D2\r
+:10A5C000853239F493FD859193FF81916F01853236\r
+:10A5D00021F4B70190E0BDD1E8CF712C312C20E0FF\r
+:10A5E0002032A8F48B3261F028F4803251F08332AB\r
+:10A5F00071F40BC08D3239F0803349F4216028C0EA\r
+:10A600002260246025C0286023C0206121C027FD6E\r
+:10A6100027C0382F30533A3078F426FF06C0FAE0CE\r
+:10A620007F9E300D1124732E13C08AE0389E300DAA\r
+:10A630001124332E20620CC08E3221F426FD66C117\r
+:10A64000206406C08C3611F4206802C0883641F4BC\r
+:10A65000F60193FD859193FF81916F018111C0CF28\r
+:10A66000982F9554933018F09052933028F40C5F43\r
+:10A670001F4FFFE3F9830DC0833631F0833771F04C\r
+:10A68000833509F05AC022C0F801808189830E5FAA\r
+:10A690001F4F66246394712C540114C02801F2E00A\r
+:10A6A0004F0E511CF801A080B18026FF03C0672D1A\r
+:10A6B00070E002C06FEF7FEFC5012C873FD13C01F6\r
+:10A6C00082012C856FE7262E222217C02801F2E096\r
+:10A6D0004F0E511CF801A080B18026FF03C0672DEA\r
+:10A6E00070E002C06FEF7FEFC5012C871CD13C01E9\r
+:10A6F0002C8550E8252E222A820123FC1AC005C091\r
+:10A70000B70180E290E025D13A94832D90E068165D\r
+:10A710007906B0F30EC0F50127FC859127FE8191E3\r
+:10A720005F01B70190E015D131103A94F1E06F1A52\r
+:10A7300071086114710479F7E6C0843611F0893626\r
+:10A7400039F5F80127FF07C060817181828193810B\r
+:10A750000C5F1F4F08C060817181882777FD80954D\r
+:10A76000982F0E5F1F4F4FE6642E622297FF09C09D\r
+:10A7700090958095709561957F4F8F4F9F4FF0E832\r
+:10A780006F2A2AE030E0A40110D1A82EA81843C0F7\r
+:10A79000853731F43FEEB32EB2222AE030E024C0F8\r
+:10A7A00099EFB92EB2228F36B9F020F4883509F02E\r
+:10A7B000ADC00DC0803721F0883709F0A7C002C0B6\r
+:10A7C00020E1B22AB4FE0BC084E0B82A08C024FFFE\r
+:10A7D00009C0E6E0BE2A06C028E030E005C020E15E\r
+:10A7E00030E002C020E132E0F801B7FE07C060812E\r
+:10A7F0007181828193810C5F1F4F06C060817181DE\r
+:10A8000080E090E00E5F1F4FA401CFD0A82EA818C3\r
+:10A810008FE7682E6B2066FE0BC0362D3E7FA71497\r
+:10A8200050F464FE0AC062FC08C0362D3E7E05C0AE\r
+:10A83000BA2C362D03C0BA2C01C0B72C34FF0DC082\r
+:10A84000FE01EA0DF11D8081803311F4397E09C0CB\r
+:10A8500032FF06C0B394B39404C0832F867809F006\r
+:10A86000B39433FD13C030FF0EC07A2CB31458F4E8\r
+:10A87000730C7B18B32C07C0B70180E290E03C87D3\r
+:10A8800068D0B3943C85B314B8F304C0B31410F487\r
+:10A890003B1801C0312C34FF11C0B70180E390E0B8\r
+:10A8A0003C8757D03C8532FF1CC031FF03C088E590\r
+:10A8B00090E002C088E790E0B7010CC0832F867853\r
+:10A8C00081F031FD02C080E201C08BE237FD8DE2F4\r
+:10A8D000B70190E03ED005C0B70180E390E039D0E9\r
+:10A8E0007A94A714C8F3AA94F401EA0DF11DB701F4\r
+:10A8F000808190E02ED0A110F6CF05C0B70180E294\r
+:10A9000090E027D03A943110F9CF4FCEF70126814D\r
+:10A91000378102C02FEF3FEFC9012C96E2E1BFC0A3\r
+:10A92000992788270895FC01059061507040011017\r
+:10A93000D8F7809590958E0F9F1F0895FC01615068\r
+:10A94000704001900110D8F7809590958E0F9F1F51\r
+:10A9500008950F931F93CF93DF938C01EB018B81AD\r
+:10A9600081FD03C00FEF1FEF1AC082FF0DC02E81C3\r
+:10A970003F818C819D812817390764F4E881F98132\r
+:10A980000193F983E88306C0E885F985802F09954E\r
+:10A99000892B41F78E819F8101969F838E83C80109\r
+:10A9A000DF91CF911F910F910895FA01AA272830C6\r
+:10A9B00051F1203181F1E8946F936E7F6E5F7F4F8C\r
+:10A9C0008F4F9F4FAF4FB1E03ED0B4E03CD0670F08\r
+:10A9D000781F891F9A1FA11D680F791F8A1F911D5B\r
+:10A9E000A11D6A0F711D811D911DA11D20D009F4AB\r
+:10A9F00068943F912AE0269F11243019305D3193ED\r
+:10AA0000DEF6CF010895462F4770405D4193B3E0D5\r
+:10AA10000FD0C9F7F6CF462F4F70405D4A3318F07C\r
+:10AA2000495D31FD4052419302D0A9F7EACFB4E02D\r
+:10AA3000A6959795879577956795BA95C9F70097E5\r
+:10AA40006105710508959B01AC010A2E0694579586\r
+:10AA5000479537952795BA95C9F7620F731F841FDD\r
+:10AA6000951FA01D08952F923F924F925F926F9273\r
+:10AA70007F928F929F92AF92BF92CF92DF92EF928E\r
+:10AA8000FF920F931F93CF93DF93CDB7DEB7CA1B0F\r
+:10AA9000DB0B0FB6F894DEBF0FBECDBF09942A883A\r
+:10AAA000398848885F846E847D848C849B84AA84E2\r
+:10AAB000B984C884DF80EE80FD800C811B81AA816F\r
+:10AAC000B981CE0FD11D0FB6F894DEBF0FBECDBF3A\r
+:08AAD000ED010895F894FFCF99\r
+:10AAD8006400640000803B4500803B4500007043F3\r
+:10AAE800000000000080BB440160EA000001010191\r
+:10AAF80001010000803F75608944A97E443E713D94\r
+:10AB0800E841FF3FFF3F010000A04214AE9F420012\r
+:10AB1800002045F6C815440000FA430000FA430037\r
+:10AB280000A04000003442282300002823000064CD\r
+:10AB3800000000102700005573696E6720446566A1\r
+:10AB480061756C742073657474696E67733A004D2F\r
+:10AB5800313130004820004C20002569206D696E95\r
+:10AB68002C20256920736563004D31303420496EEF\r
+:10AB780076616C696420657874727564657220000A\r
+:10AB88004D31303520496E76616C69642065787482\r
+:10AB9800727564657220004D31303920496E7661D6\r
+:10ABA8006C696420657874727564657220003F0072\r
+:10ABB8006F6B0020703A0020693A0020643A002048\r
+:10ABC800633A005400496E76616C69642065787454\r
+:10ABD800727564657200416374697665204578749E\r
+:10ABE80072756465723A200058595A450000010090\r
+:10ABF8001A0019000A000000FFFF1C001B000A00D1\r
+:10AC08000100FFFF170016000A000200FFFFFFFF08\r
+:10AC1800FFFF04000E00180015000A0003000000E2\r
+:10AC28000100020002002E005374657072617465A1\r
+:10AC380020746F2068696768203A200050494420D2\r
+:10AC48004175746F74756E65207374617274000059\r
 :00000001FF\r
diff --git a/examples/board_reprap/reprap_flash.bin b/examples/board_reprap/reprap_flash.bin
new file mode 100644 (file)
index 0000000..c97c12f
Binary files /dev/null and b/examples/board_reprap/reprap_flash.bin differ
diff --git a/examples/board_reprap/src/c3/README.md b/examples/board_reprap/src/c3/README.md
deleted file mode 100644 (file)
index 31207ab..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-libc3 - No frill 'scene' graph library in C
-=====
-(C) 2012 Michel Pollet <buserror@gmail.com>
-
-**WARNING** This API is not your nanny. It is made to be lean, mean, efficient
-with no frill, no asserts, no bounds checking, no sugar coating.
-
-On the other hand it's fast, reasonably clean and is a micro-fraction of the
-other giganormous 'scene graphs' or 'game engine' libraries around.
-
-It's vaguely inspired by THREE.js funnily enough, because it allows you to
-hack around and quickly get stuff on screen with the minimal amount of 
-effort.
-
-The API has various bits:
-* c3algebra: C derivative of an old C++ piece of code I had lying around and that has
-been present in my toolset for a long time. It gives you *vectors* (c3vec2, c3vec3, c3vec4)
-and *matrices* (c3mat3, c3mat4) with various tools to manipulate them.
-* c3quaternion: Quaternion implementation using c3algebra
-* c3camera/c3arcball: camera manipulation, not perfect
-
-The basic data structure is as follow:
-* *c3context*:
-       Mostly placeholder for now, hosts a "root" object, can reproject the
-       objects & geometry, and call the callbacks to draw them.
-* *c3object*: 
-       * Has a list of (sub) c3objects
-       * Has a list of c3transforms (ie matrices)
-       * Has a list of c3geometry (ie real vertices and stuff)
-  The object is a container for other objects, and for geometry itself. Objects don't
-  necessary have geometry and/or sub objects, and don't even need transforms if their
-  vertices are already projected.
-* *c3geometry*:
-       * Has a 'type' (raw for simple vertices, texture, triangles etc)
-       * Has a 'subtype' (mostly can be used to draw GL types)
-       * Has a 'material' (ie color, texture... to be completed)
-       * Has a list of vertices
-       * Has a list of texture coordinates (optional)
-       * Has a list of vertices colors (optional)
-       * Has a cached copy of a vertices when it has been 'projected'
-* *c3transform*:
-       Is just a sugar coated matrix, with an optional name.
-
-Also there are:
-* *c3pixels*:
-       Is just a wrapper/holder for some pixels, either allocated, or inherited, 
-       it's mostly used for *c3texture*
-* *c3texture*:
-       Associates a *c3geometry* with a *c3pixels* and has a standard Quad
-       for vertices. The OpenGL drawing is not done there, it's done by the application using
-       the generic *c3context* driver.
-* *c3cairo*:
-       Placeholder for now, inherits from *c3texture* and will contain a
-       cairo surface mapped to a GL texture.
-* *c3pango*:
-       A text label, inherits from *c3cairo*
-
-Draw Drivers "Inheritance"
-------------
-Various object uses static tables of callbacks to implement their behaviours
-it's kinda cheap c++ inheritance, without the usual bloat.
-
-There just a couple macros to call the driver chain for a particular function call.
-The relevant bits are in c3driver*.h.
-
-Mostly the code looks for a matching callback in a static table, and call it if found.
-If that callback wants, it can also call the inherited object callback too.
-
-Dirtyness
----------
-There is a notion of 'dirtyness' in the tree, when you touch a *c3transform*, and/remove
-objects and geometry, a dirty bit is propagated up the tree of object. This tells the
-rendering it needs to reproject the dirty bits and repopulate the projected vertice
-cache.
-
-The 'dirty' bit moves both ways, when setting a dirty bit to true, it propagates upward,
-when you set it to false, it propagates downward in the tree.
diff --git a/examples/board_reprap/src/c3/c3.c b/examples/board_reprap/src/c3/c3.c
deleted file mode 100644 (file)
index 38fcf83..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-       c3.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3.h"
-
diff --git a/examples/board_reprap/src/c3/c3.h b/examples/board_reprap/src/c3/c3.h
deleted file mode 100644 (file)
index 410fa3e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-       c3.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3_H___
-#define __C3_H___
-
-#include "c3/c3context.h"
-#include "c3/c3object.h"
-#include "c3/c3geometry.h"
-#include "c3/c3transform.h"
-#include "c3/c3texture.h"
-
-#endif /* __C3_H___ */
diff --git a/examples/board_reprap/src/c3/c3algebra.c b/examples/board_reprap/src/c3/c3algebra.c
deleted file mode 100644 (file)
index af816b1..0000000
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
-       c3algebra.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       Derivative and inspiration from original C++:
-       Paul Rademacher & Jean-Francois DOUEG,
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <string.h>
-#include "c3/c3algebra.h"
-
-#ifndef MAX
-#define MAX(a,b)  ((a)>(b) ? (a) : (b))
-#define MIN(a,b)  ((a)<(b) ? (a) : (b))
-#endif
-
-/****************************************************************
- *                                                              *
- *          c3vec2 Member functions                               *
- *                                                              *
- ****************************************************************/
-
-/******************** c3vec2 CONSTRUCTORS ********************/
-
-c3vec2 c3vec2_zero()
-{
-       c3vec2 n = { .x = 0, .y = 0 };
-    return n;
-}
-
-c3vec2 c3vec2f(c3f x, c3f y)
-{
-       c3vec2 v = { .x = x, .y = y };
-       return v;
-}
-
-/******************** c3vec2 ASSIGNMENT OPERATORS ******************/
-
-c3vec2  c3vec2_add(c3vec2 a, const c3vec2 v)
-{
-    a.n[VX] += v.n[VX];
-    a.n[VY] += v.n[VY];
-    return a;
-}
-
-c3vec2  c3vec2_sub(c3vec2 a, const c3vec2 v)
-{
-    a.n[VX] -= v.n[VX];
-    a.n[VY] -= v.n[VY];
-    return a;
-}
-
-c3vec2 c3vec2_mulf(c3vec2 a, c3f d)
-{
-    a.n[VX] *= d;
-    a.n[VY] *= d;
-    return a;
-}
-
-c3vec2 c3vec2_divf(c3vec2 a, c3f d)
-{
-    c3f d_inv = 1.0f/d;
-    a.n[VX] *= d_inv;
-    a.n[VY] *= d_inv;
-    return a;
-}
-
-/******************** c3vec2 SPECIAL FUNCTIONS ********************/
-
-
-c3f c3vec2_length2(const c3vec2 a)
-{
-    return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY];
-}
-
-c3f c3vec2_length(const c3vec2 a)
-{
-    return (c3f) sqrt(c3vec2_length2(a));
-}
-
-c3vec2 c3vec2_normalize(const c3vec2 a) // it is up to caller to avoid divide-by-zero
-{
-    return c3vec2_divf(a, c3vec2_length(a));
-}
-
-c3vec2 c3vec2_apply(c3vec2 a, V_FCT_PTR fct)
-{
-    a.n[VX] = fct(a.n[VX]);
-    a.n[VY] = fct(a.n[VY]);
-    return a;
-}
-
-
-/******************** c3vec2 FRIENDS *****************************/
-
-c3vec2 c3vec2_minus(const c3vec2 a)
-{
-    return c3vec2f(-a.n[VX],-a.n[VY]);
-}
-
-c3vec2 c3mat3_mulv2(const c3mat3p a, const c3vec2 v)
-{
-  c3vec2 av;
-
-  av.n[VX] = a->v[0].n[VX]*v.n[VX] + a->v[0].n[VY]*v.n[VY] + a->v[0].n[VZ];
-  av.n[VY] = a->v[1].n[VX]*v.n[VX] + a->v[1].n[VY]*v.n[VY] + a->v[1].n[VZ];
-//  av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
-
-  return av;
-}
-
-c3vec2 c3vec2_mulm3(const c3vec2 v, const c3mat3p a)
-{
-       c3mat3 t = c3mat3_transpose(a);
-    return c3mat3_mulv2(&t, v);
-}
-
-c3vec3 c3mat3_mulv3(const c3mat3p a, const c3vec3 v)
-{
-    c3vec3 av;
-
-    av.n[VX] = a->v[0].n[VX]*v.n[VX] + a->v[0].n[VY]*v.n[VY] + a->v[0].n[VZ]*v.n[VZ];
-    av.n[VY] = a->v[1].n[VX]*v.n[VX] + a->v[1].n[VY]*v.n[VY] + a->v[1].n[VZ]*v.n[VZ];
-    av.n[VZ] = a->v[2].n[VX]*v.n[VX] + a->v[2].n[VY]*v.n[VY] + a->v[2].n[VZ]*v.n[VZ];
-
-    return av;
-}
-
-c3vec3 c3vec3_mulm3(const c3vec3 v, const c3mat3p a)
-{
-       c3mat3 t = c3mat3_transpose(a);
-    return c3mat3_mulv3(&t, v);
-}
-
-c3f c3vec2_dot(const c3vec2 a, const c3vec2 b)
-{
-    return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY];
-}
-
-c3vec3 c3vec2_cross(const c3vec2 a, const c3vec2 b)
-{
-    return c3vec3f(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]);
-}
-
-int c3vec2_equal(const c3vec2 a, const c3vec2 b)
-{
-    return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]);
-}
-
-
-c3vec2 c3vec2_min(const c3vec2 a, const c3vec2 b)
-{
-    return c3vec2f(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY]));
-}
-
-c3vec2 c3vec2_max(const c3vec2 a, const c3vec2 b)
-{
-    return c3vec2f(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY]));
-}
-
-c3vec2 c3vec2_prod(const c3vec2 a, const c3vec2 b)
-{
-    return c3vec2f(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]);
-}
-
-/****************************************************************
- *                                                              *
- *          c3vec3 Member functions                               *
- *                                                              *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3vec3 c3vec3_zero()
-{
-       c3vec3 n = { .x = 0, .y = 0, .z = 0 };
-    return n;
-}
-
-c3vec3 c3vec3f(c3f x, c3f y, c3f z)
-{
-       c3vec3 v = { .x = x, .y = y, .z = z };
-       return v;
-}
-
-c3vec3 c3vec3_vec2f(const c3vec2 v, c3f d)
-{
-       c3vec3 n = { .x = v.x, .y = v.y, .z = d };
-       return n;
-}
-
-c3vec3 c3vec3_vec2(const c3vec2 v)
-{
-       return c3vec3_vec2f(v, 1.0);
-}
-
-c3vec3 c3vec3_vec4(const c3vec4 v) // it is up to caller to avoid divide-by-zero
-{
-       c3vec3 n;
-    n.n[VX] = v.n[VX] / v.n[VW];
-    n.n[VY] = v.n[VY] / v.n[VW];
-    n.n[VZ] = v.n[VZ] / v.n[VW];
-    return n;
-}
-
-
-c3vec3 c3vec3_add(c3vec3 a, const c3vec3 v)
-{
-    a.n[VX] += v.n[VX];
-    a.n[VY] += v.n[VY];
-    a.n[VZ] += v.n[VZ];
-    return a;
-}
-
-c3vec3 c3vec3_sub(c3vec3 a, const c3vec3 v)
-{
-       a.n[VX] -= v.n[VX];
-       a.n[VY] -= v.n[VY];
-       a.n[VZ] -= v.n[VZ];
-    return a;
-}
-
-c3vec3 c3vec3_mulf(c3vec3 a, c3f d)
-{
-       a.n[VX] *= d;
-       a.n[VY] *= d;
-       a.n[VZ] *= d;
-    return a;
-}
-
-c3vec3 c3vec3_divf(c3vec3 a, c3f d)
-{
-    c3f d_inv = 1.0f/d;
-    a.n[VX] *= d_inv;
-    a.n[VY] *= d_inv;
-    a.n[VZ] *= d_inv;
-    return a;
-}
-
-// SPECIAL FUNCTIONS
-
-c3f c3vec3_length2(const c3vec3 a)
-{
-    return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY] + a.n[VZ]*a.n[VZ];
-}
-
-c3f c3vec3_length(const c3vec3 a)
-{
-    return (c3f) sqrt(c3vec3_length2(a));
-}
-
-c3vec3 c3vec3_normalize(const c3vec3 a) // it is up to caller to avoid divide-by-zero
-{
-    return c3vec3_divf(a, c3vec3_length(a));
-}
-
-c3vec3 c3vec3_homogenize(c3vec3 a) // it is up to caller to avoid divide-by-zero
-{
-    a.n[VX] /= a.n[VZ];
-    a.n[VY] /= a.n[VZ];
-    a.n[VZ] = 1.0;
-    return a;
-}
-
-c3vec3 c3vec3_apply(c3vec3 a, V_FCT_PTR fct)
-{
-    a.n[VX] = fct(a.n[VX]);
-    a.n[VY] = fct(a.n[VY]);
-    a.n[VZ] = fct(a.n[VZ]);
-    return a;
-}
-
-// FRIENDS
-
-c3vec3 c3vec3_minus(const c3vec3 a)
-{
-    return c3vec3f(-a.n[VX],-a.n[VY],-a.n[VZ]);
-}
-
-#if later
-c3vec3 operator*(const c3mat4 &a, const c3vec3 &v)
-{
-    return a*c3vec4(v);
-}
-
-c3vec3 operator*(const c3vec3 &v, c3mat4 &a)
-{
-    return a.transpose()*v;
-}
-#endif
-
-c3f c3vec3_dot(const c3vec3 a, const c3vec3 b)
-{
-    return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ];
-}
-
-c3vec3 c3vec3_cross(const c3vec3 a, const c3vec3 b)
-{
-    return
-        c3vec3f(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
-             a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
-             a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
-}
-
-int c3vec3_equal(const c3vec3 a, const c3vec3 b)
-{
-    return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
-}
-
-
-c3vec3 c3vec3_min(const c3vec3 a, const c3vec3 b)
-{
-    return c3vec3f(
-        MIN(a.n[VX], b.n[VX]),
-        MIN(a.n[VY], b.n[VY]),
-        MIN(a.n[VZ], b.n[VZ]));
-}
-
-c3vec3 c3vec3_max(const c3vec3 a, const c3vec3 b)
-{
-    return c3vec3f(
-        MAX(a.n[VX], b.n[VX]),
-        MAX(a.n[VY], b.n[VY]),
-        MAX(a.n[VZ], b.n[VZ]));
-}
-
-c3vec3 c3vec3_prod(const c3vec3 a, const c3vec3 b)
-{
-    return c3vec3f(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]);
-}
-
-/****************************************************************
- *                                                              *
- *          c3vec4 Member functions                               *
- *                                                              *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3vec4 c3vec4_zero()
-{
-       c3vec4 n = { .x = 0, .y = 0, .z = 0, .w = 1.0 };
-    return n;
-}
-
-c3vec4 c3vec4f(c3f x, c3f y, c3f z, c3f w)
-{
-       c3vec4 n = { .x = x, .y = y, .z = z, .w = w };
-    return n;
-}
-
-c3vec4 c3vec4_vec3(const c3vec3 v)
-{
-       return c3vec4f(v.n[VX], v.n[VY], v.n[VZ], 1.0);
-}
-
-c3vec4 c3vec4_vec3f(const c3vec3 v, c3f d)
-{
-       return c3vec4f(v.n[VX], v.n[VY], v.n[VZ], d);
-}
-
-// ASSIGNMENT OPERATORS
-
-c3vec4 c3vec4_add(c3vec4 a, const c3vec4 v)
-{
-    a.n[VX] += v.n[VX];
-    a.n[VY] += v.n[VY];
-    a.n[VZ] += v.n[VZ];
-    a.n[VW] += v.n[VW];
-    return a;
-}
-
-c3vec4 c3vec4_sub(c3vec4 a, const c3vec4 v)
-{
-       a.n[VX] -= v.n[VX];
-       a.n[VY] -= v.n[VY];
-       a.n[VZ] -= v.n[VZ];
-       a.n[VW] -= v.n[VW];
-    return a;
-}
-
-c3vec4 c3vec4_mulf(c3vec4 a, c3f d)
-{
-    a.n[VX] *= d;
-    a.n[VY] *= d;
-    a.n[VZ] *= d;
-    a.n[VW] *= d;
-    return a;
-}
-
-c3vec4 c3vec4_divf(c3vec4 a, c3f d)
-{
-    c3f d_inv = 1.0f/d;
-    a.n[VX] *= d_inv;
-    a.n[VY] *= d_inv;
-    a.n[VZ] *= d_inv;
-    a.n[VW] *= d_inv;
-    return a;
-}
-
-// SPECIAL FUNCTIONS
-
-c3f c3vec4_length2(const c3vec4 a)
-{
-    return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY] + a.n[VZ]*a.n[VZ] + a.n[VW]*a.n[VW];
-}
-
-c3f c3vec4_length(const c3vec4 a)
-{
-    return (c3f) sqrt(c3vec4_length2(a));
-}
-
-c3vec4 c3vec4_normalize(c3vec4 a) // it is up to caller to avoid divide-by-zero
-{
-    return c3vec4_divf(a, c3vec4_length(a));
-}
-
-c3vec4 c3vec4_homogenize(c3vec4 a) // it is up to caller to avoid divide-by-zero
-{
-    a.n[VX] /= a.n[VW];
-    a.n[VY] /= a.n[VW];
-    a.n[VZ] /= a.n[VW];
-    a.n[VW] = 1.0;
-    return a;
-}
-
-c3vec4 c3vec4_apply(c3vec4 a, V_FCT_PTR fct)
-{
-    a.n[VX] = fct(a.n[VX]);
-    a.n[VY] = fct(a.n[VY]);
-    a.n[VZ] = fct(a.n[VZ]);
-    a.n[VW] = fct(a.n[VW]);
-    return a;
-}
-
-c3vec4 c3mat4_mulv4(const c3mat4p a, const c3vec4 v)
-{
-    #define ROWCOL(i) \
-        a->v[i].n[0]*v.n[VX] + \
-        a->v[i].n[1]*v.n[VY] + \
-        a->v[i].n[2]*v.n[VZ] + \
-        a->v[i].n[3]*v.n[VW]
-
-    return c3vec4f(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
-
-    #undef ROWCOL
-}
-
-c3vec4 c3vec4_mulm4(const c3vec4 v, const c3mat4p a)
-{
-       c3mat4 m = c3mat4_transpose(a);
-    return c3mat4_mulv4(&m, v);
-}
-
-c3vec3 c3mat4_mulv3(const c3mat4p a, const c3vec3 v)
-{
-       return c3vec3_vec4(c3mat4_mulv4(a, c3vec4_vec3(v)));
-}
-
-c3vec4 c3vec4_minus(const c3vec4 a)
-{
-    return c3vec4f(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
-}
-
-int c3vec4_equal(const c3vec4 a, const c3vec4 b)
-{
-    return
-        (a.n[VX] == b.n[VX]) &&
-        (a.n[VY] == b.n[VY]) &&
-        (a.n[VZ] == b.n[VZ]) &&
-        (a.n[VW] == b.n[VW]);
-}
-
-c3vec4 c3vec4_min(const c3vec4 a, const c3vec4 b)
-{
-    return c3vec4f(
-        MIN(a.n[VX], b.n[VX]),
-        MIN(a.n[VY], b.n[VY]),
-        MIN(a.n[VZ], b.n[VZ]),
-        MIN(a.n[VW], b.n[VW]));
-}
-
-c3vec4 c3vec4_max(const c3vec4 a, const c3vec4 b)
-{
-    return c3vec4f(
-        MAX(a.n[VX], b.n[VX]),
-        MAX(a.n[VY], b.n[VY]),
-        MAX(a.n[VZ], b.n[VZ]),
-        MAX(a.n[VW], b.n[VW]));
-}
-
-c3vec4 c3vec4_prod(const c3vec4 a, const c3vec4 b)
-{
-    return c3vec4f(
-        a.n[VX] * b.n[VX],
-        a.n[VY] * b.n[VY],
-        a.n[VZ] * b.n[VZ],
-        a.n[VW] * b.n[VW]);
-}
-
-/****************************************************************
- *                                                              *
- *          c3mat3 member functions                               *
- *                                                              *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3mat3 c3mat3_identity()
-{
-       return identity2D();
-}
-
-c3mat3 c3mat3_vec3(const c3vec3 v0, const c3vec3 v1, const c3vec3 v2)
-{
-       c3mat3 m = { .v[0] = v0, .v[1] = v1, .v[2] = v2 };
-       return m;
-}
-
-c3mat3p c3mat3_add(const c3mat3p a, const c3mat3p m)
-{
-       a->v[0] = c3vec3_add(a->v[0], m->v[0]);
-       a->v[1] = c3vec3_add(a->v[1], m->v[1]);
-       a->v[2] = c3vec3_add(a->v[2], m->v[2]);
-    return a;
-}
-
-c3mat3p c3mat3_sub(const c3mat3p a, const c3mat3p m)
-{
-       a->v[0] = c3vec3_sub(a->v[0], m->v[0]);
-       a->v[1] = c3vec3_sub(a->v[1], m->v[1]);
-       a->v[2] = c3vec3_sub(a->v[2], m->v[2]);
-    return a;
-}
-
-c3mat3p c3mat3_mulf(const c3mat3p a, c3f d)
-{
-       a->v[0] = c3vec3_mulf(a->v[0], d);
-       a->v[1] = c3vec3_mulf(a->v[1], d);
-       a->v[2] = c3vec3_mulf(a->v[2], d);
-    return a;
-}
-
-c3mat3p c3mat3_divf(const c3mat3p a, c3f d)
-{
-       a->v[0] = c3vec3_divf(a->v[0], d);
-       a->v[1] = c3vec3_divf(a->v[1], d);
-       a->v[2] = c3vec3_divf(a->v[2], d);
-    return a;
-}
-
-// SPECIAL FUNCTIONS
-
-c3mat3 c3mat3_transpose(const c3mat3p a)
-{
-    return c3mat3_vec3(
-        c3vec3f(a->v[0].n[0], a->v[1].n[0], a->v[2].n[0]),
-        c3vec3f(a->v[0].n[1], a->v[1].n[1], a->v[2].n[1]),
-        c3vec3f(a->v[0].n[2], a->v[1].n[2], a->v[2].n[2]));
-}
-
-c3mat3 c3mat3_inverse(const c3mat3p m)   // Gauss-Jordan elimination with partial pivoting
-{
-       c3mat3 a = *m; // As a evolves from original mat into identity
-       c3mat3 b = c3mat3_identity(); // b evolves from identity into inverse(a)
-       int i, j, i1;
-
-       // Loop over cols of a from left to right, eliminating above and below diag
-       for (j = 0; j < 3; j++) { // Find largest pivot in column j among rows j..2
-               i1 = j; // Row with largest pivot candidate
-               for (i = j + 1; i < 3; i++)
-                       if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
-                               i1 = i;
-
-               // Swap rows i1 and j in a and b to put pivot on diagonal
-               c3vec3 _s;
-               _s = a.v[i1]; a.v[i1] = a.v[j]; a.v[j] = _s;  // swap(a.v[i1], a.v[j]);
-               _s = b.v[i1]; b.v[i1] = b.v[j]; b.v[j] = _s;  //swap(b.v[i1], b.v[j]);
-
-               // Scale row j to have a unit diagonal
-               if (a.v[j].n[j] == 0.) {
-               //      VEC_ERROR("c3mat3::inverse: singular matrix; can't invert\n");
-                       return *m;
-               }
-
-               b.v[j] = c3vec3_divf(b.v[j], a.v[j].n[j]);
-               a.v[j] = c3vec3_divf(a.v[j], a.v[j].n[j]);
-
-               // Eliminate off-diagonal elems in col j of a, doing identical ops to b
-               for (i = 0; i < 3; i++)
-                       if (i != j) {
-                               b.v[i] = c3vec3_sub(b.v[i], c3vec3_mulf(b.v[j], a.v[i].n[j]));
-                               a.v[i] = c3vec3_sub(a.v[i], c3vec3_mulf(a.v[j], a.v[i].n[j]));
-                       }
-       }
-
-       return b;
-}
-
-c3mat3p c3mat3_apply(c3mat3p a, V_FCT_PTR fct)
-{
-       a->v[0] = c3vec3_apply(a->v[0], fct);
-       a->v[1] = c3vec3_apply(a->v[1], fct);
-       a->v[2] = c3vec3_apply(a->v[2], fct);
-    return a;
-}
-
-
-c3mat3 c3mat3_minus(const c3mat3p a)
-{
-    return c3mat3_vec3(
-               c3vec3_minus(a->v[0]),
-               c3vec3_minus(a->v[1]),
-               c3vec3_minus(a->v[2]));
-}
-
-c3mat3 c3mat3_mul(const c3mat3p a, const c3mat3p b)
-{
-    #define ROWCOL(i, j) \
-    a->v[i].n[0]*b->v[0].n[j] + a->v[i].n[1]*b->v[1].n[j] + a->v[i].n[2]*b->v[2].n[j]
-
-    return c3mat3_vec3(
-        c3vec3f(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
-        c3vec3f(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
-        c3vec3f(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
-
-    #undef ROWCOL
-}
-
-int c3mat3_equal(const c3mat3p a, const c3mat3p b)
-{
-    return
-        c3vec3_equal(a->v[0], b->v[0]) &&
-        c3vec3_equal(a->v[1], b->v[1]) &&
-        c3vec3_equal(a->v[2], b->v[2]);
-}
-
-/****************************************************************
- *                                                              *
- *          c3mat4 member functions                               *
- *                                                              *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3mat4 c3mat4_identity()
-{
-    return identity3D();
-}
-
-c3mat4 c3mat4_vec4(const c3vec4 v0, const c3vec4 v1, const c3vec4 v2, const c3vec4 v3)
-{
-       c3mat4 m = { .v[0] = v0, .v[1] = v1, .v[2] = v2, .v[3] = v3 };
-       return m;
-}
-
-c3mat4 c3mat4f(
-     c3f a00, c3f a01, c3f a02, c3f a03,
-     c3f a10, c3f a11, c3f a12, c3f a13,
-     c3f a20, c3f a21, c3f a22, c3f a23,
-     c3f a30, c3f a31, c3f a32, c3f a33 )
-{
-       c3mat4 m;
-       m.v[0] = c3vec4f(a00, a01, a01, a03);
-       m.v[1] = c3vec4f(a10, a11, a11, a13);
-       m.v[2] = c3vec4f(a20, a21, a21, a23);
-       m.v[3] = c3vec4f(a30, a31, a21, a33);
-       return m;
-}
-
-c3mat4p c3mat4p_add(c3mat4p a, const c3mat4p m)
-{
-    a->v[0] = c3vec4_add(a->v[0], m->v[0]);
-    a->v[1] = c3vec4_add(a->v[1], m->v[1]);
-    a->v[2] = c3vec4_add(a->v[2], m->v[2]);
-    a->v[3] = c3vec4_add(a->v[3], m->v[3]);
-    return a;
-}
-
-c3mat4p c3mat4p_sub(c3mat4p a, const c3mat4p m)
-{
-    a->v[0] = c3vec4_sub(a->v[0], m->v[0]);
-    a->v[1] = c3vec4_sub(a->v[1], m->v[1]);
-    a->v[2] = c3vec4_sub(a->v[2], m->v[2]);
-    a->v[3] = c3vec4_sub(a->v[3], m->v[3]);
-    return a;
-}
-
-c3mat4p c3mat4p_mulf(c3mat4p a, c3f d)
-{
-    a->v[0] = c3vec4_mulf(a->v[0], d);
-    a->v[1] = c3vec4_mulf(a->v[1], d);
-    a->v[2] = c3vec4_mulf(a->v[2], d);
-    a->v[3] = c3vec4_mulf(a->v[3], d);
-    return a;
-}
-
-c3mat4p c3mat4p_divf(c3mat4p a, c3f d)
-{
-    a->v[0] = c3vec4_divf(a->v[0], d);
-    a->v[1] = c3vec4_divf(a->v[1], d);
-    a->v[2] = c3vec4_divf(a->v[2], d);
-    a->v[3] = c3vec4_divf(a->v[3], d);
-    return a;
-}
-
-// SPECIAL FUNCTIONS;
-
-c3mat4 c3mat4_transpose(const c3mat4p a)
-{
-    return c3mat4_vec4(
-        c3vec4f(a->v[0].n[0], a->v[1].n[0], a->v[2].n[0], a->v[3].n[0]),
-        c3vec4f(a->v[0].n[1], a->v[1].n[1], a->v[2].n[1], a->v[3].n[1]),
-        c3vec4f(a->v[0].n[2], a->v[1].n[2], a->v[2].n[2], a->v[3].n[2]),
-        c3vec4f(a->v[0].n[3], a->v[1].n[3], a->v[2].n[3], a->v[3].n[3]));
-}
-
-c3mat4 c3mat4_inverse(const c3mat4p m)       // Gauss-Jordan elimination with partial pivoting
-{
-       c3mat4 a = *m; // As a evolves from original mat into identity
-       c3mat4 b = identity3D(); // b evolves from identity into inverse(a)
-       int i, j, i1;
-
-       // Loop over cols of a from left to right, eliminating above and below diag
-       for (j = 0; j < 4; j++) { // Find largest pivot in column j among rows j..3
-               i1 = j; // Row with largest pivot candidate
-               for (i = j + 1; i < 4; i++)
-                       if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
-                               i1 = i;
-
-               // Swap rows i1 and j in a and b to put pivot on diagonal
-               c3vec4 _s;
-               _s = a.v[i1]; a.v[i1] = a.v[j]; a.v[j] = _s; // swap(a.v[i1], a.v[j]);
-               _s = b.v[i1]; b.v[i1] = b.v[j]; b.v[j] = _s; // swap(b.v[i1], b.v[j]);
-
-               // Scale row j to have a unit diagonal
-               if (a.v[j].n[j] == 0.) {
-                       //    VEC_ERROR("c3mat4::inverse: singular matrix; can't invert\n");
-                       return a;
-               }
-               b.v[j] = c3vec4_divf(b.v[j], a.v[j].n[j]);
-               a.v[j] = c3vec4_divf(a.v[j], a.v[j].n[j]);
-
-               // Eliminate off-diagonal elems in col j of a, doing identical ops to b
-               for (i = 0; i < 4; i++)
-                       if (i != j) {
-                               b.v[i] = c3vec4_sub(b.v[i], c3vec4_mulf(b.v[j], a.v[i].n[j]));
-                               a.v[i] = c3vec4_sub(a.v[i], c3vec4_mulf(a.v[j], a.v[i].n[j]));
-                       }
-       }
-
-       return b;
-}
-
-c3mat4p c3mat4p_apply(c3mat4p a, V_FCT_PTR fct)
-{
-       a->v[0] = c3vec4_apply(a->v[0], fct);
-       a->v[1] = c3vec4_apply(a->v[1], fct);
-       a->v[2] = c3vec4_apply(a->v[2], fct);
-       a->v[3] = c3vec4_apply(a->v[3], fct);
-    return a;
-}
-
-c3mat4p c3mat4p_swap_rows(c3mat4p a, int i, int j)
-{
-    c3vec4 t;
-
-    t    = a->v[i];
-    a->v[i] = a->v[j];
-    a->v[j] = t;
-    return a;
-}
-
-c3mat4p c3mat4p_swap_cols(c3mat4p a, int i, int j)
-{
-       c3f t;
-
-       for (int k = 0; k < 4; k++) {
-               t = a->v[k].n[i];
-               a->v[k].n[i] = a->v[k].n[j];
-               a->v[k].n[j] = t;
-       }
-       return a;
-}
-
-
-// FRIENDS
-
-c3mat4 c3mat4_minus(const c3mat4p a)
-{
-    return c3mat4_vec4(
-               c3vec4_minus(a->v[0]),
-               c3vec4_minus(a->v[1]),
-               c3vec4_minus(a->v[2]),
-               c3vec4_minus(a->v[3]));
-}
-
-c3mat4 c3mat4_add(const c3mat4p a, const c3mat4p b)
-{
-    return c3mat4_vec4(
-        c3vec4_add(a->v[0], b->v[0]),
-        c3vec4_add(a->v[1], b->v[1]),
-        c3vec4_add(a->v[2], b->v[2]),
-        c3vec4_add(a->v[3], b->v[3]));
-}
-
-c3mat4 c3mat4_sub(const c3mat4p a, const c3mat4p b)
-{
-    return c3mat4_vec4(
-        c3vec4_sub(a->v[0], b->v[0]),
-        c3vec4_sub(a->v[1], b->v[1]),
-        c3vec4_sub(a->v[2], b->v[2]),
-        c3vec4_sub(a->v[3], b->v[3]));
-}
-
-c3mat4 c3mat4_mul(const c3mat4p a, const c3mat4p b)
-{
-    #define ROWCOL(i, j) \
-        a->v[i].n[0]*b->v[0].n[j] + \
-        a->v[i].n[1]*b->v[1].n[j] + \
-        a->v[i].n[2]*b->v[2].n[j] + \
-        a->v[i].n[3]*b->v[3].n[j]
-
-    return c3mat4_vec4(
-        c3vec4f(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
-        c3vec4f(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
-        c3vec4f(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
-        c3vec4f(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
-        );
-
-    #undef ROWCOL
-}
-
-c3mat4 c3mat4_mulf(const c3mat4p a, c3f d)
-{
-       c3mat4 r = *a;
-       return *c3mat4p_mulf(&r, d);
-}
-
-c3mat4 c3mat4_divf(const c3mat4p a, c3f d)
-{
-       c3mat4 r = *a;
-       return *c3mat4p_divf(&r, d);
-}
-
-int c3mat4_equal(const c3mat4p a, const c3mat4p b)
-{
-       return !memcmp(a->n, b->n, sizeof(a->n));
-#if 0
-    return
-        c3vec4_equal(a->v[0], b->v[0]) &&
-        c3vec4_equal(a->v[1], b->v[1]) &&
-        c3vec4_equal(a->v[2], b->v[2]) &&
-        c3vec4_equal(a->v[3], b->v[3]);
-#endif
-}
-
-/****************************************************************
- *                                                              *
- *         2D functions and 3D functions                        *
- *                                                              *
- ****************************************************************/
-
-c3mat3 identity2D()
-{
-    return c3mat3_vec3(
-        c3vec3f(1.0, 0.0, 0.0),
-        c3vec3f(0.0, 1.0, 0.0),
-        c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat3 translation2D(const c3vec2 v)
-{
-    return c3mat3_vec3(
-        c3vec3f(1.0, 0.0, v.n[VX]),
-        c3vec3f(0.0, 1.0, v.n[VY]),
-        c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat3 rotation2D(const c3vec2 Center, c3f angleDeg)
-{
-    c3f angleRad = (c3f) (angleDeg * M_PI / 180.0);
-    c3f c = (c3f) cos(angleRad);
-    c3f s = (c3f) sin(angleRad);
-
-    return c3mat3_vec3(
-        c3vec3f(c,    -s, Center.n[VX] * (1.0f-c) + Center.n[VY] * s),
-        c3vec3f(s,     c, Center.n[VY] * (1.0f-c) - Center.n[VX] * s),
-        c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat3 scaling2D(const c3vec2 scaleVector)
-{
-    return c3mat3_vec3(
-        c3vec3f(scaleVector.n[VX], 0.0, 0.0),
-        c3vec3f(0.0, scaleVector.n[VY], 0.0),
-        c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat4 identity3D()
-{
-    return c3mat4_vec4(
-        c3vec4f(1.0, 0.0, 0.0, 0.0),
-        c3vec4f(0.0, 1.0, 0.0, 0.0),
-        c3vec4f(0.0, 0.0, 1.0, 0.0),
-        c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 translation3D(const c3vec3 v)
-{
-    return c3mat4_vec4(
-        c3vec4f(1.0, 0.0, 0.0, v.n[VX]),
-        c3vec4f(0.0, 1.0, 0.0, v.n[VY]),
-        c3vec4f(0.0, 0.0, 1.0, v.n[VZ]),
-        c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 rotation3D(const c3vec3 Axis, c3f angleDeg)
-{
-    c3f angleRad = (c3f) (angleDeg * M_PI / 180.0);
-    c3f c = (c3f) cos(angleRad);
-    c3f s = (c3f) sin(angleRad);
-    c3f t = 1.0f - c;
-
-    c3vec3 axis = c3vec3_normalize(Axis);
-
-    return c3mat4_vec4(
-        c3vec4f(t * axis.n[VX] * axis.n[VX] + c,
-             t * axis.n[VX] * axis.n[VY] - s * axis.n[VZ],
-             t * axis.n[VX] * axis.n[VZ] + s * axis.n[VY],
-             0.0),
-        c3vec4f(t * axis.n[VX] * axis.n[VY] + s * axis.n[VZ],
-             t * axis.n[VY] * axis.n[VY] + c,
-             t * axis.n[VY] * axis.n[VZ] - s * axis.n[VX],
-             0.0),
-        c3vec4f(t * axis.n[VX] * axis.n[VZ] - s * axis.n[VY],
-             t * axis.n[VY] * axis.n[VZ] + s * axis.n[VX],
-             t * axis.n[VZ] * axis.n[VZ] + c,
-             0.0),
-        c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 rotation3Drad(const c3vec3 Axis, c3f angleRad)
-{
-    c3f c = (c3f) cos(angleRad);
-    c3f s = (c3f) sin(angleRad);
-    c3f t = 1.0f - c;
-
-    c3vec3 axis = c3vec3_normalize(Axis);
-
-    return c3mat4_vec4(
-        c3vec4f(t * axis.n[VX] * axis.n[VX] + c,
-             t * axis.n[VX] * axis.n[VY] - s * axis.n[VZ],
-             t * axis.n[VX] * axis.n[VZ] + s * axis.n[VY],
-             0.0),
-        c3vec4f(t * axis.n[VX] * axis.n[VY] + s * axis.n[VZ],
-             t * axis.n[VY] * axis.n[VY] + c,
-             t * axis.n[VY] * axis.n[VZ] - s * axis.n[VX],
-             0.0),
-        c3vec4f(t * axis.n[VX] * axis.n[VZ] - s * axis.n[VY],
-             t * axis.n[VY] * axis.n[VZ] + s * axis.n[VX],
-             t * axis.n[VZ] * axis.n[VZ] + c,
-             0.0),
-        c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 scaling3D(const c3vec3 scaleVector)
-{
-    return c3mat4_vec4(
-        c3vec4f(scaleVector.n[VX], 0.0, 0.0, 0.0),
-        c3vec4f(0.0, scaleVector.n[VY], 0.0, 0.0),
-        c3vec4f(0.0, 0.0, scaleVector.n[VZ], 0.0),
-        c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 perspective3D(c3f d)
-{
-    return c3mat4_vec4(
-        c3vec4f(1.0f, 0.0f, 0.0f,   0.0f),
-        c3vec4f(0.0f, 1.0f, 0.0f,   0.0f),
-        c3vec4f(0.0f, 0.0f, 1.0f,   0.0f),
-        c3vec4f(0.0f, 0.0f, 1.0f/d, 0.0f));
-}
-
diff --git a/examples/board_reprap/src/c3/c3algebra.h b/examples/board_reprap/src/c3/c3algebra.h
deleted file mode 100644 (file)
index d2b71a1..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-       c3algebra.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       Derivative and inspiration from original C++:
-       Paul Rademacher & Jean-Francois DOUEG,
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3ALGEBRA_H___
-#define __C3ALGEBRA_H___
-
-
-#ifndef M_PI
-#define M_PI 3.141592654
-#endif
-
-enum {VX, VY, VZ, VW};           // axes
-enum {PA, PB, PC, PD};           // planes
-enum {RED, GREEN, BLUE, ALPHA};  // colors
-enum {KA, KD, KS, ES};           // phong coefficients
-
-typedef float c3f;
-typedef c3f (*V_FCT_PTR)(c3f);
-
-typedef union c3vec2 {
-       struct { c3f x,y; };
-       c3f n[2];
-} c3vec2;
-
-typedef union c3vec3 {
-       struct { c3f x,y,z; };
-       c3f n[3];
-} c3vec3;
-
-typedef union c3vec4 {
-       struct { c3f x,y,z,w; };
-       c3f n[4];
-} c3vec4, * c3vec4p;
-
-typedef union c3mat3 {
-       c3vec3 v[3];
-       c3f n[3*3];
-} c3mat3, * c3mat3p;
-
-typedef union c3mat4 {
-       c3vec4 v[4];
-       c3f n[4*4];
-} c3mat4, * c3mat4p;
-
-/*
- * c3vec2 related
- */
-
-c3vec2 c3vec2_zero();
-c3vec2 c3vec2f(c3f x, c3f y);
-
-c3vec2 c3vec2_add(c3vec2 a, const c3vec2 v);
-c3vec2 c3vec2_sub(c3vec2 a, const c3vec2 v);
-c3vec2 c3vec2_mulf(c3vec2 a, c3f d);
-c3vec2 c3vec2_divf(c3vec2 a, c3f d);
-
-c3f            c3vec2_length2(const c3vec2 a);
-c3f            c3vec2_length(const c3vec2 a);
-c3vec2 c3vec2_normalize(const c3vec2 a); // it is up to caller to avoid divide-by-zero
-c3vec2 c3vec2_apply(c3vec2 a, V_FCT_PTR fct);
-c3vec2 c3vec2_minus(const c3vec2 a);
-c3f            c3vec2_dot(const c3vec2 a, const c3vec2 b);
-c3vec2 c3vec2_min(const c3vec2 a, const c3vec2 b);
-c3vec2 c3vec2_max(const c3vec2 a, const c3vec2 b);
-c3vec2 c3vec2_prod(const c3vec2 a, const c3vec2 b);
-
-/*
- * c3vec4 related
- */
-
-c3vec3 c3vec3_zero();
-c3vec3 c3vec3f(c3f x, c3f y, c3f z);
-c3vec3 c3vec3_vec2f(const c3vec2 v, c3f d);
-c3vec3 c3vec3_vec2(const c3vec2 v);
-c3vec3 c3vec3_vec4(const c3vec4 v); // it is up to caller to avoid divide-by-zero
-
-c3vec3 c3vec3_add(const c3vec3 a, const c3vec3 v);
-c3vec3 c3vec3_sub(const c3vec3 a, const c3vec3 v);
-c3vec3 c3vec3_mulf(const c3vec3 a, c3f d);
-c3vec3 c3vec3_divf(const c3vec3 a, c3f d);
-
-c3f            c3vec3_length2(const c3vec3 a);
-c3f            c3vec3_length(const c3vec3 a);
-c3vec3 c3vec3_normalize(const c3vec3 a); // it is up to caller to avoid divide-by-zero
-c3vec3 c3vec3_homogenize(c3vec3 a); // it is up to caller to avoid divide-by-zero
-c3vec3 c3vec3_apply(c3vec3 a, V_FCT_PTR fct);
-c3vec3 c3vec3_minus(const c3vec3 a);
-c3f            c3vec3_dot(const c3vec3 a, const c3vec3 b);
-int            c3vec3_equal(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec3_min(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec3_max(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec3_prod(const c3vec3 a, const c3vec3 b);
-
-c3vec3 c3vec3_cross(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec2_cross(const c3vec2 a, const c3vec2 b);
-
-/*
- * c3vec4 related
- */
-
-c3vec4 c3vec4_zero();
-c3vec4 c3vec4f(c3f x, c3f y, c3f z, c3f w);
-c3vec4 c3vec4_vec3(const c3vec3 v);
-c3vec4 c3vec4_vec3f(const c3vec3 v, c3f d);
-
-c3vec4 c3vec4_add(c3vec4 a, const c3vec4 v);
-c3vec4 c3vec4_sub(c3vec4 a, const c3vec4 v);
-c3vec4 c3vec4_mulf(c3vec4 a, c3f d);
-c3vec4 c3vec4_divf(c3vec4 a, c3f d);
-
-c3f            c3vec4_length2(const c3vec4 a);
-c3f            c3vec4_length(const c3vec4 a);
-c3vec4 c3vec4_normalize(c3vec4 a); // it is up to caller to avoid divide-by-zero
-c3vec4 c3vec4_homogenize(c3vec4 a); // it is up to caller to avoid divide-by-zero
-c3vec4 c3vec4_apply(c3vec4 a, V_FCT_PTR fct);
-c3vec4 c3vec4_minus(const c3vec4 a);
-int            c3vec4_equal(const c3vec4 a, const c3vec4 b);
-c3vec4 c3vec4_min(const c3vec4 a, const c3vec4 b);
-c3vec4 c3vec4_max(const c3vec4 a, const c3vec4 b);
-c3vec4 c3vec4_prod(const c3vec4 a, const c3vec4 b);
-
-/*
- * c3mat3 related
- */
-
-c3mat3 c3mat3_identity();
-c3mat3 c3mat3_vec3(const c3vec3 v0, const c3vec3 v1, const c3vec3 v2);
-c3mat3p        c3mat3_add(const c3mat3p a, const c3mat3p m);
-c3mat3p        c3mat3_sub(const c3mat3p a, const c3mat3p m);
-c3mat3p        c3mat3_mulf(const c3mat3p a, c3f d);
-c3mat3p        c3mat3_divf(const c3mat3p a, c3f d);
-
-c3mat3 c3mat3_transpose(const c3mat3p a);
-c3mat3 c3mat3_inverse(const c3mat3p m);   // Gauss-Jordan elimination with partial pivoting
-c3mat3p        c3mat3_apply(c3mat3p a, V_FCT_PTR fct);
-c3mat3 c3mat3_minus(const c3mat3p a);
-
-c3mat3 c3mat3_mul(const c3mat3p a, const c3mat3p b);
-int            c3mat3_equal(const c3mat3p a, const c3mat3p b);
-
-c3vec2 c3mat3_mulv2(const c3mat3p a, const c3vec2 v);
-c3vec3 c3mat3_mulv3(const c3mat3p a, const c3vec3 v);
-c3vec2 c3vec2_mulm3(const c3vec2 v, const c3mat3p a);
-c3vec3 c3vec3_mulm3(const c3vec3 v, const c3mat3p a);
-
-c3mat3 identity2D();
-c3mat3 translation2D(const c3vec2 v);
-c3mat3 rotation2D(const c3vec2 Center, c3f angleDeg);
-c3mat3 scaling2D(const c3vec2 scaleVector);
-
-/*
- * c3mat4 related
- */
-
-c3mat4 c3mat4_identity();
-c3mat4 c3mat4_vec4(const c3vec4 v0, const c3vec4 v1, const c3vec4 v2, const c3vec4 v3);
-c3mat4 c3mat4f(
-     c3f a00, c3f a01, c3f a02, c3f a03,
-     c3f a10, c3f a11, c3f a12, c3f a13,
-     c3f a20, c3f a21, c3f a22, c3f a23,
-     c3f a30, c3f a31, c3f a32, c3f a33 );
-
-c3mat4 c3mat4_minus(const c3mat4p a);
-c3mat4p        c3mat4p_add(c3mat4p a, const c3mat4p m);
-c3mat4 c3mat4_add(const c3mat4p a, const c3mat4p b);
-c3mat4p        c3mat4p_sub(c3mat4p a, const c3mat4p m);
-c3mat4 c3mat4_sub(const c3mat4p a, const c3mat4p b);
-c3mat4p        c3mat4p_mulf(c3mat4p a, c3f d);
-c3mat4         c3mat4_mulf(const c3mat4p a, c3f d);
-c3mat4 c3mat4_mul(const c3mat4p a, const c3mat4p b);
-c3mat4p        c3mat4p_divf(c3mat4p a, c3f d);
-c3mat4 c3mat4_divf(const c3mat4p a, c3f d);
-
-c3mat4 c3mat4_transpose(const c3mat4p a);
-c3mat4 c3mat4_inverse(const c3mat4p m);       // Gauss-Jordan elimination with partial pivoting
-c3mat4p        c3mat4p_apply(c3mat4p a, V_FCT_PTR fct);
-c3mat4p        c3mat4p_swap_rows(c3mat4p a, int i, int j);
-c3mat4p        c3mat4p_swap_cols(c3mat4p a, int i, int j);
-int            c3mat4_equal(const c3mat4p a, const c3mat4p b);
-
-c3vec4 c3vec4_mulm4(const c3vec4 v, const c3mat4p a);
-c3vec4 c3mat4_mulv4(const c3mat4p a, const c3vec4 v);
-c3vec3 c3mat4_mulv3(const c3mat4p a, const c3vec3 v);
-
-c3mat4 identity3D();
-c3mat4 translation3D(const c3vec3 v);
-c3mat4 rotation3D(const c3vec3 Axis, c3f angleDeg);
-c3mat4 rotation3Drad(const c3vec3 Axis, c3f angleRad);
-c3mat4 scaling3D(const c3vec3 scaleVector);
-c3mat4 perspective3D(c3f d);
-
-#endif /* __C3ALGEBRA_H___ */
diff --git a/examples/board_reprap/src/c3/c3arcball.c b/examples/board_reprap/src/c3/c3arcball.c
deleted file mode 100644 (file)
index ff412d8..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
-       c3arcball.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include "c3/c3arcball.h"
-
-
-/**************************************** c3arcball_init_mat4() ****/
-/* Takes as argument a c3mat4 to use instead of the internal rot  */
-
-void
-c3arcball_init_mat4(
-               c3arcballp a,
-               c3mat4p mtx )
-{
-    c3arcball_init(a);
-    a->rot_ptr = mtx;
-}
-
-
-/**************************************** c3arcball_init_center() ****/
-/* A constructor that accepts the screen center and arcball radius*/
-
-void
-c3arcball_init_center(
-               c3arcballp a,
-               const c3vec2 center,
-               c3f radius )
-{
-    c3arcball_init(a);
-    c3arcball_set_params(a, center, radius);
-}
-
-
-/************************************** c3arcball_set_params() ****/
-
-void
-c3arcball_set_params(
-               c3arcballp a,
-               const c3vec2 center,
-               c3f radius)
-{
-    a->center      = center;
-    a->radius      = radius;
-}
-
-/*************************************** c3arcball_init() **********/
-
-void
-c3arcball_init(
-               c3arcballp a )
-{
-    a->center = c3vec2f( 0.0, 0.0 );
-    a->radius         = 1.0;
-    a->q_now          = c3quat_identity();
-    a->rot_ptr         = &a->rot;
-    a->rot             = identity3D();
-    a->q_increment    = c3quat_identity();
-    a->rot_increment  = identity3D();
-    a->is_mouse_down  = false;
-    a->is_spinning    = false;
-    a->damp_factor    = 0.0;
-    a->zero_increment = true;
-}
-
-/*********************************** c3arcball_mouse_to_sphere() ****/
-
-c3vec3
-c3arcball_mouse_to_sphere(
-               c3arcballp a,
-               const c3vec2 p)
-{
-    c3f mag;
-    c3vec2  v2 = c3vec2_divf(c3vec2_sub(p, a->center), a->radius);
-    c3vec3  v3 = c3vec3f( v2.n[0], v2.n[1], 0.0 );
-
-    mag = c3vec2_dot(v2, v2);
-
-    if ( mag > 1.0 )
-        v3 = c3vec3_normalize(v3);
-    else
-        v3.n[VZ] = (c3f) sqrt( 1.0 - mag );
-
-    /* Now we add constraints - X takes precedence over Y */
-    if ( a->constraint_x ) {
-        v3 = c3arcball_constrain_vector( v3, c3vec3f( 1.0, 0.0, 0.0 ));
-    } else if ( a->constraint_y ) {
-       v3 = c3arcball_constrain_vector( v3, c3vec3f( 0.0, 1.0, 0.0 ));
-       }
-
-    return v3;
-}
-
-
-/************************************ c3arcball_constrain_vector() ****/
-
-c3vec3
-c3arcball_constrain_vector(
-               const c3vec3 vector,
-               const c3vec3 axis)
-{
-//    return (vector - (vector * axis) * axis).normalize();
-    return vector;
-}
-
-/************************************ c3arcball_mouse_down() **********/
-
-void
-c3arcball_mouse_down(
-               c3arcballp a,
-               int x,
-               int y)
-{
-    a->down_pt = c3vec2f( (c3f)x, (c3f) y );
-    a->is_mouse_down = true;
-
-    a->q_increment   = c3quat_identity();
-    a->rot_increment = identity3D();
-    a->zero_increment = true;
-}
-
-
-/************************************ c3arcball_mouse_up() **********/
-
-void
-c3arcball_mouse_up(
-               c3arcballp a)
-{
-    a->q_now = c3quat_mul(a->q_drag, a->q_now);
-    a->is_mouse_down = false;
-}
-
-
-/********************************** c3arcball_mouse_motion() **********/
-
-void
-c3arcball_mouse_motion(
-               c3arcballp a,
-               int x,
-               int y,
-               int shift,
-               int ctrl,
-               int alt)
-{
-    /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
-       c3arcball_set_constraints(a, ctrl != 0, alt != 0 );
-
-    c3vec2 new_pt = c3vec2f( (c3f)x, (c3f) y );
-    c3vec3 v0 = c3arcball_mouse_to_sphere(a, a->down_pt );
-    c3vec3 v1 = c3arcball_mouse_to_sphere(a, new_pt );
-
-    c3vec3 cross = c3vec3_cross(v0, v1);
-
-    a->q_drag = c3quat_vec3(cross, c3vec3_dot(v0, v1));
-
-    //    *rot_ptr = (q_drag * q_now).to_mat4();
-    c3mat4 temp = c3quat_to_mat4(a->q_drag);
-    *a->rot_ptr = c3mat4_mul(a->rot_ptr, &temp);
-
-    a->down_pt = new_pt;
-
-    /* We keep a copy of the current incremental rotation (= q_drag) */
-    a->q_increment   = a->q_drag;
-    a->rot_increment = c3quat_to_mat4(a->q_increment);
-
-    c3arcball_set_constraints(a, false, false);
-
-       if (a->q_increment.s < .999999) {
-               a->is_spinning = true;
-               a->zero_increment = false;
-       } else {
-               a->is_spinning = false;
-               a->zero_increment = true;
-       }
-}
-
-
-/********************************** c3arcball_mouse_motion() **********/
-#if 0
-void
-c3arcball_mouse_motion(
-               c3arcballp a,
-               int x,
-               int y)
-{
-    mouse_motion(x, y, 0, 0, 0);
-}
-#endif
-
-/***************************** c3arcball_set_constraints() **********/
-
-void
-c3arcball_set_constraints(
-               c3arcballp a,
-               bool _constraint_x,
-               bool _constraint_y)
-{
-    a->constraint_x = _constraint_x;
-    a->constraint_y = _constraint_y;
-}
-
-/***************************** c3arcball_idle() *********************/
-
-void
-c3arcball_idle(
-               c3arcballp a)
-{
-       if (a->is_mouse_down) {
-               a->is_spinning = false;
-               a->zero_increment = true;
-       }
-
-       if (a->damp_factor < 1.0f)
-               c3quat_scale_angle(&a->q_increment, 1.0f - a->damp_factor);
-
-       a->rot_increment = c3quat_to_mat4(a->q_increment);
-
-       if (a->q_increment.s >= .999999f) {
-               a->is_spinning = false;
-               a->zero_increment = true;
-       }
-}
-
-
-/************************ c3arcball_set_damping() *********************/
-
-void
-c3arcball_set_damping(
-               c3arcballp a,
-               c3f d)
-{
-    a->damp_factor = d;
-}
-
-
-
diff --git a/examples/board_reprap/src/c3/c3arcball.h b/examples/board_reprap/src/c3/c3arcball.h
deleted file mode 100644 (file)
index 2adba8b..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-       c3arcball.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-       Copyright (c) 1998 Paul Rademacher
-    Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
-    Oct 2003, Nigel Stewart - GLUI Code Cleaning
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
-       Arcball, as described by Ken
-       Shoemake in Graphics Gems IV.
-       This class takes as input mouse events (mouse down, mouse drag,
-       mouse up), and creates the appropriate quaternions and 4x4 matrices
-       to represent the rotation given by the mouse.
-
-       This class is used as follows:
-       - initialize [either in the constructor or with set_params()], the
-       center position (x,y) of the arcball on the screen, and the radius
-       - on mouse down, call mouse_down(x,y) with the mouse position
-       - as the mouse is dragged, repeatedly call mouse_motion() with the
-       current x and y positions.  One can optionally pass in the current
-       state of the SHIFT, ALT, and CONTROL keys (passing zero if keys
-       are not pressed, non-zero otherwise), which constrains
-       the rotation to certain axes (X for CONTROL, Y for ALT).
-       - when the mouse button is released, call mouse_up()
-
-       Axis constraints can also be explicitly set with the
-       set_constraints() function.
-
-       The current rotation is stored in the 4x4 float matrix 'rot'.
-       It is also stored in the quaternion 'q_now'.
- */
-
-#ifndef __C3ARCBALL_H___
-#define __C3ARCBALL_H___
-
-#include "c3/c3quaternion.h"
-
-typedef struct c3arcball {
-    int        is_mouse_down : 1,  /* true for down, false for up */
-               is_spinning : 1,
-               constraint_x : 1,
-               constraint_y : 1,
-               zero_increment : 1;
-    c3quat  q_now, q_down, q_drag, q_increment;
-    c3vec2  down_pt;
-    c3mat4  rot, rot_increment;
-    c3mat4  *rot_ptr;
-
-    c3vec2  center;
-    c3f                radius, damp_factor;
-} c3arcball, *c3arcballp;
-
-void
-c3arcball_init(
-               c3arcballp a );
-void
-c3arcball_init_mat4(
-               c3arcballp a,
-               c3mat4p mtx );
-void
-c3arcball_init_center(
-               c3arcballp a,
-               const c3vec2 center,
-               c3f radius );
-void
-c3arcball_set_params(
-               c3arcballp a,
-               const c3vec2 center,
-               c3f radius);
-c3vec3
-c3arcball_mouse_to_sphere(
-               c3arcballp a,
-               const c3vec2 p);
-c3vec3
-c3arcball_constrain_vector(
-               const c3vec3 vector,
-               const c3vec3 axis);
-void
-c3arcball_mouse_down(
-               c3arcballp a,
-               int x,
-               int y);
-void
-c3arcball_mouse_up(
-               c3arcballp a);
-
-void
-c3arcball_mouse_motion(
-               c3arcballp a,
-               int x,
-               int y,
-               int shift,
-               int ctrl,
-               int alt);
-void
-c3arcball_set_constraints(
-               c3arcballp a,
-               bool _constraint_x,
-               bool _constraint_y);
-void
-c3arcball_idle(
-               c3arcballp a);
-void
-c3arcball_set_damping(
-               c3arcballp a,
-               c3f d);
-
-#endif /* __C3ARCBALL_H___ */
diff --git a/examples/board_reprap/src/c3/c3cairo.c b/examples/board_reprap/src/c3/c3cairo.c
deleted file mode 100644 (file)
index 840822c..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-       c3cairo.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3/c3cairo.h"
-#include "c3/c3driver_geometry.h"
-
-void
-_c3cairo_dispose(
-               c3geometry_p g,
-               const c3driver_geometry_t * d)
-{
-       c3cairo_p c = (c3cairo_p)g;
-
-       if (c->cr)
-               cairo_destroy(c->cr);
-       if (c->surface)
-               cairo_surface_destroy(c->surface);
-       C3_DRIVER_INHERITED(g, d, dispose);
-}
-
-static void
-_c3cairo_project(
-               c3geometry_p g,
-               const struct c3driver_geometry_t *d,
-               c3mat4p m)
-{
-       C3_DRIVER_INHERITED(g, d, project, m);
-}
-
-const c3driver_geometry_t c3cairo_base_driver = {
-       .dispose = _c3cairo_dispose,
-       .project = _c3cairo_project,
-};
-const c3driver_geometry_t c3texture_driver;
-const c3driver_geometry_t c3geometry_driver;
-
-c3cairo_p
-c3cairo_new(
-               struct c3object_t * parent)
-{
-       c3cairo_p res = malloc(sizeof(*res));
-       return c3cairo_init(res, parent);
-}
-
-c3cairo_p
-c3cairo_init(
-               c3cairo_p o,
-               struct c3object_t * parent)
-{
-       memset(o, 0, sizeof(*o));
-       c3texture_init(&o->tex, parent);
-
-       static const c3driver_geometry_t * list[] = {
-                       &c3cairo_base_driver, &c3texture_driver, &c3geometry_driver, NULL,
-       };
-       ((c3geometry_p)o)->driver = list;
-
-       return o;
-}
-
-c3cairo_p
-c3cairo_new_offscreen(
-               struct c3object_t * parent,
-               int w, int h)
-{
-       c3cairo_p o = c3cairo_new(parent);
-
-       o->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
-       o->cr = cairo_create(o->surface);
-
-       c3pixels_init(&o->tex.pixels, w, h, 4,
-                       cairo_image_surface_get_stride(o->surface),
-                       cairo_image_surface_get_data(o->surface));
-
-       return o;
-}
-
-#if 0
-cairo_surface_destroy(_surface);
-else
-cairo_surface_finish(_surface);
-#endif
diff --git a/examples/board_reprap/src/c3/c3cairo.h b/examples/board_reprap/src/c3/c3cairo.h
deleted file mode 100644 (file)
index 75082b3..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-       c3cairo.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3CAIRO_H___
-#define __C3CAIRO_H___
-
-#include "c3/c3texture.h"
-#include "c3/c3pixels.h"
-#include <pango/pangocairo.h>
-
-typedef struct c3cairo_t {
-       c3texture_t     tex;
-       cairo_t *       cr;
-       cairo_surface_t * surface;
-} c3cairo_t, *c3cairo_p;
-
-c3cairo_p
-c3cairo_new(
-               struct c3object_t * parent /* = NULL */);
-
-c3cairo_p
-c3cairo_init(
-               c3cairo_p o,
-               struct c3object_t * parent /* = NULL */);
-
-c3cairo_p
-c3cairo_new_offscreen(
-               struct c3object_t * parent /* = NULL */,
-               int w, int h);
-
-#endif /* __C3CAIRO_H___ */
diff --git a/examples/board_reprap/src/c3/c3camera.c b/examples/board_reprap/src/c3/c3camera.c
deleted file mode 100644 (file)
index 009672b..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
-       c3camera.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-       Copyright (c) 1998 Paul Rademacher
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3/c3camera.h"
-
-
-void
-c3cam_set_distance(
-               c3camp c,
-               const c3f new_distance)
-{
-    if ( new_distance <= 0.0 )  /* Distance has to be positive */
-        return;
-
-    /* We find the current forward vector */
-//    forward = lookat - eye;
-    c->forward = c3vec3_normalize(c3vec3_sub(c->lookat, c->eye));
-
-    /* Set distance */
-    c->distance = new_distance;
-
-    /* Find new eye point */
-    c->eye = c3vec3_sub(c->lookat, c3vec3_mulf(c->forward, c->distance));
-    c3cam_update(c);
-}
-
-void
-c3cam_set_upv(
-               c3camp c,
-               const c3vec3 new_up)
-{
-    c->up = new_up;
-    c3cam_update(c);
-}
-
-void
-c3cam_set_upf(
-               c3camp c,
-               const c3f x,
-               const c3f y,
-               const c3f z)
-{
-       c3cam_set_upv(c, c3vec3f(x,y,z));
-}
-
-void
-c3cam_set_eyev(
-               c3camp c,
-               const c3vec3 new_eye)
-{
-    c->eye = new_eye;
-    c3cam_update(c);
-}
-
-void
-c3cam_set_eyef(
-               c3camp c,
-               const c3f x,
-               const c3f y,
-               const c3f z)
-{
-       c3cam_set_eyev(c, c3vec3f(x,y,z));
-}
-
-void
-c3cam_set_lookatv(
-               c3camp c,
-               const c3vec3 new_lookat)
-{
-    c->lookat = new_lookat;
-    c3cam_update(c);
-}
-
-void
-c3cam_set_lookatf(
-               c3camp c,
-               const c3f x,
-               const c3f y,
-               const c3f z)
-{
-       c3cam_set_lookatv(c, c3vec3f(x,y,z));
-}
-
-
-void
-c3cam_roll(
-               c3camp c,
-               const c3f angle)
-{
-    c3mat4 rot = rotation3D(c->forward, angle );
-    c->up = c3mat4_mulv3(&rot, c->up);
-    c3cam_update(c);
-}
-
-void
-c3cam_eye_yaw(
-               c3camp c,
-               const c3f angle)
-{
-    c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
-    c3mat4 rot    = rotation3D( c->up, angle );
-
-    eye_pt = c3mat4_mulv3(&rot, eye_pt);
-    c->eye    = c3vec3_add(c->lookat, eye_pt);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_eye_yaw_abs(
-               c3camp c,
-               const c3f angle,
-               const c3vec3 axis)
-{
-    c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
-    c3mat4 rot      = rotation3D( axis, angle );
-
-    eye_pt = c3mat4_mulv3(&rot, eye_pt);
-    c->eye    = c3vec3_add(c->lookat, eye_pt);
-
-    c->up = c3mat4_mulv3(&rot, c->up);
-
-    c3cam_update(c);
-}
-
-
-void
-c3cam_eye_pitch(
-               c3camp c,
-               const c3f angle)
-{
-    c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
-    c3mat4 rot    = rotation3D( c->side, angle );
-
-    eye_pt = c3mat4_mulv3(&rot, eye_pt);
-    c->eye    = c3vec3_add(c->lookat, eye_pt);
-
-    c->up = c3mat4_mulv3(&rot, c->up);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_lookat_yaw(
-               c3camp c,
-               const c3f angle)
-{
-    c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
-    c3mat4 rot = rotation3D( c->up, -angle );
-
-    lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
-    c->lookat = c3vec3_add(c->eye, lookat_pt);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_lookat_pitch(
-               c3camp c,
-               const c3f angle)
-{
-    c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
-    c3mat4 rot = rotation3D( c->side, -angle );
-
-    lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
-    c->lookat = c3vec3_add(c->eye, lookat_pt);
-
-    c->up = c3mat4_mulv3(&rot, c->up);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_reset_up_axis(
-               c3camp c,
-               const int axis_num)
-{
-    c3vec3 eye_pt = c3vec3_sub(c->lookat, c->eye); /* eye w/lookat at center */
-    c3f eye_distance = c3vec3_length(eye_pt);
-    c->eye.n[axis_num] = c->lookat.n[axis_num];
-    /* Bring eye to same level as lookat */
-
-    c3vec3 vector = c3vec3_sub(c->eye, c->lookat);
-    vector = c3vec3_normalize(vector);
-    vector = c3vec3_mulf(vector, eye_distance);
-
-    c->eye = c3vec3_add(c->lookat, vector);
-    c->up = c3vec3f( 0.0, 0.0, 0.0 );
-    c->up.n[axis_num] = 1.0;
-
-    c3cam_update(c);
-}
-
-void
-c3cam_reset_up(
-               c3camp c)
-{
-       c3cam_reset_up_axis(c, VY ); /* Resets to the Y axis */
-}
-
-void
-c3cam_movef(
-               c3camp c,
-               const c3f side_move,
-               const c3f up_move,
-               const c3f forw_move)
-{
-    c->eye    = c3vec3_add(c->eye, c3vec3_mulf(c->forward,             forw_move));
-    c->eye    = c3vec3_add(c->eye, c3vec3_mulf(c->side,                        side_move));
-    c->eye    = c3vec3_add(c->eye, c3vec3_mulf(c->up,                  up_move));
-    c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->forward,  forw_move));
-    c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->side,             side_move));
-    c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->up,               up_move));
-    c3cam_update(c);
-}
-
-void
-c3cam_movev(
-               c3camp c,
-               const c3vec3 v) /* A vector version of the above command */
-{
-       c3cam_movef(c, v.n[VX], v.n[VY], v.n[VZ] );
-}
-
-void
-c3cam_move_by_eye(
-               c3camp c,
-               const c3vec3 new_eye)
-{
-    c3vec3 diff = c3vec3_sub(new_eye, c->eye);
-
-    c->lookat = c3vec3_add(c->lookat, diff);
-    c->eye    = c3vec3_add(c->eye, diff);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_move_by_lookat(
-               c3camp c,
-               const c3vec3 new_lookat)
-{
-    c3vec3 diff = c3vec3_sub(new_lookat, c->lookat);
-
-    c->lookat = c3vec3_add(c->lookat, diff);
-    c->eye    = c3vec3_add(c->eye, diff);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_move_abs(
-               c3camp c,
-               const c3vec3 v)
-{
-    c->lookat = c3vec3_add(c->lookat, v);
-    c->eye    = c3vec3_add(c->eye, v);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_rot_about_eye(
-               c3camp c,
-               const c3mat4p rot)
-{
-    c3vec3  view = c3vec3_sub(c->lookat, c->eye);
-
-    view = c3mat4_mulv3(rot, view);
-    c->up   = c3mat4_mulv3(rot, c->up);
-
-    c->lookat = c3vec3_add(c->eye, view);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_rot_about_lookat(
-               c3camp c,
-               const c3mat4p rot)
-{
-    // NOT QUITE RIGHT YET
-
-    c3vec3 view = c3vec3_sub(c->eye, c->lookat);
-
-    view = c3mat4_mulv3(rot, view);
-    c->up   = c3mat4_mulv3(rot, c->up);
-
-    c->eye = c3vec3_add(c->lookat, view);
-
-    c3cam_update(c);
-}
-
-void
-c3cam_update_matrix(
-               c3camp c)
-{
-    c3cam_update(c);
-
-    c->mtx = c3mat4_vec4(
-               c3vec4f(c->side.n[VX],  c->up.n[VX],    c->forward.n[VX],       0.0),
-               c3vec4f(c->side.n[VY],  c->up.n[VY],    c->forward.n[VY],       0.0),
-               c3vec4f(c->side.n[VZ],  c->up.n[VZ],    c->forward.n[VZ],       0.0),
-               c3vec4f(0.0,                    0.0,                    0.0,                            1.0));
-}
-#if 0
-void
-c3cam_load_to_openGL(c3camp c)
-{
-    c3mat4  m;
-
-    make_mtx();
-
-    glMatrixMode( GL_MODELVIEW );
-    glLoadIdentity();
-    glMultMatrixf( (c3f*) &mtx[0][0]);
-    glTranslatef( -eye[VX], -eye[VY], -eye[VZ] );
-}
-
-void
-c3cam_load_to_openGL_noident(c3camp c)
-{
-    c3mat4  m;
-
-    make_mtx();
-
-    glMatrixMode( GL_MODELVIEW );
-    glMultMatrixf( (c3f*) &mtx[0][0]);
-    glTranslatef( -eye[VX], -eye[VY], -eye[VZ] );
-}
-#endif
-
-void
-c3cam_reset(
-               c3camp c)
-{
-    c->up = c3vec3f( 0.0, 1.0, 0.0 );
-    c->eye = c3vec3f(0.0, 0.0, 10.0);
-    c->lookat = c3vec3f(0.0,0.0,0.0);
-
-    c->mtx = identity3D();
-
-    c3cam_update(c);
-}
-
-c3cam
-c3cam_new()
-{
-       c3cam c;
-       c3cam_reset(&c);
-       return c;
-}
-
-void
-c3cam_update(
-               c3camp c)
-{
-       /* get proper side and forward vectors, and distance  */
-       c->forward = c3vec3_minus(c3vec3_sub(c->lookat, c->eye));
-       c->distance = c3vec3_length(c->forward);
-       c->forward = c3vec3_divf(c->forward, c->distance);
-
-       c->side = c3vec3_cross(c->up, c->forward);
-       c->up = c3vec3_cross(c->forward, c->side);
-
-       c->forward = c3vec3_normalize(c->forward);
-       c->up = c3vec3_normalize(c->up);
-       c->side = c3vec3_normalize(c->side);
-}
-
-# if 0
-void
-c3cam_dump(c3camp c, FILE *output) const
-{
-    fprintf( output, "Viewmodel: \n" );
-    eye.print(    output, "  eye"    );
-    lookat.print( output, "  lookat" );
-    up.print(     output, "  up"     );
-    side.print(   output, "  side"   );
-    forward.print(output, "  forward");
-    mtx.print(    output, "  mtx"    );
-}
-#endif
diff --git a/examples/board_reprap/src/c3/c3camera.h b/examples/board_reprap/src/c3/c3camera.h
deleted file mode 100644 (file)
index cc27c14..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- c3camera.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
- Copyright (c) 1998 Paul Rademacher
-
- This file is part of simavr.
-
- simavr 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 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __C3VIEW_H___
-#define __C3VIEW_H___
-
-#include "c3/c3algebra.h"
-
-typedef struct c3cam {
-       c3vec3 eye, lookat;
-       c3vec3 up, side, forward;
-       c3mat4 mtx;
-       c3f distance;
-} c3cam, *c3camp;
-
-/******************************* set_distance() ***********/
-/* This readjusts the distance from the eye to the lookat */
-/* (changing the eye point in the process)                */
-/* The lookat point is unaffected                         */
-void
-c3cam_set_distance(
-               c3camp c,
-               const c3f new_distance);
-
-/******************************* set_up() ***************/
-void
-c3cam_set_upv(
-               c3camp c,
-               const c3vec3 new_up);
-void
-c3cam_set_upf(
-               c3camp c,
-               const c3f x,
-               const c3f y,
-               const c3f z);
-
-/******************************* set_eye() ***************/
-void
-c3cam_set_eyev(
-               c3camp c,
-               const c3vec3 new_eye);
-void
-c3cam_set_eyef(
-               c3camp c,
-               const c3f x,
-               const c3f y,
-               const c3f z);
-
-/******************************* set_lookat() ***************/
-void
-c3cam_set_lookatv(
-               c3camp c,
-               const c3vec3 new_lookat);
-void
-c3cam_set_lookatf(
-               c3camp c,
-               const c3f x,
-               const c3f y,
-               const c3f z);
-
-/******************************* roll() *****************/
-/* Rotates about the forward vector                     */
-/* eye and lookat remain unchanged                      */
-void
-c3cam_roll(
-               c3camp c,
-               const c3f angle);
-
-/******************************* eye_yaw() *********************/
-/* Rotates the eye about the lookat point, using the up vector */
-/* Lookat is unaffected                                        */
-void
-c3cam_eye_yaw(
-               c3camp c,
-               const c3f angle);
-
-/******************************* eye_yaw_abs() ******************/
-/* Rotates the eye about the lookat point, with a specific axis */
-/* Lookat is unaffected                                         */
-void
-c3cam_eye_yaw_abs(
-               c3camp c,
-               const c3f angle,
-               const c3vec3 axis);
-
-/******************************* eye_pitch() ************/
-/* Rotates the eye about the side vector                */
-/* Lookat is unaffected                                 */
-void
-c3cam_eye_pitch(
-               c3camp c,
-               const c3f angle);
-
-/******************************* lookat_yaw()************/
-/* This assumes the up vector is correct.               */
-/* Rotates the lookat about the side vector             */
-/* Eye point is unaffected                              */
-void
-c3cam_lookat_yaw(
-               c3camp c,
-               const c3f angle);
-
-/******************************* lookat_pitch() *********/
-/* Rotates the lookat point about the side vector       */
-/* This assumes the side vector is correct.             */
-/* Eye point is unaffected                              */
-void
-c3cam_lookat_pitch(
-               c3camp c,
-               const c3f angle);
-
-/******************************* reset_up() ******************/
-/* Resets the up vector to a specified axis (0=X, 1=Y, 2=Z)  */
-/* Also sets the eye point level with the lookat point,      */
-/* along the specified axis                                  */
-void
-c3cam_reset_up_axis(
-               c3camp c,
-               const int axis_num);
-void
-c3cam_reset_up(
-               c3camp c);
-
-/******************************* move() ********************/
-/* Moves a specified distance in the forward, side, and up */
-/* directions.  This function does NOT move by world       */
-/* coordinates.  To move by world coords, use the move_abs */
-/* function.                                               */
-void
-c3cam_movef(
-               c3camp c,
-               const c3f side_move,
-               const c3f up_move,
-               const c3f forw_move);
-void
-c3cam_movev(
-               c3camp c,
-               const c3vec3 v); /* A vector version of the above command */
-
-/******************************* move_by_eye() ***********/
-/* Sets the eye point, AND moves the lookat point by the */
-/* same amount as the eye is moved.                      */
-void
-c3cam_move_by_eye(
-               c3camp c,
-               const c3vec3 new_eye);
-
-/******************************* move_by_lookat() *********/
-/* Sets the lookat point, AND moves the eye point by the  */
-/* same amount as the lookat is moved.                    */
-void
-c3cam_move_by_lookat(
-               c3camp c,
-               const c3vec3 new_lookat);
-
-/******************************* move_abs() *****************/
-/* Move the eye and lookat in world coordinates             */
-void
-c3cam_move_abs(
-               c3camp c,
-               const c3vec3 v);
-
-/****************************** rot_about_eye() ************/
-/* Rotates the lookat point about the eye, based on a 4x4  */
-/* (pure) rotation matrix                                  */
-void
-c3cam_rot_about_eye(
-               c3camp c,
-               const c3mat4p rot);
-
-/****************************** rot_about_lookat() ************/
-/* Rotates the lookat point about the lookat, based on a 4x4  */
-/* (pure) rotation matrix                                  */
-void
-c3cam_rot_about_lookat(
-               c3camp c,
-               const c3mat4p rot);
-
-/******************************* make_mtx() *************/
-/* Constructs a 4x4 matrix - used by load_to_openGL()   */
-void
-c3cam_update_matrix(
-               c3camp c);
-
-/******************************* load_to_openGL() ********/
-/* Sets the OpenGL modelview matrix based on the current */
-/* camera coordinates                                    */
-//void c3cam_load_to_openGL();
-
-/******************************* load_to_openGL_noident() ******/
-/* Multiplies the current camera matrix by the existing openGL */
-/* modelview matrix.  This is same as above function, but      */
-/* does not set the OpenGL matrix to identity first            */
-//void c3cam_load_to_openGL_noident();
-
-/******************************* reset() ****************/
-/* Resets the parameters of this class                  */
-void
-c3cam_reset(
-               c3camp c);
-
-/******************************* ViewModel() ************/
-/* Constructor                                          */
-c3cam c3cam_new();
-
-/******************************* update() ****************/
-/* updates the view params.  Call this after making      */
-/* direct changes to the vectors or points of this class */
-void c3cam_update(
-               c3camp c);
-
-/******************************* dump() *******************/
-/* Prints the contents of this class to a file, typically */
-/* stdin or stderr                                        */
-//void c3cam_dump(FILE *output);
-
-#endif /* __C3VIEW_H___ */
diff --git a/examples/board_reprap/src/c3/c3context.c b/examples/board_reprap/src/c3/c3context.c
deleted file mode 100644 (file)
index 0c0f26a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-       c3context.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3/c3context.h"
-#include "c3/c3object.h"
-#include "c3/c3driver_context.h"
-
-c3context_p
-c3context_new(
-               int w,
-               int h)
-{
-       c3context_p res = malloc(sizeof(*res));
-       return c3context_init(res, w, h);
-}
-
-c3context_p
-c3context_init(
-               c3context_p c,
-               int w,
-               int h)
-{
-       memset(c, 0, sizeof(*c));
-       c->size.x = w;
-       c->size.y = h;
-       c->root = c3object_new(NULL);
-       c->root->context = c;
-       return c;
-}
-
-void
-c3context_dispose(
-               c3context_p c)
-{
-       c3object_dispose(c->root);
-       c3geometry_array_free(&c->projected);
-       free(c);
-}
-
-void
-c3context_project(
-               c3context_p c)
-{
-       if (!c->root || !c->root->dirty)
-               return;
-
-       c3mat4 m = identity3D();
-       c3object_project(c->root, &m);
-       c3geometry_array_clear(&c->projected);
-       c3object_get_geometry(c->root, &c->projected);
-}
-
-void
-c3context_draw(
-               c3context_p c)
-{
-       c3context_project(c);
-       for (int gi = 0; gi < c->projected.count; gi++) {
-               c3geometry_p g = c->projected.e[gi];
-               c3geometry_draw(g);
-       }
-}
diff --git a/examples/board_reprap/src/c3/c3context.h b/examples/board_reprap/src/c3/c3context.h
deleted file mode 100644 (file)
index 00af7e6..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-       c3context.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3CONTEXT_H___
-#define __C3CONTEXT_H___
-
-#include "c3/c3algebra.h"
-#include "c3/c3geometry.h"
-
-//! c3context_t is a container for a 'scene' to be drawn
-/*!
- * A c3context_t holds a root object, a list of already cached projected
- * version of the geometry, and a driver that can be customized to draw it.
- *
- * This is a wrapper around a "top level object", the list of projected
- * geometries is kept, purged and resorted if the root object becomes
- * dirty
- * TODO: Add the camera/eye/arcball control there
- */
-typedef struct c3context_t {
-       c3vec2  size;
-       struct c3object_t * root;
-       c3geometry_array_t      projected;
-
-       const struct c3driver_context_t ** driver;
-} c3context_t, *c3context_p;
-
-//! Allocates a new context of size w=width, h=height
-c3context_p
-c3context_new(
-               int w,
-               int h);
-
-//! Initializes a new context 'c' of size w=width, h=height
-c3context_p
-c3context_init(
-               c3context_p c,
-               int w,
-               int h);
-
-//! Disposes the context, and everything underneath
-void
-c3context_dispose(
-               c3context_p c);
-
-//! Reproject geometry for dirty objects
-void
-c3context_project(
-               c3context_p c);
-//! Draws the context
-void
-c3context_draw(
-               c3context_p c);
-
-#endif /* __C3CONTEXT_H___ */
diff --git a/examples/board_reprap/src/c3/c3driver.h b/examples/board_reprap/src/c3/c3driver.h
deleted file mode 100644 (file)
index 901c32d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-       c3driver.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_H___
-#define __C3DRIVER_H___
-
-#define C3_DRIVER_CALL(__o, __callback, __args...) { \
-               if ((__o) && (__o)->driver) \
-                       for (int _di = 0; (__o)->driver[_di]; _di++) \
-                               if ((__o)->driver[_di]->__callback) { \
-                                       (__o)->driver[_di]->__callback(__o, (__o)->driver[_di], ##__args); \
-                                       break; \
-                               } \
-       }
-#define C3_DRIVER(__o, __callback, __args...) \
-               C3_DRIVER_CALL(__o, __callback, ##__args)
-#define C3_DRIVER_INHERITED(__o, __driver, __callback, __args...) { \
-               if ((__o) && (__o)->driver) \
-                       for (int _di = 0; (__o)->driver[_di]; _di++) \
-                               if ((__o)->driver[_di] == __driver && (__o)->driver[_di+1]) { \
-                                       (__o)->driver[_di+1]->__callback(__o, (__o)->driver[_di+1], ##__args); \
-                                       break; \
-                               } \
-       }
-#endif /* __C3DRIVER_H___ */
diff --git a/examples/board_reprap/src/c3/c3driver_context.h b/examples/board_reprap/src/c3/c3driver_context.h
deleted file mode 100644 (file)
index 0f780d4..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-       c3driver_context.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_CONTEXT_H___
-#define __C3DRIVER_CONTEXT_H___
-
-#include "c3/c3driver.h"
-
-struct c3context_t;
-struct c3driver_context_t;
-struct c3geometry_t;
-
-typedef struct c3driver_context_t {
-       void (*geometry_project)(
-                       struct c3context_t * c,
-                       const struct c3driver_context_t *d,
-                       struct c3geometry_t * g,
-                       union c3mat4 * mat);
-       void (*geometry_draw)(
-                       struct c3context_t * c,
-                       const struct c3driver_context_t *d,
-                       struct c3geometry_t * g);
-} c3driver_context_t, *c3driver_context_p;
-
-#endif /* __C3DRIVER_CONTEXT_H___ */
diff --git a/examples/board_reprap/src/c3/c3driver_geometry.h b/examples/board_reprap/src/c3/c3driver_geometry.h
deleted file mode 100644 (file)
index 46bd101..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-       c3driver_geometry.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_GEOMETRY_H___
-#define __C3DRIVER_GEOMETRY_H___
-
-#include "c3/c3driver.h"
-
-struct c3geometry_t;
-
-typedef struct c3driver_geometry_t {
-       void (*dispose)(
-                       struct c3geometry_t * geometry,
-                       const struct c3driver_geometry_t *d);
-       void (*project)(
-                       struct c3geometry_t * geometry,
-                       const struct c3driver_geometry_t *d,
-                       union c3mat4 * mat);
-       void (*draw)(
-                       struct c3geometry_t * geometry,
-                       const struct c3driver_geometry_t *d);
-} c3driver_geometry_t, *c3driver_geometry_p;
-
-
-#endif /* __C3DRIVER_GEOMETRY_H___ */
diff --git a/examples/board_reprap/src/c3/c3driver_object.h b/examples/board_reprap/src/c3/c3driver_object.h
deleted file mode 100644 (file)
index 05a11f2..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-       c3driver_object.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_OBJECT_H___
-#define __C3DRIVER_OBJECT_H___
-
-#include "c3/c3driver.h"
-
-struct c3object_t;
-struct c3geometry_array_t;
-union c3mat4;
-
-typedef struct c3driver_object_t {
-       /*
-        * Delete any object related to this object, geometry etc
-        * The object will still exist, just empty
-        */
-       void (*clear)(
-                       struct c3object_t * object,
-                       const struct c3driver_object_t * d);
-       /*
-        * Dispose of the remaining memory for an object, detaches it
-        * and frees remaining traces of it
-        */
-       void (*dispose)(
-                       struct c3object_t * object,
-                       const struct c3driver_object_t * d);
-       /*
-        * Adds sub objects geometry and self geometry to array 'out'
-        */
-       void (*get_geometry)(
-                       struct c3object_t * object,
-                       const struct c3driver_object_t * d,
-                       struct c3geometry_array_t * out);
-       /*
-        * Reproject geometry along matrix 'mat', applies our own
-        * transform and call down the chain for sub-objects
-        */
-       void (*project)(
-                       struct c3object_t * object,
-                       const struct c3driver_object_t * d,
-                       union c3mat4 * mat);
-} c3driver_object_t, *c3driver_object_p;
-
-
-#endif /* __C3DRIVER_OBJECT_H___ */
diff --git a/examples/board_reprap/src/c3/c3geometry.c b/examples/board_reprap/src/c3/c3geometry.c
deleted file mode 100644 (file)
index e041ff2..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-       c3geometry.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3/c3object.h"
-#include "c3/c3context.h"
-#include "c3/c3driver_geometry.h"
-#include "c3/c3driver_context.h"
-
-static void
-_c3geometry_dispose(
-               c3geometry_p  g,
-               const struct c3driver_geometry_t *d)
-{
-       /*
-        * If we're still attached to an object, detach
-        */
-       if (g->object) {
-               for (int oi = 0; oi < g->object->geometry.count; oi++)
-                       if (g->object->geometry.e[oi] == g) {
-                               c3geometry_array_delete(&g->object->geometry, oi, 1);
-                               c3object_set_dirty(g->object, true);
-                               break;
-                       }
-               g->object = NULL;
-       }
-       str_free(g->name);
-       c3vertex_array_free(&g->vertice);
-       c3vertex_array_free(&g->projected);
-       c3tex_array_free(&g->textures);
-       c3colorf_array_free(&g->colorf);
-       free(g);
-//     C3_DRIVER_INHERITED(g, d, dispose);
-}
-
-static void
-_c3geometry_project(
-               c3geometry_p g,
-               const struct c3driver_geometry_t *d,
-               c3mat4p m)
-{
-       if (g->vertice.count) {
-               c3vertex_array_realloc(&g->projected, g->vertice.count);
-               g->projected.count = g->vertice.count;
-               for (int vi = 0; vi < g->vertice.count; vi++) {
-                       g->projected.e[vi] = c3mat4_mulv3(m, g->vertice.e[vi]);
-                       if (vi == 0)
-                               g->bbox.min = g->bbox.max = g->projected.e[vi];
-                       else {
-                               g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
-                               g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
-                       }
-               }
-       }
-
-       if (g->object && g->object->context)
-               C3_DRIVER(g->object->context, geometry_project, g, m);
-       g->dirty = 0;
-//     C3_DRIVER_INHERITED(g, d, project);
-}
-
-static void
-_c3geometry_draw(
-               c3geometry_p g,
-               const struct c3driver_geometry_t *d)
-{
-       if (g->object && g->object->context)
-               C3_DRIVER(g->object->context, geometry_draw, g);
-//     C3_DRIVER_INHERITED(g, d, draw);
-}
-
-const  c3driver_geometry_t c3geometry_driver = {
-       .dispose = _c3geometry_dispose,
-       .project = _c3geometry_project,
-       .draw = _c3geometry_draw,
-};
-
-c3geometry_p
-c3geometry_new(
-               c3geometry_type_t type,
-               c3object_p o /* = NULL */)
-{
-       c3geometry_p res = malloc(sizeof(c3geometry_t));
-       return c3geometry_init(res, type, o);
-}
-
-c3geometry_p
-c3geometry_init(
-               c3geometry_p g,
-               c3geometry_type_t type,
-               struct c3object_t * o /* = NULL */)
-{
-       memset(g, 0, sizeof(*g));
-       static const c3driver_geometry_t * list[] = {
-                       &c3geometry_driver, NULL,
-       };
-       g->driver = list;
-       g->type = type;
-       g->dirty = 1;
-       if (o)
-               c3object_add_geometry(o, g);
-       return g;
-}
-
-c3driver_geometry_p
-c3geometry_get_custom(
-               c3geometry_p g )
-{
-       if (g->custom)
-               return (c3driver_geometry_p)g->driver[0];
-       int cnt = 0;
-       for (int di = 0; g->driver[di]; di++)
-               cnt++;
-       c3driver_geometry_p * newd = malloc(sizeof(c3driver_geometry_p) * (cnt + 2));
-       memcpy(&newd[1], g->driver, (cnt + 1) * sizeof(c3driver_geometry_p));
-       newd[0] = malloc(sizeof(c3driver_geometry_t));
-       memset(newd[0], 0, sizeof(c3driver_geometry_t));
-       g->custom = 1;
-       g->driver = (typeof(g->driver))newd;
-       return newd[0];
-}
-
-void
-c3geometry_dispose(
-               c3geometry_p g)
-{
-       C3_DRIVER(g, dispose);
-}
-
-void
-c3geometry_project(
-               c3geometry_p g,
-               c3mat4p m)
-{
-       if (!g->dirty)
-               return;
-       C3_DRIVER(g, project, m);
-}
-
-void
-c3geometry_draw(
-               c3geometry_p g )
-{
-       C3_DRIVER(g, draw);
-}
diff --git a/examples/board_reprap/src/c3/c3geometry.h b/examples/board_reprap/src/c3/c3geometry.h
deleted file mode 100644 (file)
index 2364fb3..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-       c3geometry.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * c3geometry is a structure containing one set of vertices and various
- * bits related to it. Ultimately it contains a pre-cached projected
- * version of the vertices that the drawing code can use directly.
- * c3geometry is aways attached to a c3object as a parent.
- */
-
-#ifndef __C3GEOMETRY_H___
-#define __C3GEOMETRY_H___
-
-#include "c3/c3algebra.h"
-#include "c_utils.h"
-
-typedef c3vec3 c3vertex;
-typedef c3vec4 c3colorf;
-typedef c3vec2 c3tex;
-
-struct c3object_t;
-
-DECLARE_C_ARRAY(c3vertex, c3vertex_array, 16);
-DECLARE_C_ARRAY(c3tex, c3tex_array, 16);
-DECLARE_C_ARRAY(c3colorf, c3colorf_array, 16);
-
-//! Geometry material. TODO: Beef up. Add vertex/fragment programs..
-typedef struct c3material_t {
-       c3colorf        color;
-       uint32_t        texture;
-       uint32_t        mode;
-} c3material_t;
-
-//! Bounding box. TODO: Move to a separate file?
-typedef struct c3bbox_t {
-       c3vec3  min, max;
-} c3bbox_t;
-
-//! Generic geometry type
-enum {
-       C3_RAW_TYPE = 0,
-       C3_LINES_TYPE,
-       C3_TRIANGLE_TYPE,
-       C3_TEXTURE_TYPE,
-};
-
-/*!
- * geometry type.
- * The type is used as non-opengl description of what the geometry
- * contains, like "texture", and the subtype can be used to store the
- * real format of the vertices. like GL_LINES etc
- */
-typedef union {
-       struct  { uint32_t type : 16, subtype : 16; };
-       uint32_t value;
-} c3geometry_type_t;
-
-/*!
- * Geometry object. Describes a set of vertices, texture coordinates,
- * normals, colors and material
- * The projection is not set here, a geometry is always attached to a
- * c3object that has the projection
- */
-typedef struct c3geometry_t {
-       c3geometry_type_t       type;   // C3_TRIANGLE_TYPE, GL_LINES etc
-       int                                     dirty : 1,
-                                               texture : 1,    // has a valid material.texture
-                                               custom : 1;             // has a custom driver
-       str_p                           name;   // optional
-       c3material_t            mat;
-       struct c3object_t * object;
-       const struct c3driver_geometry_t ** driver;
-
-       c3vertex_array_t        vertice;
-       c3tex_array_t           textures;
-       c3colorf_array_t        colorf;
-       c3vertex_array_t        normals;
-
-       // projected version of the vertice
-       c3vertex_array_t        projected;
-       c3bbox_t                        bbox;
-} c3geometry_t, *c3geometry_p;
-
-DECLARE_C_ARRAY(c3geometry_p, c3geometry_array, 4);
-
-//! Allocates a new geometry, init it, and attached it to parent 'o' (optional)
-c3geometry_p
-c3geometry_new(
-               c3geometry_type_t type,
-               struct c3object_t * o /* = NULL */);
-//! Init an existing new geometry, and attached it to parent 'o' (optional)
-c3geometry_p
-c3geometry_init(
-               c3geometry_p g,
-               c3geometry_type_t type,
-               struct c3object_t * o /* = NULL */);
-//! Disposes (via the driver interface) the geometry
-void
-c3geometry_dispose(
-               c3geometry_p g);
-
-//! Prepares a geometry. 
-/*!
- * The project phase is called only when the container object is 'dirty'
- * for example if it's projection has changed.
- * The project call is responsible for reprojecting the geometry and that
- * sort of things
- */
-void
-c3geometry_project(
-               c3geometry_p g,
-               c3mat4p m);
-
-//! Draw the geometry
-/*
- * Called when drawing the context. Typicaly this calls the geometry 
- * driver, which in turn will call the 'context' draw method, and the 
- * application to draw this particular geometry
- */
-void
-c3geometry_draw(
-               c3geometry_p g );
-
-
-//! allocate (if not there) and return a custom driver for this geometry
-/*!
- * Geometries come with a default, read only driver stack.. It is a constant
- * global to save memory for each of the 'generic' object.
- * This call will duplicate that stack and allocate (if not there) a read/write
- * empty driver that the application can use to put their own, per object,
- * callback. For example you can add your own project() or draw() function
- * and have it called first
- */
-struct c3driver_geometry_t *
-c3geometry_get_custom(
-               c3geometry_p g );
-
-IMPLEMENT_C_ARRAY(c3geometry_array);
-IMPLEMENT_C_ARRAY(c3vertex_array);
-IMPLEMENT_C_ARRAY(c3tex_array);
-IMPLEMENT_C_ARRAY(c3colorf_array);
-
-static inline c3geometry_type_t
-c3geometry_type(int type, int subtype)
-{
-       c3geometry_type_t r = { .type = type, .subtype = subtype };
-       return r;
-}
-
-#endif /* __C3GEOMETRY_H___ */
diff --git a/examples/board_reprap/src/c3/c3object.c b/examples/board_reprap/src/c3/c3object.c
deleted file mode 100644 (file)
index 50d46e4..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
-       c3object.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3/c3object.h"
-#include "c3/c3driver_object.h"
-
-void
-_c3object_clear(
-               c3object_p o,
-               const c3driver_object_t * d)
-{
-       for (int oi = 0; oi < o->transform.count; oi++) {
-               o->transform.e[oi]->object = NULL;
-               c3transform_dispose(o->transform.e[oi]);
-       }
-       for (int oi = 0; oi < o->geometry.count; oi++) {
-               o->geometry.e[oi]->object = NULL;       // don't try to detach
-               c3geometry_dispose(o->geometry.e[oi]);
-       }
-       for (int oi = 0; oi < o->objects.count; oi++) {
-               o->objects.e[oi]->parent = NULL;        // don't try to detach
-               c3object_dispose(o->objects.e[oi]);
-       }
-       c3object_array_free(&o->objects);
-       c3geometry_array_free(&o->geometry);
-       c3transform_array_free(&o->transform);
-}
-
-void
-_c3object_dispose(
-               c3object_p o,
-               const c3driver_object_t * d)
-{
-       if (o->parent) {
-               for (int oi = 0; oi < o->parent->objects.count; oi++)
-                       if (o->parent->objects.e[oi] == o) {
-                               c3object_array_delete(&o->parent->objects, oi, 1);
-                               c3object_set_dirty(o->parent, true);
-                               break;
-                       }
-               o->parent = NULL;
-       }
-       //C3O_DRIVER_INHERITED(dispose, d);
-       free(o);
-}
-
-void
-_c3object_get_geometry(
-               c3object_p o,
-               const c3driver_object_t * d,
-               c3geometry_array_p out)
-{
-       for (int oi = 0; oi < o->geometry.count; oi++)
-               c3geometry_array_add(out, o->geometry.e[oi]);
-       for (int oi = 0; oi < o->objects.count; oi++)
-               c3object_get_geometry(o->objects.e[oi], out);
-}
-
-void
-_c3object_project(
-               c3object_p o,
-               const c3driver_object_t * d,
-               c3mat4p m)
-{
-       if (!o->dirty)
-               return;
-
-//     c3mat4 identity = identity3D();
-       c3mat4 p = *m;
-       for (int pi = 0; pi < o->transform.count; pi++)
-               p = c3mat4_mul(&p, &o->transform.e[pi]->matrix);
-//     bool is_identity = c3mat4_equal(m, &identity);
-
-       for (int gi = 0; gi < o->geometry.count; gi++) {
-               c3geometry_p g = o->geometry.e[gi];
-               c3vertex_array_clear(&g->projected);
-
-               g->bbox.min = g->bbox.max = c3vec3f(0,0,0);
-               c3geometry_project(g, &p);
-       }
-       for (int oi = 0; oi < o->objects.count; oi++)
-               c3object_project(o->objects.e[oi], &p);
-       o->dirty = false;
-}
-
-const c3driver_object_t c3object_driver = {
-       .clear = _c3object_clear,
-       .dispose = _c3object_dispose,
-       .get_geometry = _c3object_get_geometry,
-       .project = _c3object_project,
-};
-
-
-c3object_p
-c3object_init(
-               c3object_p o /* = NULL */,
-               c3object_p parent)
-{
-       memset(o, 0, sizeof(*o));
-       o->parent = parent;
-       static const c3driver_object_t * list[] =
-                       { &c3object_driver, NULL };
-       o->driver = list;
-       if (parent) {
-               c3object_array_add(&parent->objects, o);
-               o->context = parent->context;
-       }
-       return o;
-}
-
-c3object_p
-c3object_new(
-               c3object_p o /* = NULL */)
-{
-       c3object_p res = malloc(sizeof(*o));
-       return c3object_init(res, o);
-}
-
-void
-c3object_clear(
-               c3object_p o)
-{
-       C3_DRIVER(o, clear);
-}
-
-void
-c3object_dispose(
-               c3object_p o)
-{
-       c3object_clear(o);
-       C3_DRIVER(o, dispose);
-}
-
-void
-c3object_set_dirty(
-               c3object_p o,
-               bool dirty)
-{
-       if (dirty) {
-               while (o) {
-                       o->dirty = true;
-                       o = o->parent;
-               }
-       } else {
-               for (int oi = 0; oi < o->objects.count; oi++)
-                       if (o->objects.e[oi]->dirty)
-                               c3object_set_dirty(o->objects.e[oi], false);
-               o->dirty = false;
-       }
-}
-
-void
-c3object_add_object(
-               c3object_p o,
-               c3object_p sub)
-{
-       if (sub->parent == o)
-               return;
-       if (sub->parent) {
-               for (int oi = 0; oi < sub->parent->objects.count; oi++) {
-                       if (sub->parent->objects.e[oi] == sub) {
-                               c3object_array_delete(&sub->parent->objects, oi, 1);
-                               c3object_set_dirty(sub->parent, true);
-                               break;
-                       }
-               }
-               sub->parent = NULL;
-       }
-       sub->parent = o;
-       if (o) {
-               c3object_array_add(&o->objects, sub);
-               c3object_set_dirty(o, true);
-       }
-}
-
-void
-c3object_add_geometry(
-               c3object_p o,
-               c3geometry_p g)
-{
-       if (g->object == o)
-               return;
-       if (g->object) {
-               for (int oi = 0; oi < g->object->geometry.count; oi++) {
-                       if (g->object->geometry.e[oi] == g) {
-                               c3geometry_array_delete(&g->object->geometry, oi, 1);
-                               c3object_set_dirty(g->object, true);
-                               break;
-                       }
-               }
-               g->object = NULL;
-       }
-       g->object = o;
-       if (o) {
-               c3geometry_array_add(&o->geometry, g);
-               c3object_set_dirty(o, true);
-       }
-}
-
-void
-c3object_get_geometry(
-               c3object_p o,
-               c3geometry_array_p array )
-{
-       C3_DRIVER(o, get_geometry, array);
-}
-
-void
-c3object_project(
-               c3object_p o,
-               const c3mat4p m)
-{
-       C3_DRIVER(o, project, m);
-}
diff --git a/examples/board_reprap/src/c3/c3object.h b/examples/board_reprap/src/c3/c3object.h
deleted file mode 100644 (file)
index 1ee1d9c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-       c3object.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3OBJECT_H___
-#define __C3OBJECT_H___
-
-#include <stdbool.h>
-#include "c3/c3transform.h"
-#include "c3/c3geometry.h"
-
-struct c3object_t;
-
-DECLARE_C_ARRAY(struct c3object_t*, c3object_array, 4);
-
-//! c3object is a container for child object, and geometry
-/*!
- * a c3object is a node in a c3object tree, it contains sub-objects and/or
- * geometry. It also contains it's own list of transform matrices, so can
- * be seen as a "anchor" that can be moved around and where you can
- * attach other objects or geometry.
- *
- * An object has a notion of 'dirty bit' -- something that signals that
- * something has changed and deserved reprojection. the dirty bit
- * is propagated upward when 1 (up to the root object) and downward when 0
- * (to allow clearing the bit on a subtree)
- */
-typedef struct c3object_t {
-       str_p                           name;   //! optional name
-       int                                     dirty : 1, 
-                                               visible : 1 /* TODO: Implement visible */;
-       struct c3context_t * context; //! context this object is attached to
-       struct c3object_t * parent;             //! Parent object
-       const struct c3driver_object_t ** driver;       //! Driver stack
-       c3transform_array_t     transform;
-       c3object_array_t        objects;        //! child object list
-       c3geometry_array_t      geometry;       //! Object geometri(es)
-} c3object_t, *c3object_p;
-
-//! Allocates and initialize an emty object, attaches it to parent 'o'
-c3object_p
-c3object_new(
-               c3object_p o /* = NULL */);
-//! Disposes of everything under this object
-void
-c3object_dispose(
-               c3object_p o);
-//! Clears every sub-object, geometry, and transform, but do not dispose of o
-void
-c3object_clear(
-               c3object_p o);
-//! Initializes 'o' as a new object, attaches it to parent (optional)
-c3object_p
-c3object_init(
-               c3object_p o,
-               c3object_p parent /* = NULL */);
-//! sets the dirty bit for 'o' and related tree
-/*!
- * When dirty is 1, sets the dirty bit of this object and all the parent
- * objects up to the root object.
- * When dirty is 0, clear the dirty bit of this object, and all the
- * sub objects.
- */
-void
-c3object_set_dirty(
-               c3object_p o,
-               bool dirty);
-//! Adds a new geometry g to object o
-void
-c3object_add_geometry(
-               c3object_p o,
-               c3geometry_p g);
-//! Adds a new sub-object sub to object o
-void
-c3object_add_object(
-               c3object_p o,
-               c3object_p sub);
-//! Adds a new transform matrix, initialized as identity
-c3transform_p
-c3object_add_transform(
-               c3object_p o );
-//! Iterates all the sub-objects and collects all the geometries
-/*!
- * This call iterates the sub-objects and collects all their 'projected'
- * geometry, and add them to the array
- */
-void
-c3object_get_geometry(
-               c3object_p o,
-               c3geometry_array_p array );
-//! Project object 'o' using it's own transformations, relative to matrix 'm'
-/*!
- * Multiply this objects transformation(s) to matrix 'm' and calls
- * reprojects the geometries using that matrix as an anchor. also call
- * recursively to sub-objects to follow the projection down.
- */
-void
-c3object_project(
-               c3object_p o,
-               const c3mat4p m);
-
-IMPLEMENT_C_ARRAY(c3object_array);
-
-#endif /* __C3OBJECT_H___ */
diff --git a/examples/board_reprap/src/c3/c3pixels.c b/examples/board_reprap/src/c3/c3pixels.c
deleted file mode 100644 (file)
index cdaef7e..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-       c3pixels.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "c3pixels.h"
-
-c3pixels_p
-c3pixels_new(
-               uint32_t w,
-               uint32_t h,
-               int      psize /* in bytes */,
-               size_t row,
-               void * base)
-{
-       c3pixels_p p = malloc(sizeof(*p));
-       c3pixels_init(p, w, h, psize, row, base);
-       p->alloc = 1;
-       return p;
-}
-
-c3pixels_p
-c3pixels_init(
-               c3pixels_p p,
-               uint32_t w,
-               uint32_t h,
-               int      psize /* in bytes */,
-               size_t row,
-               void * base)
-{
-       memset (p, 0, sizeof(*p));
-       p->w = w;
-       p->h = h;
-       p->row = row;
-       p->psize = psize;
-       p->base = base;
-       c3pixels_alloc(p);
-       return p;
-}
-
-void
-c3pixels_dispose(
-               c3pixels_p p )
-{
-       if (p->own && p->base)
-               free(p->base);
-       if (p->alloc)
-               free(p);
-       else
-               memset(p, 0, sizeof(*p));
-}
-
-void
-c3pixels_alloc(
-               c3pixels_p p )
-{
-       if (p->base)
-               return;
-       p->base = malloc(p->row * p->h);
-       p->own = p->base != NULL;
-}
-
-void
-c3pixels_purge(
-               c3pixels_p p )
-{
-       if (!p->base)
-               return;
-       if (p->own)
-               free(p->base);
-       p->own = 0;
-       p->base = NULL;
-}
-
-void
-c3pixels_zero(
-               c3pixels_p p)
-{
-       if (!p->base)
-               return;
-       memset(p->base, 0, p->h * p->row);
-}
diff --git a/examples/board_reprap/src/c3/c3pixels.h b/examples/board_reprap/src/c3/c3pixels.h
deleted file mode 100644 (file)
index 8e7d1d2..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-       c3pixels.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3PIXELS_H___
-#define __C3PIXELS_H___
-
-#include <stdint.h>
-
-//! for format hint
-enum {
-       C3PIXEL_ARGB = 0,
-       C3PIXEL_RGB,
-       C3PIXEL_A
-};
-
-typedef struct c3pixels_t {
-       uint32_t w, h;  // width & height in pixels
-       size_t row;             // size of one row in bytes
-       void * base;    // base address
-
-       union {
-               struct {
-                       uint32_t        own : 1,        // is the base our own to delete
-                               alloc : 1,                      // is the c3pixels_p our own to delete
-                               dirty : 1,                      // pixels have been changed
-                               psize : 4,                      // pixel size in byte
-                               format : 8;                     // not used internally
-               };
-               uint32_t flags;
-       };
-       int             refCount;       // TODO: Implement reference counting ?
-} c3pixels_t, *c3pixels_p;
-
-//! Allocates a new c3pixels, also allocates the pixels if row == NULL
-c3pixels_p
-c3pixels_new(
-               uint32_t w,
-               uint32_t h,
-               int      psize /* in bytes */,
-               size_t row,
-               void * base);
-
-//! Initializes p, also allocates the pixels if row == NULL
-c3pixels_p
-c3pixels_init(
-               c3pixels_p p,
-               uint32_t w,
-               uint32_t h,
-               int      psize /* in bytes */,
-               size_t row,
-               void * base);
-
-//! Dispose of the pixels, and potentially p if it was allocated with c3pixels_new
-void
-c3pixels_dispose(
-               c3pixels_p p );
-
-//! Disposes of the pixels, only
-void
-c3pixels_purge(
-               c3pixels_p p );
-
-//! (Re)allocate pixels if pixels had been purged
-void
-c3pixels_alloc(
-               c3pixels_p p );
-
-//! Get a pixel address
-static inline void *
-c3pixels_get(
-               c3pixels_p p,
-               int x, int y)
-{
-       return ((uint8_t*)p->base) + (y * p->row) + (x * p->psize);
-}
-
-//! Zeroes the pixels
-void
-c3pixels_zero(
-               c3pixels_p p);
-
-#endif /* __C3PIXELS_H___ */
diff --git a/examples/board_reprap/src/c3/c3quaternion.c b/examples/board_reprap/src/c3/c3quaternion.c
deleted file mode 100644 (file)
index a0816bf..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-       c3quaternion.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include "c3/c3quaternion.h"
-
-#ifndef DEG2RAD
-#define DEG2RAD(x) ((x)/180.0*M_PI)
-#define RAD2DEG(x) ((x)/M_PI*180.0)
-#endif
-#ifndef FUDGE
-#define FUDGE .00001
-#endif
-
-c3quat
-c3quat_new()
-{
-    return c3quat_identity();
-}
-
-/************************************************* c3quat_identity() *****/
-/* Returns quaternion identity element                                 */
-
-c3quat
-c3quat_identity()
-{
-    return c3quat_vec3( c3vec3f( 0.0, 0.0, 0.0 ), 1.0 );
-}
-
-c3quat
-c3quatf(
-               const c3f x,
-               const c3f y,
-               const c3f z,
-               const c3f w)
-{
-       c3quat q = { .v = c3vec3f(x,y,z), .s = w };
-       return q;
-}
-
-c3quat
-c3quat_vec3(
-               const c3vec3 v,
-               const c3f s)
-{
-       c3quat q = { .v = v, .s = s };
-    return q;
-}
-
-c3quat
-c3quat_vec4(
-               const c3vec4 v)
-{
-       c3quat q = { .v = c3vec3f(v.n[0], v.n[1], v.n[2]), .s = v.n[3] };
-    return q;
-}
-
-c3quat
-c3quat_double(
-               const double *d)
-{
-       c3quat q;
-    q.v.n[0] = (c3f) d[0];
-    q.v.n[1] = (c3f) d[1];
-    q.v.n[2] = (c3f) d[2];
-    q.s         = (c3f) d[3];
-    return q;
-}
-
-
-c3quat
-c3quat_add(
-               const c3quat a,
-               const c3quat b)
-{
-    return c3quat_vec3(c3vec3_add(a.v, b.v), a.s + b.s );
-}
-
-c3quat
-c3quat_sub(
-               const c3quat a,
-               const c3quat b)
-{
-    return c3quat_vec3(c3vec3_sub(a.v, b.v), a.s - b.s );
-}
-
-c3quat
-c3quat_minus(
-               const c3quat a )
-{
-    return c3quat_vec3(c3vec3_minus(a.v), -a.s);
-}
-
-c3quat
-c3quat_mul(
-               const c3quat a,
-               const c3quat b)
-{
-//    return c3quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + a.v^b.v );
-    return c3quat_vec3(
-               c3vec3_add(c3vec3_mulf(b.v, a.s), c3vec3_add(c3vec3_mulf(a.v, b.s), c3vec3_cross(a.v, b.v))),
-               (a.s * b.s) - c3vec3_dot(a.v, b.v));
-}
-
-c3quat
-c3quat_mulf( const c3quat a, const c3f t)
-{
-    return c3quat_vec3(c3vec3_mulf(a.v, t), a.s * t );
-}
-
-c3mat4
-c3quat_to_mat4(
-               const c3quat a )
-{
-    c3f xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
-
-    c3f t  = 2.0f / (c3vec3_dot(a.v, a.v) + (a.s * a.s));
-
-    xs = a.v.n[VX]*t;   ys = a.v.n[VY]*t;   zs = a.v.n[VZ]*t;
-    wx = a.s*xs;               wy = a.s*ys;            wz = a.s*zs;
-    xx = a.v.n[VX]*xs;  xy = a.v.n[VX]*ys;  xz = a.v.n[VX]*zs;
-    yy = a.v.n[VY]*ys;  yz = a.v.n[VY]*zs;  zz = a.v.n[VZ]*zs;
-
-    c3mat4 m = c3mat4_vec4(
-           c3vec4f(1.0f-(yy+zz), xy+wz,        xz-wy,        0.0f),
-           c3vec4f(xy-wz,        1.0f-(xx+zz), yz+wx,        0.0f),
-           c3vec4f(xz+wy,        yz-wx,        1.0f-(xx+yy), 0.0f),
-           c3vec4f(0.0f,         0.0f,         0.0f,         1.0f ));
-
-    return m;
-}
-
-
-/************************************************ quat_slerp() ********/
-/* Quaternion spherical interpolation                                 */
-
-c3quat
-quat_slerp(
-               const c3quat from,
-               const c3quat to,
-               c3f t)
-{
-    c3quat to1;
-    c3f omega, cosom, sinom, scale0, scale1;
-
-    /* calculate cosine */
-    cosom = c3vec3_dot(from.v, to.v) + from.s + to.s;
-
-       /* Adjust signs (if necessary) */
-       if (cosom < 0.0) {
-               cosom = -cosom;
-               to1 = c3quat_minus(to);
-       } else {
-               to1 = to;
-       }
-
-    /* Calculate coefficients */
-    if ((1.0 - cosom) > FUDGE ) {
-        /* standard case (slerp) */
-        omega =  (c3f) acos( cosom );
-        sinom =  (c3f) sin( omega );
-        scale0 = (c3f) sin((1.0 - t) * omega) / sinom;
-        scale1 = (c3f) sin(t * omega) / sinom;
-    } else {
-        /* 'from' and 'to' are very close - just do linear interpolation */
-        scale0 = 1.0f - t;
-        scale1 = t;
-    }
-
-    return c3quat_add(c3quat_mulf(from, scale0), c3quat_mulf(to1, scale1));
-}
-
-/********************************************** set_angle() ************/
-/* set rot angle (degrees)                                             */
-
-c3quatp
-c3quat_set_angle(
-               c3quatp a,
-               c3f f)
-{
-    c3vec3 axis = c3quat_get_axis(a);
-
-    a->s = (c3f) cos( DEG2RAD( f ) / 2.0 );
-
-    a->v = c3vec3_mulf(axis, (c3f) sin(DEG2RAD(f) / 2.0));
-    return a;
-}
-
-/********************************************** scale_angle() ************/
-/* scale rot angle (degrees)                                             */
-
-c3quatp
-c3quat_scale_angle(
-               c3quatp a,
-               c3f f)
-{
-       return c3quat_set_angle(a, f * c3quat_get_angle(a) );
-}
-
-/********************************************** get_angle() ************/
-/* get rot angle (degrees).  Assumes s is between -1 and 1             */
-
-c3f
-c3quat_get_angle(
-               const c3quatp a)
-{
-    return (c3f) RAD2DEG( 2.0 * acos( a->s ) );
-}
-
-/********************************************* get_axis() **************/
-
-c3vec3
-c3quat_get_axis(
-               c3quatp a)
-{
-    c3f scale = (c3f) sin( acos( a->s ) );
-
-    if ( scale < FUDGE && scale > -FUDGE )
-        return c3vec3f( 0.0, 0.0, 0.0 );
-    else
-        return  c3vec3_divf(a->v, scale);
-}
-
-/******************************************* c3quat_print() ************/
-#if 0
-void c3quat_print(FILE *dest, const char *name) const
-{
-    fprintf( dest, "%s:   v:<%3.2f %3.2f %3.2f>  s:%3.2f\n",
-        name, v[0], v[1], v[2], s );
-}
-#endif
diff --git a/examples/board_reprap/src/c3/c3quaternion.h b/examples/board_reprap/src/c3/c3quaternion.h
deleted file mode 100644 (file)
index 6e3f042..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-       c3quaternion.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3QUATERNION_H___
-#define __C3QUATERNION_H___
-
-#include <stdbool.h>
-#include "c3/c3algebra.h"
-
-typedef struct c3quat {
-  c3vec3  v;   /* vector component */
-  c3f s;               /* scalar component */
-} c3quat, *c3quatp;
-
-c3quat
-c3quat_new();
-c3quat
-c3quat_identity();
-
-c3quat
-c3quatf(
-               const c3f x,
-               const c3f y,
-               const c3f z,
-               const c3f w);
-c3quat
-c3quat_vec3(
-               const c3vec3 v,
-               const c3f s);
-c3quat
-c3quat_vec4(
-               const c3vec4 v);
-
-c3quat
-c3quat_double(
-               const double *d);
-
-c3quat
-c3quat_add(
-               const c3quat a,
-               const c3quat b);
-c3quat
-c3quat_sub(
-               const c3quat a,
-               const c3quat b);
-c3quat
-c3quat_minus(
-               const c3quat a );
-
-c3quat
-c3quat_mul(
-               const c3quat a,
-               const c3quat b);
-
-c3mat4
-c3quat_to_mat4(
-               const c3quat a );
-
-c3quatp
-c3quat_set_angle(
-               c3quatp a,
-               c3f f);
-c3quatp
-c3quat_scale_angle(
-               c3quatp a,
-               c3f f);
-c3f
-c3quat_get_angle(
-               const c3quatp a);
-c3vec3
-c3quat_get_axis(
-               c3quatp a);
-
-#endif /* __C3QUATERNION_H___ */
diff --git a/examples/board_reprap/src/c3/c3stl.c b/examples/board_reprap/src/c3/c3stl.c
deleted file mode 100644 (file)
index 248094e..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-       c3stl.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include "c3/c3algebra.h"
-#include "c3/c3geometry.h"
-#include "c3/c3object.h"
-#include "c3/c3stl.h"
-
-enum {
-       vertex_None = -1,
-       vertex_Vertex,
-       vertex_Normal,
-};
-
-static int
-_c3stl_read_vertex(
-               char * vt,
-               c3vec3 * out )
-{
-       int res = 1;
-       char *l = vt;
-       /*char * key =*/ strsep(&l, " \t");
-       char * x = strsep(&l, " \t");
-       char * y = strsep(&l, " \t");
-       char * z = strsep(&l, " \t");
-
-       if (x) sscanf(x, "%f", out->n);
-       if (y) sscanf(y, "%f", out->n + 1);
-       if (z) sscanf(z, "%f", out->n + 2);
-//     printf("'%s' '%s' '%s' '%s' = %.2f %.2f %.2f\n",
-//                     key, x, y, z, out->n[0], out->n[1], out->n[2]);
-       return res;
-}
-
-struct c3object_t *
-c3stl_load(
-               const char * filename,
-               c3object_p parent)
-{
-       FILE *f = fopen(filename, "r");
-       if (!f) {
-               perror(filename);
-               return NULL;
-       }
-
-       c3object_p              o = c3object_new(parent);
-       c3geometry_p    current_g = NULL;
-
-       int state = 0;
-       while (!feof(f)) {
-               char line[256];
-
-               fgets(line, sizeof(line), f);
-
-               int l = strlen(line);
-               while (l && line[l-1] < ' ')
-                       line[--l] = 0;
-               if (!l)
-                       continue;
-               char * keyword = line;
-               while (*keyword && *keyword <= ' ')
-                       keyword++;
-               l = strlen(keyword);
-       //      printf("%d>'%s'\n", state, keyword);
-
-               switch (state) {
-                       case 0: //
-                               if (!strncmp(keyword, "solid ", 6)) {
-                                       char * n = keyword + 6;
-                                       current_g = c3geometry_new(c3geometry_type(C3_TRIANGLE_TYPE, 0), o);
-                                       current_g->name = str_new(n);
-
-                                       state = 1;
-                               }
-                               break;
-                       case 1: //
-                               if (!strncmp(keyword, "facet ", 6)) {
-                                       c3vec3 normal;
-                                       _c3stl_read_vertex(keyword + 6, &normal);
-                                       c3vertex_array_add(&current_g->normals, normal);
-                                       c3vertex_array_add(&current_g->normals, normal);
-                                       c3vertex_array_add(&current_g->normals, normal);
-                                       state = 2;
-                               } else if (!strncmp(keyword, "endsolid ", 9))
-                                       state = 0;
-                               break;
-                       case 2:
-                               if (!strncmp(keyword, "outer loop", 10))
-                                       state = 3;
-                               else if (!strncmp(keyword, "endfacet", 8))
-                                       state = 1;
-                               break;
-                       case 3:
-                               if (!strncmp(keyword, "vertex ", 7)) {
-                                       c3vec3 v;
-                                       _c3stl_read_vertex(keyword, &v);
-                                       c3vertex_array_add(&current_g->vertice, v);
-                                       state = 3;
-                               } else if (!strncmp(keyword, "endloop", 7))
-                                       state = 2;
-                               break;
-               }
-       }
-
-       fclose(f);
-       return o;
-}
diff --git a/examples/board_reprap/src/c3/c3stl.h b/examples/board_reprap/src/c3/c3stl.h
deleted file mode 100644 (file)
index d8bd250..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-       c3stl.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3STL_H___
-#define __C3STL_H___
-
-struct c3object_t *
-c3stl_load(
-               const char * filename,
-               struct c3object_t * parent);
-
-#endif /* __C3STL_H___ */
diff --git a/examples/board_reprap/src/c3/c3texture.c b/examples/board_reprap/src/c3/c3texture.c
deleted file mode 100644 (file)
index 2230378..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-       c3texture.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3texture.h"
-#include "c3/c3driver_geometry.h"
-
-void
-_c3texture_dispose(
-               c3geometry_p g,
-               const c3driver_geometry_t * d)
-{
-       c3texture_p t = (c3texture_p)g;
-       c3pixels_dispose(&t->pixels);
-       C3_DRIVER_INHERITED(g, d, dispose);
-}
-
-void
-_c3texture_project(
-               c3geometry_p g,
-               const c3driver_geometry_t * d,
-               c3mat4p m)
-{
-       c3texture_p t = (c3texture_p)g;
-       if (!t->pixels.base) {
-               C3_DRIVER_INHERITED(g, d, project, m);
-               return;
-       }
-       c3vec3 v[4] = {
-                       c3vec3f(0, 0, 0), c3vec3f(t->pixels.w, 0, 0),
-                       c3vec3f(t->pixels.w, t->pixels.h, 0), c3vec3f(0, t->pixels.h, 0)
-       };
-       c3vertex_array_clear(&g->vertice);
-       c3vertex_array_realloc(&g->vertice, 4);
-       c3vertex_array_insert(&g->vertice, 0, v, 4);
-
-       c3vec2 ti[4] = {
-                       c3vec2f(0, 0), c3vec2f(1, 0),
-                       c3vec2f(1, 1), c3vec2f(0, 1)
-//                     c3vec2f(0, 0), c3vec2f(t->pixels.w, 0),
-//                     c3vec2f(t->pixels.w, t->pixels.h), c3vec2f(0, t->pixels.h)
-       };
-       c3tex_array_clear(&t->geometry.textures);
-       c3tex_array_realloc(&t->geometry.textures, 4);
-       c3tex_array_insert(&t->geometry.textures, 0, ti, 4);
-
-       C3_DRIVER_INHERITED(g, d, project, m);
-}
-
-const c3driver_geometry_t c3texture_driver = {
-               .dispose = _c3texture_dispose,
-               .project = _c3texture_project,
-};
-const c3driver_geometry_t c3geometry_driver;
-
-c3texture_p
-c3texture_new(
-               struct c3object_t * o /* = NULL */)
-{
-       c3texture_p res = malloc(sizeof(*res));
-       return c3texture_init(res, o);
-}
-
-c3texture_p
-c3texture_init(
-               c3texture_p t,
-               struct c3object_t * o /* = NULL */)
-{
-       memset(t, 0, sizeof(*t));
-       c3geometry_init(&t->geometry,
-                       c3geometry_type(C3_TEXTURE_TYPE, 0 /* GL_TRIANGLE_FAN */),
-                       o);
-       static const c3driver_geometry_t * list[] = {
-                       &c3texture_driver, &c3geometry_driver, NULL,
-       };
-       t->geometry.driver = list;
-
-       return t;
-}
-
-void
-c3texture_setpixels(
-               )
-{
-
-}
diff --git a/examples/board_reprap/src/c3/c3texture.h b/examples/board_reprap/src/c3/c3texture.h
deleted file mode 100644 (file)
index 97328c5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-       c3texture.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3TEXTURE_H___
-#define __C3TEXTURE_H___
-
-#include "c3/c3geometry.h"
-#include "c3/c3pixels.h"
-
-typedef struct c3texture_t {
-       c3geometry_t    geometry;
-       c3pixels_t              pixels;
-} c3texture_t, *c3texture_p;
-
-c3texture_p
-c3texture_new(
-               struct c3object_t * parent /* = NULL */);
-c3texture_p
-c3texture_init(
-               c3texture_p t,
-               struct c3object_t * parent /* = NULL */);
-
-#endif /* __C3TEXTURE_H___ */
diff --git a/examples/board_reprap/src/c3/c3transform.c b/examples/board_reprap/src/c3/c3transform.c
deleted file mode 100644 (file)
index 4c68b6b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-       c3transform.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3/c3object.h"
-
-c3transform_p
-c3transform_new(
-               c3object_p o )
-{
-       c3transform_p res = malloc(sizeof(*res));
-       res->matrix = identity3D();
-       res->object = o;
-       res->name = NULL;
-       c3transform_array_add(&o->transform, res);
-       return res;
-}
-
-void
-c3transform_dispose(
-               c3transform_p t )
-{
-       if (t->object) {
-               for (int oi = 0; oi < t->object->transform.count; oi++)
-                       if (t->object->transform.e[oi] == t) {
-                               c3transform_array_delete(&t->object->transform, oi, 1);
-                               c3object_set_dirty(t->object, true);
-                               break;
-                       }
-               t->object = NULL;
-       }
-       str_free(t->name);
-       free(t);
-}
-
-void
-c3transform_set(
-               c3transform_p t,
-               const c3mat4p m )
-{
-       if (c3mat4_equal(m, &t->matrix))
-               return;
-       t->matrix = *m;
-       c3object_set_dirty(t->object, true);
-}
diff --git a/examples/board_reprap/src/c3/c3transform.h b/examples/board_reprap/src/c3/c3transform.h
deleted file mode 100644 (file)
index 9a50e3b..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-       c3transform.h
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3TRANSFORM_H___
-#define __C3TRANSFORM_H___
-
-#include "c3/c3algebra.h"
-#include "c_utils.h"
-
-typedef struct c3transform_t {
-       str_p name;
-       struct c3object_t * object;
-       c3mat4  matrix;
-} c3transform_t, *c3transform_p;
-
-c3transform_p
-c3transform_new(
-               struct c3object_t * o );
-void
-c3transform_set(
-               c3transform_p t,
-               c3mat4p m );
-void
-c3transform_dispose(
-               c3transform_p t );
-
-DECLARE_C_ARRAY(c3transform_p, c3transform_array, 4);
-IMPLEMENT_C_ARRAY(c3transform_array);
-
-#endif /* __C3TRANSFORM_H___ */
diff --git a/examples/board_reprap/src/c3/c_array.h b/examples/board_reprap/src/c3/c_array.h
deleted file mode 100644 (file)
index 8c08efa..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-       c_array.h
-
-       Copyright 2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of gcodepp.
-
-       gcodepp 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 3 of the License, or
-       (at your option) any later version.
-
-       gcodepp 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 gcodepp.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C_ARRAY_H___
-#define __C_ARRAY_H___
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef C_ARRAY_INLINE
-#define C_ARRAY_INLINE inline
-#endif
-#ifndef C_ARRAY_SIZE_TYPE
-#define C_ARRAY_SIZE_TYPE uint32_t
-#endif
-
-#define DECLARE_C_ARRAY(__type, __name, __page) \
-enum { __name##_page_size = __page }; \
-typedef __type __name##_element_t; \
-typedef C_ARRAY_SIZE_TYPE __name##_count_t; \
-typedef struct __name##_t {\
-       volatile __name##_count_t count;\
-       volatile __name##_count_t size;\
-       __name##_element_t * e;\
-} __name##_t, *__name##_p;
-
-#define C_ARRAY_NULL { 0, 0, NULL }
-
-#define IMPLEMENT_C_ARRAY(__name) \
-static const __name##_t __name##_zero = C_ARRAY_NULL; \
-static C_ARRAY_INLINE \
-       void __name##_free(\
-                       __name##_p a) \
-{\
-       if (!a) return;\
-       if (a->e) free(a->e);\
-       *a = __name##_zero;\
-}\
-static C_ARRAY_INLINE \
-       void __name##_clear(\
-                       __name##_p a) \
-{\
-       if (!a) return;\
-       a->count = 0;\
-}\
-static C_ARRAY_INLINE \
-       void __name##_realloc(\
-                       __name##_p a, __name##_count_t size) \
-{\
-       if (!a || a->size == size) return; \
-       a->e = realloc(a->e, size * sizeof(__name##_element_t));\
-       a->size = size; \
-}\
-static C_ARRAY_INLINE \
-       void __name##_trim(\
-                       __name##_p a) \
-{\
-       if (!a) return;\
-       __name##_count_t n = a->count + __name##_page_size;\
-       n -= (n % __name##_page_size);\
-       if (n != a->size)\
-               __name##_realloc(a, n);\
-}\
-static C_ARRAY_INLINE \
-       __name##_element_t * __name##_get_ptr(\
-                       __name##_p a, __name##_count_t index) \
-{\
-       if (!a) return NULL;\
-       if (index > a->count) index = a->count;\
-       return index < a->count ? a->e + index : NULL;\
-}\
-static C_ARRAY_INLINE \
-       __name##_count_t __name##_add(\
-                       __name##_p a, __name##_element_t e) \
-{\
-       if (!a) return 0;\
-       if (a->count + 1 >= a->size)\
-               __name##_realloc(a, a->size + __name##_page_size);\
-       a->e[a->count++] = e;\
-       return a->count;\
-}\
-static C_ARRAY_INLINE \
-       __name##_count_t __name##_insert(\
-                       __name##_p a, __name##_count_t index, \
-                       __name##_element_t * e, __name##_count_t count) \
-{\
-       if (!a) return 0;\
-       if (index > a->count) index = a->count;\
-       if (a->count + count >= a->size) \
-               __name##_realloc(a, (((a->count + count) / __name##_page_size)+1) * __name##_page_size);\
-       if (index < a->count)\
-               memmove(&a->e[index + count], &a->e[index], \
-                               (a->count - index + count) * sizeof(__name##_element_t));\
-       memmove(&a->e[index], e, count * sizeof(__name##_element_t));\
-       a->count += count;\
-       return a->count;\
-}\
-static C_ARRAY_INLINE \
-       __name##_count_t __name##_delete(\
-                       __name##_p a, __name##_count_t index, __name##_count_t count) \
-{\
-       if (!a) return 0;\
-       if (index > a->count) index = a->count;\
-       if (index + count > a->count) \
-               count = a->count - index;\
-       if (count && a->count - index) { \
-               memmove(&a->e[index], &a->e[index + count], \
-                               (a->count - index - count) * sizeof(__name##_element_t));\
-       }\
-       a->count -= count;\
-       return a->count;\
-}
-
-#endif /* __C_ARRAY_H___ */
diff --git a/examples/board_reprap/src/c3/c_utils.c b/examples/board_reprap/src/c3/c_utils.c
deleted file mode 100644 (file)
index e3bb673..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-       c_utils.c
-
-       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
-       This file is part of simavr.
-
-       simavr 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 3 of the License, or
-       (at your option) any later version.
-
-       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c_utils.h"
-
-void
-str_hash_init(str_hash_p h)
-{
-       memset(h, 0, sizeof(*h));
-}
-
-void
-str_hash_add(
-       str_hash_p h,
-       str_p k,
-       void * v)
-{
-       uint16_t hv = str_hash(k);
-       hashval_array_p bin = &h->bin[hv & (STR_HASH_SIZE-1)];
-       int inserti = bin->count;
-
-       for (int i = 0; i < bin->count; i++)
-               if (bin->e[i].key->hash >= hv) {
-                       inserti = i;
-                       break;
-               }
-       str_hashval_t n = { .key = str_dup(k), .val = v };
-       hashval_array_insert(bin, inserti, &n, 1);
-       return;
-}
-
-void *
-str_hash_lookup(
-       str_hash_p h,
-       str_p k )
-{
-       uint16_t hv = str_hash(k);
-       hashval_array_p bin = &h->bin[hv & (STR_HASH_SIZE-1)];
-
-       for (int i = 0; i < bin->count; i++) {
-               uint16_t h = bin->e[i].key->hash;
-               if (h == hv && !str_cmp(k, bin->e[i].key))
-                       return bin->e[i].val;
-               else if (h > hv)
-                       break;
-       }
-       return NULL;
-}
diff --git a/examples/board_reprap/src/c3/c_utils.h b/examples/board_reprap/src/c3/c_utils.h
deleted file mode 100644 (file)
index 2360fd8..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-       c_utils.h
-
-       Copyright 2008-11 Michel Pollet <buserror@gmail.com>
-
-       This program cross examines a root filesystem, loads all the elf
-       files it can find, see what other library they load and then
-       find the orphans. In then remove the orphans as "user" for it's
-       dependencies and continues removing until everything has at least
-       one user, OR is a program itself (ie, not a shared library)
-
-       cross_linker 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 3 of the License, or
-       (at your option) any later version.
-
-       cross_linker 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 cross_linker.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __C_UTILS_H__
-#define __C_UTILS_H__
-
-#ifndef NO_ALLOCA
-#include <alloca.h>
-#endif
-#include "c_array.h"
-
-/********************************************************************
- * CRC16
- ********************************************************************/
-
-static uint8_t _crc16_lh[16] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
-        0x70, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1 };
-static uint8_t _crc16_ll[16] = { 0x00, 0x21, 0x42, 0x63, 0x84, 0xA5, 0xC6,
-        0xE7, 0x08, 0x29, 0x4A, 0x6B, 0x8C, 0xAD, 0xCE, 0xEF };
-
-static uint16_t crc16_u4(uint16_t crc, uint8_t val)
-{
-       uint8_t h = crc >> 8, l = crc & 0xff;
-       uint8_t t = (h >> 4) ^ val;
-
-       // Shift the CRC Register left 4 bits
-       h = (h << 4) | (l >> 4);
-       l = l << 4;
-       // Do the table lookups and XOR the result into the CRC Tables
-       h = h ^ _crc16_lh[t];
-       l = l ^ _crc16_ll[t];
-       return (h << 8) | l;
-}
-
-static uint16_t crc16_update(uint16_t crc, uint8_t val)
-{
-       crc = crc16_u4(crc, val >> 4); // High nibble first
-       crc = crc16_u4(crc, val & 0x0F); // Low nibble
-       return crc;
-}
-
-static uint16_t crc16_string(char * str)
-{
-       uint16_t crc = 0xffff;
-       while (*str)
-               crc = crc16_update(crc, *str++);
-       return crc;
-}
-
-/********************************************************************
- * Hashed strings
- ********************************************************************/
-
-#include <string.h>
-typedef struct str_t {
-       uint32_t hash : 16, rom : 1,  len : 15;
-       char str[0];
-} str_t, *str_p;
-
-static inline str_p str_new_i(const char *s, void * (*_alloc)(size_t))
-{
-       int l = s ? strlen(s) : 0;
-       str_p r = (str_p)_alloc(sizeof(*r) + l + 1);
-       r->hash = 0; r->len = l;
-       if (s)
-               strcpy(r->str, s);
-       return r;
-}
-static inline void str_free(str_p s)
-{
-       if (s && !s->rom)
-               free(s);
-}
-static inline str_p str_new(const char *s)
-{
-       return str_new_i(s, malloc);
-}
-static inline str_p str_anew(const char *s)
-{
-       str_p r = str_new_i(s, alloca);
-       r->rom = 1;
-       return r;
-}
-static inline str_p str_dup(const str_p s)
-{
-       size_t l = sizeof(*s) + s->len + 1;
-       str_p r = (str_p)malloc(l);
-       memcpy(r, s, l);
-       return r;
-}
-#ifndef NO_ALLOCA
-static inline str_p str_adup(const str_p s)
-{
-       size_t l = sizeof(*s) + s->len + 1;
-       str_p r = (str_p)alloca(l);
-       memcpy(r, s, l);
-       r->rom = 1;
-       return r;
-}
-#endif
-static inline uint16_t str_hash(str_p s)
-{
-       if (!s->hash) s->hash = crc16_string(s->str);
-       return s->hash;
-}
-static inline int str_cmp(str_p s1, str_p s2)
-{
-       if (s1 == s2) return 1;
-       if (s1->len != s2->len) return 1;
-       str_hash(s1);
-       str_hash(s2);
-       return s1->hash == s2->hash ? strcmp(s1->str, s2->str) : 1;
-}
-
-/********************************************************************
- * Hash table of strings. Key/value pair
- ********************************************************************/
-
-typedef struct str_hashval_t {
-       str_p key;
-       void * val;
-} str_hashval_t;
-
-DECLARE_C_ARRAY(str_hashval_t, hashval_array, 16);
-IMPLEMENT_C_ARRAY(hashval_array);
-
-#ifndef STR_HASH_SIZE
-#define STR_HASH_SIZE  512     // use 9 bits of the 16 of the CRC
-#endif
-/* uses bins to store the strings as per their hash values */
-typedef struct str_hash_t {
-       hashval_array_t bin[STR_HASH_SIZE];
-} str_hash_t, *str_hash_p;
-
-void
-str_hash_init(
-               str_hash_p h);
-void
-str_hash_add(
-       str_hash_p h, 
-       str_p k, 
-       void * v);
-
-void *
-str_hash_lookup(
-       str_hash_p h, 
-       str_p k );
-
-#endif /* __C_UTILS_H__ */
index 8bfe8a97da9cab1240f26e400725682de47d4170..1d66cbd657aa7a9b5f57179e3ea2a54268a00775 100644 (file)
  */
 
 #if __APPLE__
+#define GL_GLEXT_PROTOTYPES
 #include <GLUT/glut.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
 #else
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
 #include <GL/glut.h>
+#include <GL/glext.h>
 #endif
 
 #include <stdio.h>
 #include "reprap.h"
 #include "reprap_gl.h"
 
-#include "c3/c3.h"
-#include "c3/c3camera.h"
-#include "c3/c3arcball.h"
-#include "c3/c3driver_context.h"
-#include "c3/c3stl.h"
+#include "c3.h"
+#include "c3camera.h"
+#include "c3driver_context.h"
+#include "c3stl.h"
+#include "c3lines.h"
 
 #include <cairo/cairo.h>
 
+struct cairo_surface_t;
+
 int _w = 800, _h = 600;
-c3cam cam;
-c3arcball arcball;
+//c3cam cam;
 c3context_p c3;
 c3context_p hud;
 c3object_p head;
 
+c3texture_p fbo_c3;
+
 extern reprap_t reprap;
 
 static int dumpError(const char * what)
@@ -59,6 +68,200 @@ static int dumpError(const char * what)
        return count;
 }
 
+#define GLCHECK(_w) {_w; dumpError(#_w);}
+
+void print_log(GLuint obj)
+{
+       int infologLength = 0;
+       int maxLength;
+
+       if(glIsShader(obj))
+               glGetShaderiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
+       else
+               glGetProgramiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
+
+       char infoLog[maxLength];
+
+       if (glIsShader(obj))
+               glGetShaderInfoLog(obj, maxLength, &infologLength, infoLog);
+       else
+               glGetProgramInfoLog(obj, maxLength, &infologLength, infoLog);
+
+       if (infologLength > 0)
+               printf("%s\n",infoLog);
+}
+/* Global */
+GLuint fbo, fbo_texture, rbo_depth;
+//GLuint vbo_fbo_vertices;
+
+static void
+gl_offscreenInit(
+               int screen_width,
+               int screen_height)
+{
+       /* init_resources */
+       /* Create back-buffer, used for post-processing */
+
+       /* Texture */
+       GLCHECK(glActiveTexture(GL_TEXTURE0));
+       glGenTextures(1, &fbo_texture);
+       glBindTexture(GL_TEXTURE_2D, fbo_texture);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
+               GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+       glBindTexture(GL_TEXTURE_2D, 0);
+
+       /* Depth buffer */
+       GLCHECK(glGenRenderbuffers(1, &rbo_depth));
+       glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
+       glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
+               screen_height);
+       glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+       /* Framebuffer to link everything together */
+       GLCHECK(glGenFramebuffers(1, &fbo));
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+               fbo_texture, 0);
+       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+               GL_RENDERBUFFER, rbo_depth);
+
+       GLenum status;
+       if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER))
+               != GL_FRAMEBUFFER_COMPLETE) {
+               fprintf(stderr, "glCheckFramebufferStatus: error %d", (int)status);
+               return ;
+       }
+#if 0
+       // Set the list of draw buffers.
+       GLenum DrawBuffers[2] = {GL_COLOR_ATTACHMENT0};
+       glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#endif
+}
+
+void
+gl_offscreenReshape(
+               int screen_width,
+               int screen_height)
+{
+// Rescale FBO and RBO as well
+       glBindTexture(GL_TEXTURE_2D, fbo_texture);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0,
+               GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+       glBindTexture(GL_TEXTURE_2D, 0);
+
+       glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
+       glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width,
+               screen_height);
+       glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+//     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+//    glViewport(0, 0, screen_width, screen_height);
+//     glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void gl_offscreenFree()
+{
+       /* free_resources */
+       glDeleteRenderbuffers(1, &rbo_depth);
+       glDeleteTextures(1, &fbo_texture);
+       glDeleteFramebuffers(1, &fbo);
+//       glDeleteBuffers(1, &vbo_fbo_vertices);
+}
+
+GLuint program_postproc = 0, uniform_fbo_texture;
+
+static GLuint create_shader(const char * fname, GLuint pid)
+{
+       const GLchar * buf;
+
+       FILE *f = fopen(fname, "r");
+       if (!f) {
+               perror(fname);
+               return 0;
+       }
+       fseek(f, 0, SEEK_END);
+       long fs = ftell(f);
+       fseek(f, 0, SEEK_SET);
+       buf = malloc(fs + 1);
+       fread((void*)buf, 1, fs, f);
+       ((char*)buf)[fs] = 0;
+       fclose(f);
+
+       GLuint vs = glCreateShader(pid);
+       glShaderSource(vs, 1, &buf, NULL);
+       glCompileShader(vs);
+       dumpError("glCompileShader");
+       print_log(vs);
+       free((void*)buf);
+       return vs;
+}
+
+
+int gl_ppProgram()
+{
+       int vs, fs;
+       int link_ok, validate_ok;
+       /* init_resources */
+       /* Post-processing */
+       if ((vs = create_shader("gfx/postproc.vs", GL_VERTEX_SHADER)) == 0)
+               return 0;
+       if ((fs = create_shader("gfx/postproc.fs", GL_FRAGMENT_SHADER)) == 0)
+               return 0;
+
+       program_postproc = glCreateProgram();
+       glAttachShader(program_postproc, vs);
+       glAttachShader(program_postproc, fs);
+       glLinkProgram(program_postproc);
+       glGetProgramiv(program_postproc, GL_LINK_STATUS, &link_ok);
+       if (!link_ok) {
+               fprintf(stderr, "glLinkProgram:");
+               goto error;
+       }
+       glValidateProgram(program_postproc);
+       glGetProgramiv(program_postproc, GL_VALIDATE_STATUS, &validate_ok);
+       if (!validate_ok) {
+               fprintf(stderr, "glValidateProgram:");
+               goto error;
+       }
+
+       char * uniform_name = "m_Texture";
+       uniform_fbo_texture = glGetUniformLocation(program_postproc, uniform_name);
+       if (uniform_fbo_texture == -1) {
+               fprintf(stderr, "Could not bind uniform %s\n", uniform_name);
+               goto error;
+       }
+       return 0;
+error:
+       print_log(program_postproc);
+       glDeleteProgram(program_postproc);
+       program_postproc = 0;
+       return -1;
+}
+
+void
+gl_ppFree()
+{
+       if (program_postproc)
+               glDeleteProgram(program_postproc);
+       program_postproc = 0;
+}
+
+static void
+_gl_reshape_cb(int w, int h)
+{
+    _w  = w;
+    _h = h;
+
+    glViewport(0, 0, _w, _h);
+    gl_offscreenReshape(_w, _h);
+    glutPostRedisplay();
+}
+
 static void
 _gl_key_cb(
                unsigned char key,
@@ -79,9 +282,71 @@ _gl_key_cb(
                        printf("Stopping VCD trace\n");
                //      avr_vcd_stop(&vcd_file);
                        break;
+               case '1':
+                       if (fbo_c3->geometry.mat.program.pid)
+                               fbo_c3->geometry.mat.program.pid = 0;
+                       else
+                               fbo_c3->geometry.mat.program.pid = program_postproc;
+                       glutPostRedisplay();
+                       break;
        }
 }
 
+static void
+_c3_load_pixels(
+               c3pixels_p pix)
+{
+       GLuint mode = pix->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
+       if (!pix->texture) {
+               printf("Creating texture %s %dx%d\n", pix->name ? pix->name->str : "", pix->w, pix->h);
+               pix->dirty = 1;
+               GLuint texID = 0;
+               dumpError("cp_gl_texture_load_argb flush");
+               GLCHECK(glEnable(mode));
+
+               glGenTextures(1, &texID);
+//             glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+//                             GL_MODULATE); //set texture environment parameters
+//             dumpError("glTexEnvf");
+
+               glPixelStorei(GL_UNPACK_ROW_LENGTH, pix->row / pix->psize);
+               glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               dumpError("GL_TEXTURE_MAG_FILTER");//
+               glTexParameteri(mode, GL_TEXTURE_MIN_FILTER,
+                               pix->normalize ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
+               dumpError("GL_TEXTURE_MIN_FILTER");
+               glTexParameteri(mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+               dumpError("GL_TEXTURE_WRAP_S");
+               glTexParameteri(mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+               dumpError("GL_TEXTURE_WRAP_T");
+               if (pix->normalize)
+                       GLCHECK(glTexParameteri(mode, GL_GENERATE_MIPMAP, GL_TRUE));
+       #if 1
+               GLfloat fLargest;
+               glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
+               //printf("fLargest = %f\n", fLargest);
+               GLCHECK(glTexParameterf(mode, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest));
+       #endif
+               if (pix->normalize)
+                       GLCHECK(glGenerateMipmap(mode));
+
+               pix->texture = texID;
+               pix->dirty = 1;
+       }
+       if (pix->dirty) {
+               pix->dirty = 0;
+               GLCHECK(glBindTexture(mode, pix->texture));
+               glTexImage2D(mode, 0,
+                               pix->format == C3PIXEL_A ? GL_ALPHA16 : GL_RGBA8,
+                               pix->w, pix->h, 0,
+                               pix->format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
+                               GL_UNSIGNED_BYTE,
+                               pix->base);
+               dumpError("glTexImage2D");
+               if (pix->normalize)
+                       GLCHECK(glGenerateMipmap(mode));
+       }
+}
 
 static void
 _c3_geometry_project(
@@ -90,142 +355,24 @@ _c3_geometry_project(
                c3geometry_p g,
                c3mat4p m)
 {
+       if (g->mat.texture) {
+//             printf("_c3_geometry_project xrure %d!\n", g->textures.count);
+               _c3_load_pixels(g->mat.texture);
+       }
+
        switch(g->type.type) {
-               case C3_TRIANGLE_TYPE: {
+               case C3_TRIANGLE_TYPE:
                        g->type.subtype = GL_TRIANGLES;
-                       //g->mat.color = c3vec4f(0.0, 0.0, 1.0, 1.0);
-               }       break;
+                       break;
                case C3_TEXTURE_TYPE: {
-                       c3texture_p t = (c3texture_p)g;
-                       g->type.subtype = GL_TRIANGLE_FAN;
-                       g->mat.color = c3vec4f(0.0, 1.0, 0.0, 0.5);
-                       printf("_c3_geometry_project xrure %d!\n", g->textures.count);
-                       if (!g->texture) {
-                               GLuint texID = 0;
-                               dumpError("cp_gl_texture_load_argb flush");
-
-                               if (g->mat.mode == 0)
-                                       g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
-
-                               printf("C3_TEXTURE_TYPE %d\n",g->mat.mode);
-                               glEnable(g->mat.mode);
-                               dumpError("cp_gl_texture_load_argb GL_TEXTURE_RECTANGLE_ARB");
-
-                               glGenTextures(1, &texID);
-                               dumpError("cp_gl_texture_load_argb glBindTexture GL_TEXTURE_RECTANGLE_ARB");
-
-//                             glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
-//                                             GL_MODULATE ); //set texture environment parameters
-                               dumpError("glTexEnvf");
-
-                               glPixelStorei(GL_UNPACK_ROW_LENGTH, t->pixels.row / t->pixels.psize);
-                               glTexParameteri(g->mat.mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-                               dumpError("GL_TEXTURE_MAG_FILTER");
-                               glTexParameteri(g->mat.mode, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-                               dumpError("GL_TEXTURE_MIN_FILTER");
-                               glTexParameteri(g->mat.mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-                               dumpError("GL_TEXTURE_WRAP_S");
-                               glTexParameteri(g->mat.mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
-                               dumpError("GL_TEXTURE_WRAP_T");
-                               glTexParameteri(g->mat.mode, GL_GENERATE_MIPMAP, GL_TRUE);
-                               dumpError("GL_GENERATE_MIPMAP");
-                               glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
-                               dumpError("GL_GENERATE_MIPMAP_HINT");
-
-                               g->mat.texture = texID;
-                               g->texture = 1;
+               //      c3texture_p t = (c3texture_p)g;
+                       if (g->mat.texture) {
+                               g->type.subtype = GL_TRIANGLE_FAN;
                        }
-                       glBindTexture(g->mat.mode, g->mat.texture);
-                       dumpError("glBindTexture");
-                       glTexImage2D(g->mat.mode, 0,
-                                       t->pixels.format == C3PIXEL_A ? GL_ALPHA8 : GL_RGBA8,
-                                       t->pixels.w, t->pixels.h, 0,
-                                       t->pixels.format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
-                                       GL_UNSIGNED_BYTE,
-                                       t->pixels.base);
-                       dumpError("glTexImage2D");
-                       glGenerateMipmap(GL_TEXTURE_2D);
-                       dumpError("glGenerateMipmap");
-
                }       break;
-               case C3_LINES_TYPE: {
-               //      glLineWidth(1);
-                       float lineWidth = 0.2;
-
-                       c3vertex_array_p v = &g->projected;
-                       c3tex_array_p tex = &g->textures;
-                       c3tex_array_clear(tex);
-                       c3vertex_array_clear(v);
-                       for (int l = 0; l < g->vertice.count; l += 2) {
-                               c3vec3 a = c3mat4_mulv3(m, g->vertice.e[l]);
-                               c3vec3 b = c3mat4_mulv3(m, g->vertice.e[l+1]);
-
-                               c3vec3 e = c3vec3_mulf(c3vec3_normalize(c3vec3_sub(b, a)), lineWidth);
-
-                               c3vec3 N = c3vec3f(-e.y, e.x, 0);
-                               c3vec3 S = c3vec3_minus(N);
-                               c3vec3 NE = c3vec3_add(N, e);
-                               c3vec3 NW = c3vec3_sub(N, e);
-                               c3vec3 SW = c3vec3_minus(NE);
-                               c3vec3 SE = c3vec3_minus(NW);
-#if 0
-                               c3vertex_array_add(v, c3vec3_add(a, SW));
-                               c3vertex_array_add(v, c3vec3_add(a, NW));
-                               c3vertex_array_add(v, c3vec3_add(a, S));
-                               c3vertex_array_add(v, c3vec3_add(a, N));
-                               c3vertex_array_add(v, c3vec3_add(b, S));
-                               c3vertex_array_add(v, c3vec3_add(b, N));
-                               c3vertex_array_add(v, c3vec3_add(b, SE));
-                               c3vertex_array_add(v, c3vec3_add(b, NE));
-#endif
-
-                               const float ts = 1;
-
-                               c3vertex_array_add(v, c3vec3_add(a, SW));
-                               c3vertex_array_add(v, c3vec3_add(a, S));
-                               c3vertex_array_add(v, c3vec3_add(a, NW));
-                               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
-
-                               c3vertex_array_add(v, c3vec3_add(a, S));
-                               c3vertex_array_add(v, c3vec3_add(a, N));
-                               c3vertex_array_add(v, c3vec3_add(a, NW));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
-
-                               c3vertex_array_add(v, c3vec3_add(a, N));
-                               c3vertex_array_add(v, c3vec3_add(b, S));
-                               c3vertex_array_add(v, c3vec3_add(b, N));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
-
-                               c3vertex_array_add(v, c3vec3_add(a, N));
-                               c3vertex_array_add(v, c3vec3_add(a, S));
-                               c3vertex_array_add(v, c3vec3_add(b, S));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
-
-                               c3vertex_array_add(v, c3vec3_add(b, N));
-                               c3vertex_array_add(v, c3vec3_add(b, S));
-                               c3vertex_array_add(v, c3vec3_add(b, SE));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
-
-                               c3vertex_array_add(v, c3vec3_add(b, N));
-                               c3vertex_array_add(v, c3vec3_add(b, SE));
-                               c3vertex_array_add(v, c3vec3_add(b, NE));
-                               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
-                               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 1  ));
-
-                       }
+               case C3_LINES_TYPE:
                        g->type.subtype = GL_TRIANGLES;
-               }       break;
+                       break;
                default:
                    break;
        }
@@ -245,26 +392,37 @@ _c3_geometry_draw(
        glEnableClientState(GL_VERTEX_ARRAY);
        dumpError("GL_VERTEX_ARRAY");
        glDisable(GL_TEXTURE_2D);
-       if (g->textures.count && g->texture) {
-               glEnable(g->mat.mode);
+       if (g->mat.texture) {
+               GLuint mode = g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
+               glEnable(mode);
+               if (g->mat.texture->trace)
+                       printf("%s uses texture %s (%d tex)\n",
+                                       __func__, g->mat.texture->name->str, g->textures.count);
        //      printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
                dumpError("glEnable texture");
-               glBindTexture(g->mat.mode, g->mat.texture);
+               glBindTexture(mode, g->mat.texture->texture);
                dumpError("glBindTexture");
                glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                dumpError("GL_TEXTURE_COORD_ARRAY");
        }
+       if (g->mat.program.pid) {
+               glUseProgram(g->mat.program.pid);
+               dumpError("glUseProgram program_postproc");
+       }
        if (g->normals.count) {
                glNormalPointer(GL_FLOAT, 0, g->normals.e);
                glEnableClientState(GL_NORMAL_ARRAY);
        }
-       glDrawArrays(g->type.subtype, 0, g->projected.count ? g->projected.count : g->vertice.count);
+       glDrawArrays(g->type.subtype, 0,
+                       g->projected.count ? g->projected.count : g->vertice.count);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);
-       if (g->textures.count && g->texture)
-               glDisable(g->mat.mode);
+       if (g->mat.texture)
+               glDisable(g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB);
+       if (g->mat.program.pid)
+               glUseProgram(0);
 }
 
 const c3driver_context_t c3context_driver = {
@@ -272,6 +430,7 @@ const c3driver_context_t c3context_driver = {
                .geometry_draw = _c3_geometry_draw,
 };
 
+float z_min, z_max;
 /*
  * Computes the distance from the eye, sort by this value
  */
@@ -286,9 +445,13 @@ _c3_z_sorter(
        c3vec3 c1 = c3vec3_add(g1->bbox.min, c3vec3_divf(c3vec3_sub(g1->bbox.max, g1->bbox.min), 2));
        c3vec3 c2 = c3vec3_add(g2->bbox.min, c3vec3_divf(c3vec3_sub(g2->bbox.max, g2->bbox.min), 2));
 
-       c3f d1 = c3vec3_length2(c3vec3_sub(c1, cam.eye));
-       c3f d2 = c3vec3_length2(c3vec3_sub(c2, cam.eye));
+       c3f d1 = c3vec3_length2(c3vec3_sub(c1, c3->cam.eye));
+       c3f d2 = c3vec3_length2(c3vec3_sub(c2, c3->cam.eye));
 
+       if (d1 > z_max) z_max = d1;
+       if (d1 < z_min) z_min = d1;
+       if (d2 > z_max) z_max = d2;
+       if (d2 < z_min) z_min = d2;
        /*
         * make sure transparent items are drawn after everyone else
         */
@@ -300,9 +463,52 @@ _c3_z_sorter(
        return d1 < d2 ? 1 : d1 > d2 ? -1 : 0;
 }
 
+#define FBO 0
+
 static void
 _gl_display_cb(void)           /* function called whenever redisplay needed */
 {
+#if FBO
+       if (program_postproc) {
+               /*
+                * Draw in FBO object
+                */
+               glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+               // draw (without glutSwapBuffers)
+               dumpError("glBindFramebuffer fbo");
+               glViewport(0, 0, _w, _h);
+       }
+#else
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#endif
+
+       c3vec3 headp = c3vec3f(
+                       stepper_get_position_mm(&reprap.step_x),
+                       stepper_get_position_mm(&reprap.step_y),
+                       stepper_get_position_mm(&reprap.step_z));
+       c3mat4 headmove = translation3D(headp);
+       c3transform_set(head->transform.e[0], &headmove);
+
+       if (c3->root->dirty) {
+               printf("reproject head %.2f,%.2f,%.2f\n", headp.x, headp.y,headp.z);
+               c3context_project(c3);
+
+               z_min = 1000000000;
+               z_max = -1000000000;
+               qsort(c3->projected.e, c3->projected.count, sizeof(c3->projected.e[0]),
+                       _c3_z_sorter);
+               z_min = sqrt(z_min);
+               z_max = sqrt(z_max);
+               //      printf("z_min %f, z_max %f\n", z_min, z_max);
+               //z_min -= 50;
+               if (z_min < 0)
+                       z_min = 10;
+               z_min = 10;
+               if (z_max < z_min || z_max > 1000)
+                       z_max = 1000;
+       }
+
+
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -310,50 +516,71 @@ _gl_display_cb(void)              /* function called whenever redisplay needed */
        glMatrixMode(GL_PROJECTION); // Select projection matrix
        glLoadIdentity(); // Start with an identity matrix
 
-       gluPerspective(60, _w / _h, 60, 400);
+       gluPerspective(50, (float)_w / (float)_h, z_min, z_max);
 #if 0
        glCullFace(GL_BACK);
        glEnable(GL_CULL_FACE);
 #endif
        glDepthMask(GL_TRUE);
+       glDepthFunc(GL_LEQUAL);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
 //     glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
 
-       glEnable(GL_BLEND);                         // Enable Blending
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);          // Type Of Blending To Use
-
-    glMatrixMode( GL_MODELVIEW );
-    glLoadIdentity();
-   // glMultMatrixf(arcball.rot.n);
-    glMultMatrixf(cam.mtx.n);
-    glTranslatef( -cam.eye.n[VX], -cam.eye.n[VY], -cam.eye.n[VZ] );
-  //  glMultMatrixf(arcball.rot.n);
+       glEnable(GL_ALPHA_TEST);
+       glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
+       glEnable(GL_BLEND); // Enable Blending
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Type Of Blending To Use
 
-       c3vec3 headp = c3vec3f(
-                       stepper_get_position_mm(&reprap.step_x),
-                       stepper_get_position_mm(&reprap.step_y),
-                       stepper_get_position_mm(&reprap.step_z));
-       c3mat4 headmove = translation3D(headp);
-       c3transform_set(head->transform.e[0], &headmove);
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+       glMultMatrixf(c3->cam.mtx.n);
+       glTranslatef(-c3->cam.eye.n[VX], -c3->cam.eye.n[VY], -c3->cam.eye.n[VZ]);
 
-       if (c3->root->dirty) {
-       //      printf("reproject\n");
-               c3context_project(c3);
+       dumpError("flush");
 
-               qsort(c3->projected.e, c3->projected.count,
-                               sizeof(c3->projected.e[0]), _c3_z_sorter);
-       }
        c3context_draw(c3);
 
-       glMatrixMode(GL_PROJECTION); // Select projection matrix
+#if FBO
+       /*
+        * Draw back FBO over the screen
+        */
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+       dumpError("glBindFramebuffer 0");
+
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
+       glDisable(GL_ALPHA_TEST);
+
+       glMatrixMode(GL_PROJECTION); // Select projection matrix
+       glLoadIdentity(); // Start with an identity matrix
+
+       glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+       glMatrixMode(GL_MODELVIEW); // Select modelview matrix
+       glLoadIdentity(); // Start with an identity matrix
+
+#if 0
+       glEnable(GL_TEXTURE_2D);
+       glBindTexture(GL_TEXTURE_2D, fbo_texture);
+       dumpError("glBindTexture fbo");
+#if 0
+       glUseProgram(program_postproc);
+       dumpError("glUseProgram program_postproc");
+       glUniform1i(uniform_fbo_texture, /*GL_TEXTURE*/0);
+#endif
+       glUseProgram(0);
+#endif
+#endif
+
+       glMatrixMode(GL_PROJECTION); // Select projection matrix
        glLoadIdentity(); // Start with an identity matrix
        glOrtho(0, _w, 0, _h, 0, 10);
-       glScalef(1,-1,1);
+       glScalef(1, -1, 1);
        glTranslatef(0, -1 * _h, 0);
        glMatrixMode(GL_MODELVIEW); // Select modelview matrix
+       glLoadIdentity(); // Start with an identity matrix
 
        if (hud)
                c3context_draw(hud);
@@ -361,9 +588,14 @@ _gl_display_cb(void)               /* function called whenever redisplay needed */
     glutSwapBuffers();
 }
 
+#if !defined(GLUT_WHEEL_UP)
+#  define GLUT_WHEEL_UP   3
+#  define GLUT_WHEEL_DOWN 4
+#endif
+
+
 int button;
 c3vec2 move;
-c3cam startcam;
 
 static
 void _gl_button_cb(
@@ -373,12 +605,22 @@ void _gl_button_cb(
                int y)
 {
        button = s == GLUT_DOWN ? b : 0;
-       startcam = cam;
        move = c3vec2f(x, y);
-       if (s == GLUT_DOWN)
-               c3arcball_mouse_down(&arcball, x, y);
-       else
-               c3arcball_mouse_up(&arcball);
+//     printf("button %d: %.1f,%.1f\n", b, move.x, move.y);
+       switch (b) {
+               case GLUT_LEFT_BUTTON:
+               case GLUT_RIGHT_BUTTON: // call motion
+                       break;
+               case GLUT_WHEEL_UP:
+               case GLUT_WHEEL_DOWN:
+                       if (c3->cam.distance > 10) {
+                               const float d = 0.004;
+                               c3cam_set_distance(&c3->cam, c3->cam.distance * ((b == GLUT_WHEEL_DOWN) ? (1.0+d) : (1.0-d)));
+                               c3cam_update_matrix(&c3->cam);
+                               c3->root->dirty = 1;    // resort the array
+                       }
+                       break;
+       }
 }
 
 void
@@ -389,26 +631,32 @@ _gl_motion_cb(
        c3vec2 m = c3vec2f(x, y);
        c3vec2 delta = c3vec2_sub(move, m);
 
-//     printf("%s b%d click %.1f,%.1f now %d,%d\n",
-//                     __func__, button, move.n[0], move.n[1], x, y);
+//     printf("%s b%d click %.1f,%.1f now %d,%d delta %.1f,%.1f\n",
+//                     __func__, button, move.n[0], move.n[1], x, y, delta.x, delta.y);
 
        switch (button) {
                case GLUT_LEFT_BUTTON: {
 
-               //      c3cam_eye_yaw(&cam, delta.n[0] / 4);
-               //      c3cam_eye_pitch(&cam, delta.n[1] / 4);
+//                     c3mat4 rotx = rotation3D(c3vec3f(1.0, 0, 0), delta.n[1] / 4);
+//                     c3mat4 roty = rotation3D(c3vec3f(0.0, 0.0, 1.0), delta.n[0] / 4);
 
-                       c3mat4 rotx = rotation3D(c3vec3f(1.0, 0, 0), delta.n[1] / 4);
+                       c3mat4 rotx = rotation3D(c3->cam.side, delta.n[1] / 4);
                        c3mat4 roty = rotation3D(c3vec3f(0.0, 0.0, 1.0), delta.n[0] / 4);
                        rotx = c3mat4_mul(&rotx, &roty);
-                       c3cam_rot_about_lookat(&cam, &rotx);
+                       c3cam_rot_about_lookat(&c3->cam, &rotx);
 
-                   c3cam_update_matrix(&cam);
+                   c3cam_update_matrix(&c3->cam);
                    c3->root->dirty = 1;        // resort the array
-//                 c3arcball_mouse_motion(&arcball, x, y, 0,0,0);
                }       break;
                case GLUT_RIGHT_BUTTON: {
+                       // offset both points, but following the plane
+                       c3vec3 f = c3vec3_mulf(c3vec3f(-c3->cam.side.y, c3->cam.side.x, 0), -delta.n[1] / 4);
+                       c3->cam.eye = c3vec3_add(c3->cam.eye, f);
+                       c3->cam.lookat = c3vec3_add(c3->cam.lookat, f);
+                       c3cam_movef(&c3->cam, delta.n[0] / 8, 0, 0);
 
+                   c3cam_update_matrix(&c3->cam);
+                   c3->root->dirty = 1;        // resort the array
                }       break;
        }
        move = m;
@@ -419,9 +667,6 @@ static void
 _gl_timer_cb(
                int i)
 {
-       //static int oldstate = -1;
-       // restart timer
-       c3arcball_idle(&arcball);
        glutTimerFunc(1000 / 24, _gl_timer_cb, 0);
        glutPostRedisplay();
 }
@@ -433,7 +678,7 @@ gl_init(
 {
        glutInit(&argc, argv);          /* initialize GLUT system */
 
-       glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
+       glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
        glutInitWindowSize(_w, _h);             /* width=400pixels height=500pixels */
        /*window =*/ glutCreateWindow("Press 'q' to quit");     /* create window */
 
@@ -443,8 +688,10 @@ gl_init(
 
        glutMouseFunc(_gl_button_cb);
        glutMotionFunc(_gl_motion_cb);
+    glutReshapeFunc(_gl_reshape_cb);
 
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+       glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
        /*
        glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
@@ -479,28 +726,41 @@ gl_init(
                glEnable(GL_LIGHT0);
        }
 #endif
-//     glEnable(GL_BLEND);
-       // Works for the UI !!
-//     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-       cam = c3cam_new();
-       cam.lookat = c3vec3f(100.0, 100.0, 0.0);
-    cam.eye = c3vec3f(100.0, -100.0, 100.0);
-    c3cam_update_matrix(&cam);
-
-    c3arcball_init_center(&arcball, c3vec2f(_w/2, _h/2), 100);
-//     hd44780_gl_init();
+       gl_offscreenInit(_w, _h);
+       gl_ppProgram();
 
     c3 = c3context_new(_w, _h);
     static const c3driver_context_t * list[] = { &c3context_driver, NULL };
     c3->driver = list;
 
-    c3texture_p line_aa_tex = NULL;
+       c3->cam.lookat = c3vec3f(100.0, 100.0, 0.0);
+       c3->cam.eye = c3vec3f(100.0, -100.0, 100.0);
+    c3cam_update_matrix(&c3->cam);
+
     {
-        cairo_surface_t * image = cairo_image_surface_create_from_png ("gfx/BlurryCircle.png");
+       const char *path = "gfx/hb.png";
+        cairo_surface_t * image = cairo_image_surface_create_from_png (path);
         printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
        c3texture_p b = c3texture_new(c3->root);
 
+       c3pixels_p dst = c3pixels_new(
+                       cairo_image_surface_get_width (image),
+                       cairo_image_surface_get_height (image),
+                       4, cairo_image_surface_get_stride(image),
+                       cairo_image_surface_get_data (image));
+               dst->name = str_new(path);
+       b->geometry.mat.texture = dst;
+       b->size = c3vec2f(200, 200);
+               b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
+//         c3transform_new(head);
+    }
+    c3pixels_p line_aa_tex = NULL;
+    {
+       const char *path = "gfx/BlurryCircle.png";
+        cairo_surface_t * image = cairo_image_surface_create_from_png (path);
+        printf("image = %p %p\n", image, cairo_image_surface_get_data (image));
+
+#if 0
        c3pixels_p dst = &b->pixels;
        c3pixels_init(dst,
                        cairo_image_surface_get_width (image),
@@ -508,6 +768,8 @@ gl_init(
                        1, cairo_image_surface_get_width (image),
                        NULL);
        c3pixels_alloc(dst);
+       b->size = c3vec2f(32, 32);
+       b->normalized = 1;
 
        c3pixels_p src = c3pixels_new(
                        cairo_image_surface_get_width (image),
@@ -523,56 +785,62 @@ gl_init(
                        max = _s[i] & 0xff;
        for (int i = 0; i < dst->h * dst->w; i++)
                *_d++ = ((_s[i] & 0xff) * 255) / max;// + (0xff - max);
-
-       b->geometry.dirty = 1;
-       c3mat4 i = identity3D();
-       b->geometry.mat.mode = GL_TEXTURE_2D;
        b->pixels.format = C3PIXEL_A;
-       c3geometry_project(&b->geometry, &i);
-       //_c3_geometry_project(NULL, NULL, &b->geometry, &i);
-       line_aa_tex = b;
+#else
+       c3pixels_p dst = c3pixels_new(
+                       cairo_image_surface_get_width (image),
+                       cairo_image_surface_get_height (image),
+                       4, cairo_image_surface_get_stride(image),
+                       cairo_image_surface_get_data (image));
+       dst->format = C3PIXEL_ARGB;
+       dst->normalize = 1;
+       dst->name = str_new(path);
+       uint8_t * line = dst->base;
+       for (int y = 0; y < dst->h; y++, line += dst->row) {
+               uint32_t *p = (uint32_t *)line;
+               for (int x = 0; x < dst->w; x++, p++) {
+                       uint8_t b = *p;
+                       *p = ((0xff - b) << 24);//|(b << 16)|(b << 8)|(b);
+               }
+       }
+#endif
+       line_aa_tex = dst;
 
-       c3pixels_p p = &b->pixels;
+       c3pixels_p p = dst;
        printf("struct { int w, h, stride, size, format; uint8_t pix[] } img = {\n"
                        "%d, %d, %d, %d, %d\n",
                        p->w, p->h, (int)p->row, p->psize, cairo_image_surface_get_format(image));
        for (int i = 0; i < 32; i++)
-               printf("0x%08x", ((uint32_t*)src->base)[i]);
+               printf("0x%08x ", ((uint32_t*)p->base)[i]);
        printf("\n");
     }
     c3object_p grid = c3object_new(c3->root);
     {
-        for (int x = 0; x < 20; x++) {
-               for (int y = 0; y < 20; y++) {
+        for (int x = 0; x <= 20; x++) {
+               for (int y = 0; y <= 20; y++) {
                        c3vec3 p[4] = {
-                               c3vec3f(-1+x*10,y*10,0), c3vec3f(1+x*10,y*10,0),
-                               c3vec3f(x*10,-1+y*10,0), c3vec3f(x*10,1+y*10,0),
+                               c3vec3f(-1+x*10,y*10,0.01), c3vec3f(1+x*10,y*10,0.01),
+                               c3vec3f(x*10,-1+y*10,0.02), c3vec3f(x*10,1+y*10,0.02),
                        };
                c3geometry_p g = c3geometry_new(
                                c3geometry_type(C3_LINES_TYPE, 0), grid);
-               g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
-               g->mat.texture = line_aa_tex->geometry.mat.texture;
-               g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
-               g->texture = 1;
-                       c3vertex_array_insert(&g->vertice,
-                                       g->vertice.count, p, 4);
+               g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
+               g->mat.texture = line_aa_tex;
+                       c3lines_init(g, p, 4, 0.2);
                }
         }
     }
 
-    {
+   if (0) {
                c3vec3 p[4] = {
-                       c3vec3f(-5,-5,0), c3vec3f(205,-5,0),
+                       c3vec3f(-5,-5,1), c3vec3f(205,-5,1),
                };
        c3geometry_p g = c3geometry_new(
                        c3geometry_type(C3_LINES_TYPE, 0), grid);
-       g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
-       g->mat.texture = line_aa_tex->geometry.mat.texture;
-       g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
-//     g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
-       g->texture = 1;
+       g->mat.color = c3vec4f(0.0, 0.0, 0.0, 1.0);
+       g->mat.texture = line_aa_tex;
+       g->line.width = 2;
 
-       printf("AA texture is %d\n", line_aa_tex->geometry.mat.texture);
                c3vertex_array_insert(&g->vertice,
                                g->vertice.count, p, 2);
 
@@ -594,20 +862,34 @@ gl_init(
 
     hud = c3context_new(_w, _h);
     hud->driver = list;
+    /*
+     * This is the offscreen framebuffer where the 3D scene is drawn
+     */
+    if (program_postproc) {
+       c3texture_p b = c3texture_new(hud->root);
+
+       c3pixels_p dst = c3pixels_new(_w, _h, 4, _w * 4, NULL);
+               dst->name = str_new("fbo");
+               dst->texture = fbo_texture;
+               dst->normalize = 1;
+               dst->dirty = 0;
+       //      dst->trace = 1;
+       b->geometry.mat.texture = dst;
+       b->geometry.mat.program.pid = program_postproc;
+       b->size = c3vec2f(_w, _h);
+               b->geometry.mat.color = c3vec4f(1.0, 1.0, 1.0, 1.0);
+               fbo_c3 = b;
+    }
 
     {
                c3vec3 p[4] = {
-                       c3vec3f(10,10,0), c3vec3f(700,40,0),
+                       c3vec3f(10,10,0), c3vec3f(800-10,10,0),
                };
        c3geometry_p g = c3geometry_new(
                        c3geometry_type(C3_LINES_TYPE, 0), hud->root);
-       g->mat.color = c3vec4f(0.0, 0.0, 0.0, 0.8);
-       g->mat.texture = line_aa_tex->geometry.mat.texture;
-       g->mat.mode = GL_TEXTURE_2D;//GL_TEXTURE_RECTANGLE_ARB;
-//     g->mat.mode = GL_TEXTURE_RECTANGLE_ARB;
-       g->texture = 1;
-               c3vertex_array_insert(&g->vertice,
-                               g->vertice.count, p, 2);
+       g->mat.color = c3vec4f(0.5, 0.5, 1.0, .3f);
+       g->mat.texture = line_aa_tex;
+               c3lines_init(g, p, 2, 10);
     }
        return 1;
 }
diff --git a/examples/shared/libc3/Makefile b/examples/shared/libc3/Makefile
new file mode 100644 (file)
index 0000000..25ab1db
--- /dev/null
@@ -0,0 +1,80 @@
+
+VERSION                = 0.1.0
+REVISION       = 1
+
+SHELL          := ${shell which bash}
+
+IPATH          += src
+VPATH          += src
+
+OBJ            = obj-${shell $(CC) -dumpmachine}
+
+C3SRC          = ${wildcard src/*.c}
+C3OBJ          = ${patsubst src/%,${OBJ}/%,${C3SRC:.c=.lo}}
+
+CC                     = clang
+PKGCONFIG      = pkg-config
+LIBTOOL                = libtool
+INSTALL                = install
+
+CFLAGS         = -g -O2
+CPPFLAGS       += --std=gnu99 -fPIC
+CPPFLAGS       += ${patsubst %,-I%,${subst :, ,${IPATH}}}
+CPPFLAGS       += ${shell $(PKGCONFIG) --cflags pango cairo}
+
+LDFLAGS                += 
+
+DESTDIR                = /usr/local
+
+-include ${wildcard .make.options*}
+
+all:   ${OBJ} src/c3config.h ${OBJ}/libc3.la
+
+${OBJ}:
+       mkdir -p ${OBJ}
+
+ifneq (${V}, 1)
+E=@
+LIBTOOL += --quiet
+endif
+
+src/c3config.h:
+       $(E)rm -f $@
+       $(E)echo CONFIG $@
+       $(E)( \
+       printf "#ifndef __C3_CONFIG__\n#define __C3_CONFIG__\n"; \
+       printf "#define CONFIG_C3_VERSION \"$(VERSION)\"\n"; \
+       $(PKGCONFIG) --exists pango cairo || printf "// " ; \
+               printf "#define CONFIG_C3_CAIRO 1\n"; \
+       printf "#endif\n"; \
+       ) >$@
+
+${OBJ}/libc3.la: ${C3OBJ}
+       @echo LINK $@
+       $(E)$(LIBTOOL) --mode=link --tag=CC \
+               $(CC) $(CPPFLAGS) $(CFLAGS) \
+                       $^ -o $@ \
+                       -version-info 0:1:0 \
+                       -rpath $(DESTDIR)/lib $(LDFLAGS)
+
+${OBJ}/%.lo: src/c3config.h
+${OBJ}/%.lo: %.c
+       @echo CC $<
+       $(E)$(LIBTOOL) --mode=compile --tag=CC \
+               $(CC) $(CPPFLAGS) $(CFLAGS) -MT $@ -MMD \
+                       $<  -c -o $@
+
+install:
+       mkdir -p $(DESTDIR)/lib/pkgconfig $(DESTDIR)/include/c3
+       rm -f $(DESTDIR)/lib/libc3* $(DESTDIR)/include/c3/*
+       $(INSTALL) src/*.h $(DESTDIR)/include/c3/
+       cp -a ${OBJ}/.libs/*.a ${OBJ}/.libs/*.so* $(DESTDIR)/lib/
+       sed -e 's|PREFIX|${DESTDIR}|g' -e 's|VERSION|${VERSION}|g' \
+               libc3.pc >$(DESTDIR)/lib/pkgconfig/libc3.pc 
+        
+clean:
+       rm -rf ${OBJ}
+
+# include the dependency files generated by gcc, if any
+-include ${wildcard ${OBJ}/*.d}
\ No newline at end of file
diff --git a/examples/shared/libc3/README.md b/examples/shared/libc3/README.md
new file mode 100644 (file)
index 0000000..31207ab
--- /dev/null
@@ -0,0 +1,77 @@
+libc3 - No frill 'scene' graph library in C
+=====
+(C) 2012 Michel Pollet <buserror@gmail.com>
+
+**WARNING** This API is not your nanny. It is made to be lean, mean, efficient
+with no frill, no asserts, no bounds checking, no sugar coating.
+
+On the other hand it's fast, reasonably clean and is a micro-fraction of the
+other giganormous 'scene graphs' or 'game engine' libraries around.
+
+It's vaguely inspired by THREE.js funnily enough, because it allows you to
+hack around and quickly get stuff on screen with the minimal amount of 
+effort.
+
+The API has various bits:
+* c3algebra: C derivative of an old C++ piece of code I had lying around and that has
+been present in my toolset for a long time. It gives you *vectors* (c3vec2, c3vec3, c3vec4)
+and *matrices* (c3mat3, c3mat4) with various tools to manipulate them.
+* c3quaternion: Quaternion implementation using c3algebra
+* c3camera/c3arcball: camera manipulation, not perfect
+
+The basic data structure is as follow:
+* *c3context*:
+       Mostly placeholder for now, hosts a "root" object, can reproject the
+       objects & geometry, and call the callbacks to draw them.
+* *c3object*: 
+       * Has a list of (sub) c3objects
+       * Has a list of c3transforms (ie matrices)
+       * Has a list of c3geometry (ie real vertices and stuff)
+  The object is a container for other objects, and for geometry itself. Objects don't
+  necessary have geometry and/or sub objects, and don't even need transforms if their
+  vertices are already projected.
+* *c3geometry*:
+       * Has a 'type' (raw for simple vertices, texture, triangles etc)
+       * Has a 'subtype' (mostly can be used to draw GL types)
+       * Has a 'material' (ie color, texture... to be completed)
+       * Has a list of vertices
+       * Has a list of texture coordinates (optional)
+       * Has a list of vertices colors (optional)
+       * Has a cached copy of a vertices when it has been 'projected'
+* *c3transform*:
+       Is just a sugar coated matrix, with an optional name.
+
+Also there are:
+* *c3pixels*:
+       Is just a wrapper/holder for some pixels, either allocated, or inherited, 
+       it's mostly used for *c3texture*
+* *c3texture*:
+       Associates a *c3geometry* with a *c3pixels* and has a standard Quad
+       for vertices. The OpenGL drawing is not done there, it's done by the application using
+       the generic *c3context* driver.
+* *c3cairo*:
+       Placeholder for now, inherits from *c3texture* and will contain a
+       cairo surface mapped to a GL texture.
+* *c3pango*:
+       A text label, inherits from *c3cairo*
+
+Draw Drivers "Inheritance"
+------------
+Various object uses static tables of callbacks to implement their behaviours
+it's kinda cheap c++ inheritance, without the usual bloat.
+
+There just a couple macros to call the driver chain for a particular function call.
+The relevant bits are in c3driver*.h.
+
+Mostly the code looks for a matching callback in a static table, and call it if found.
+If that callback wants, it can also call the inherited object callback too.
+
+Dirtyness
+---------
+There is a notion of 'dirtyness' in the tree, when you touch a *c3transform*, and/remove
+objects and geometry, a dirty bit is propagated up the tree of object. This tells the
+rendering it needs to reproject the dirty bits and repopulate the projected vertice
+cache.
+
+The 'dirty' bit moves both ways, when setting a dirty bit to true, it propagates upward,
+when you set it to false, it propagates downward in the tree.
diff --git a/examples/shared/libc3/libc3.pc b/examples/shared/libc3/libc3.pc
new file mode 100644 (file)
index 0000000..3413e95
--- /dev/null
@@ -0,0 +1,12 @@
+libc3.pc:
+prefix=PREFIX
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+
+Name: libc3
+Description: Lightweight scene graph library in C 
+Version: VERSION
+Cflags: -I${includedir}
+Requires.private: pangocairo
+Libs: -L${libdir} -llibc3
diff --git a/examples/shared/libc3/src/c3.c b/examples/shared/libc3/src/c3.c
new file mode 100644 (file)
index 0000000..38fcf83
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+       c3.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3.h"
+
diff --git a/examples/shared/libc3/src/c3.h b/examples/shared/libc3/src/c3.h
new file mode 100644 (file)
index 0000000..190ba23
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+       c3.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3_H___
+#define __C3_H___
+
+#include "c3context.h"
+#include "c3object.h"
+#include "c3geometry.h"
+#include "c3transform.h"
+#include "c3texture.h"
+
+#endif /* __C3_H___ */
diff --git a/examples/shared/libc3/src/c3algebra.c b/examples/shared/libc3/src/c3algebra.c
new file mode 100644 (file)
index 0000000..b47525d
--- /dev/null
@@ -0,0 +1,1008 @@
+/*
+       c3algebra.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       Derivative and inspiration from original C++:
+       Paul Rademacher & Jean-Francois DOUEG,
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <math.h>
+#include <string.h>
+#include "c3algebra.h"
+
+#ifndef MAX
+#define MAX(a,b)  ((a)>(b) ? (a) : (b))
+#define MIN(a,b)  ((a)<(b) ? (a) : (b))
+#endif
+
+/****************************************************************
+ *                                                              *
+ *          c3vec2 Member functions                             *
+ *                                                              *
+ ****************************************************************/
+
+/******************** c3vec2 CONSTRUCTORS ********************/
+
+c3vec2 c3vec2_zero()
+{
+       c3vec2 n;// = { .x = 0, .y = 0 };// older gcc <4.6 doesn't like this
+       n.x = n.y = 0;
+    return n;
+}
+
+c3vec2 c3vec2f(c3f x, c3f y)
+{
+       c3vec2 v;// = { .x = x, .y = y };// older gcc <4.6 doesn't like this
+       v.x = x; v.y = y;
+       return v;
+}
+
+/******************** c3vec2 ASSIGNMENT OPERATORS ******************/
+
+c3vec2  c3vec2_add(c3vec2 a, const c3vec2 v)
+{
+    a.n[VX] += v.n[VX];
+    a.n[VY] += v.n[VY];
+    return a;
+}
+
+c3vec2  c3vec2_sub(c3vec2 a, const c3vec2 v)
+{
+    a.n[VX] -= v.n[VX];
+    a.n[VY] -= v.n[VY];
+    return a;
+}
+
+c3vec2 c3vec2_mulf(c3vec2 a, c3f d)
+{
+    a.n[VX] *= d;
+    a.n[VY] *= d;
+    return a;
+}
+
+c3vec2 c3vec2_divf(c3vec2 a, c3f d)
+{
+    c3f d_inv = 1.0f/d;
+    a.n[VX] *= d_inv;
+    a.n[VY] *= d_inv;
+    return a;
+}
+
+/******************** c3vec2 SPECIAL FUNCTIONS ********************/
+
+
+c3f c3vec2_length2(const c3vec2 a)
+{
+    return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY];
+}
+
+c3f c3vec2_length(const c3vec2 a)
+{
+    return (c3f) sqrt(c3vec2_length2(a));
+}
+
+c3vec2 c3vec2_normalize(const c3vec2 a) // it is up to caller to avoid divide-by-zero
+{
+    return c3vec2_divf(a, c3vec2_length(a));
+}
+
+c3vec2 c3vec2_apply(c3vec2 a, V_FCT_PTR fct)
+{
+    a.n[VX] = fct(a.n[VX]);
+    a.n[VY] = fct(a.n[VY]);
+    return a;
+}
+
+
+/******************** c3vec2 FRIENDS *****************************/
+
+c3vec2 c3vec2_minus(const c3vec2 a)
+{
+    return c3vec2f(-a.n[VX],-a.n[VY]);
+}
+
+c3vec2 c3mat3_mulv2(const c3mat3p a, const c3vec2 v)
+{
+  c3vec2 av;
+
+  av.n[VX] = a->v[0].n[VX]*v.n[VX] + a->v[0].n[VY]*v.n[VY] + a->v[0].n[VZ];
+  av.n[VY] = a->v[1].n[VX]*v.n[VX] + a->v[1].n[VY]*v.n[VY] + a->v[1].n[VZ];
+//  av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
+
+  return av;
+}
+
+c3vec2 c3vec2_mulm3(const c3vec2 v, const c3mat3p a)
+{
+       c3mat3 t = c3mat3_transpose(a);
+    return c3mat3_mulv2(&t, v);
+}
+
+c3vec3 c3mat3_mulv3(const c3mat3p a, const c3vec3 v)
+{
+    c3vec3 av;
+
+    av.n[VX] = a->v[0].n[VX]*v.n[VX] + a->v[0].n[VY]*v.n[VY] + a->v[0].n[VZ]*v.n[VZ];
+    av.n[VY] = a->v[1].n[VX]*v.n[VX] + a->v[1].n[VY]*v.n[VY] + a->v[1].n[VZ]*v.n[VZ];
+    av.n[VZ] = a->v[2].n[VX]*v.n[VX] + a->v[2].n[VY]*v.n[VY] + a->v[2].n[VZ]*v.n[VZ];
+
+    return av;
+}
+
+c3vec3 c3vec3_mulm3(const c3vec3 v, const c3mat3p a)
+{
+       c3mat3 t = c3mat3_transpose(a);
+    return c3mat3_mulv3(&t, v);
+}
+
+c3f c3vec2_dot(const c3vec2 a, const c3vec2 b)
+{
+    return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY];
+}
+
+c3vec3 c3vec2_cross(const c3vec2 a, const c3vec2 b)
+{
+    return c3vec3f(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]);
+}
+
+int c3vec2_equal(const c3vec2 a, const c3vec2 b)
+{
+    return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]);
+}
+
+
+c3vec2 c3vec2_min(const c3vec2 a, const c3vec2 b)
+{
+    return c3vec2f(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY]));
+}
+
+c3vec2 c3vec2_max(const c3vec2 a, const c3vec2 b)
+{
+    return c3vec2f(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY]));
+}
+
+c3vec2 c3vec2_prod(const c3vec2 a, const c3vec2 b)
+{
+    return c3vec2f(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]);
+}
+
+/****************************************************************
+ *                                                              *
+ *          c3vec3 Member functions                               *
+ *                                                              *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+c3vec3 c3vec3_zero()
+{
+       c3vec3 n;// = { .x = 0, .y = 0, .z = 0 };// older gcc <4.6 doesn't like this
+       n.x = n.y = n.z = 0;
+    return n;
+}
+
+c3vec3 c3vec3f(c3f x, c3f y, c3f z)
+{
+       c3vec3 v;// = { .x = x, .y = y, .z = z };// older gcc <4.6 doesn't like this
+       v.x = x; v.y = y; v.z = z;
+       return v;
+}
+
+c3vec3 c3vec3_vec2f(const c3vec2 v, c3f d)
+{
+       c3vec3 n;// = { .x = v.x, .y = v.y, .z = d }; // older gcc <4.6 doesn't like this
+       n.x = v.x; n.y = v.y; n.z = d;
+       return n;
+}
+
+c3vec3 c3vec3_vec2(const c3vec2 v)
+{
+       return c3vec3_vec2f(v, 1.0);
+}
+
+c3vec3 c3vec3_vec4(const c3vec4 v) // it is up to caller to avoid divide-by-zero
+{
+       c3vec3 n;
+    n.n[VX] = v.n[VX] / v.n[VW];
+    n.n[VY] = v.n[VY] / v.n[VW];
+    n.n[VZ] = v.n[VZ] / v.n[VW];
+    return n;
+}
+
+
+c3vec3 c3vec3_add(c3vec3 a, const c3vec3 v)
+{
+    a.n[VX] += v.n[VX];
+    a.n[VY] += v.n[VY];
+    a.n[VZ] += v.n[VZ];
+    return a;
+}
+
+c3vec3 c3vec3_sub(c3vec3 a, const c3vec3 v)
+{
+       a.n[VX] -= v.n[VX];
+       a.n[VY] -= v.n[VY];
+       a.n[VZ] -= v.n[VZ];
+    return a;
+}
+
+c3vec3 c3vec3_mulf(c3vec3 a, c3f d)
+{
+       a.n[VX] *= d;
+       a.n[VY] *= d;
+       a.n[VZ] *= d;
+    return a;
+}
+
+c3vec3 c3vec3_divf(c3vec3 a, c3f d)
+{
+    c3f d_inv = 1.0f/d;
+    a.n[VX] *= d_inv;
+    a.n[VY] *= d_inv;
+    a.n[VZ] *= d_inv;
+    return a;
+}
+
+// SPECIAL FUNCTIONS
+
+c3f c3vec3_length2(const c3vec3 a)
+{
+    return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY] + a.n[VZ]*a.n[VZ];
+}
+
+c3f c3vec3_length(const c3vec3 a)
+{
+    return (c3f) sqrt(c3vec3_length2(a));
+}
+
+c3vec3 c3vec3_normalize(const c3vec3 a) // it is up to caller to avoid divide-by-zero
+{
+    return c3vec3_divf(a, c3vec3_length(a));
+}
+
+c3vec3 c3vec3_homogenize(c3vec3 a) // it is up to caller to avoid divide-by-zero
+{
+    a.n[VX] /= a.n[VZ];
+    a.n[VY] /= a.n[VZ];
+    a.n[VZ] = 1.0;
+    return a;
+}
+
+c3vec3 c3vec3_apply(c3vec3 a, V_FCT_PTR fct)
+{
+    a.n[VX] = fct(a.n[VX]);
+    a.n[VY] = fct(a.n[VY]);
+    a.n[VZ] = fct(a.n[VZ]);
+    return a;
+}
+
+// FRIENDS
+
+c3vec3 c3vec3_minus(const c3vec3 a)
+{
+    return c3vec3f(-a.n[VX],-a.n[VY],-a.n[VZ]);
+}
+
+#if later
+c3vec3 operator*(const c3mat4 &a, const c3vec3 &v)
+{
+    return a*c3vec4(v);
+}
+
+c3vec3 operator*(const c3vec3 &v, c3mat4 &a)
+{
+    return a.transpose()*v;
+}
+#endif
+
+c3f c3vec3_dot(const c3vec3 a, const c3vec3 b)
+{
+    return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ];
+}
+
+c3vec3 c3vec3_cross(const c3vec3 a, const c3vec3 b)
+{
+    return
+        c3vec3f(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
+             a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
+             a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
+}
+
+int c3vec3_equal(const c3vec3 a, const c3vec3 b)
+{
+    return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
+}
+
+
+c3vec3 c3vec3_min(const c3vec3 a, const c3vec3 b)
+{
+    return c3vec3f(
+        MIN(a.n[VX], b.n[VX]),
+        MIN(a.n[VY], b.n[VY]),
+        MIN(a.n[VZ], b.n[VZ]));
+}
+
+c3vec3 c3vec3_max(const c3vec3 a, const c3vec3 b)
+{
+    return c3vec3f(
+        MAX(a.n[VX], b.n[VX]),
+        MAX(a.n[VY], b.n[VY]),
+        MAX(a.n[VZ], b.n[VZ]));
+}
+
+c3vec3 c3vec3_prod(const c3vec3 a, const c3vec3 b)
+{
+    return c3vec3f(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]);
+}
+
+/****************************************************************
+ *                                                              *
+ *          c3vec4 Member functions                               *
+ *                                                              *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+c3vec4 c3vec4_zero()
+{
+       c3vec4 n ;//= { .x = 0, .y = 0, .z = 0, .w = 1.0 }; // older gcc <4.6 doesn't like this
+       n.x = n.y = n.z = 0; n.w = 1.0;
+    return n;
+}
+
+c3vec4 c3vec4f(c3f x, c3f y, c3f z, c3f w)
+{
+       c3vec4 n;// = { .x = x, .y = y, .z = z, .w = w }; // older gcc <4.6 doesn't like this
+       n.x =x;  n.y = y; n.z = z; n.w = w;
+    return n;
+}
+
+c3vec4 c3vec4_vec3(const c3vec3 v)
+{
+       return c3vec4f(v.n[VX], v.n[VY], v.n[VZ], 1.0);
+}
+
+c3vec4 c3vec4_vec3f(const c3vec3 v, c3f d)
+{
+       return c3vec4f(v.n[VX], v.n[VY], v.n[VZ], d);
+}
+
+// ASSIGNMENT OPERATORS
+
+c3vec4 c3vec4_add(c3vec4 a, const c3vec4 v)
+{
+    a.n[VX] += v.n[VX];
+    a.n[VY] += v.n[VY];
+    a.n[VZ] += v.n[VZ];
+    a.n[VW] += v.n[VW];
+    return a;
+}
+
+c3vec4 c3vec4_sub(c3vec4 a, const c3vec4 v)
+{
+       a.n[VX] -= v.n[VX];
+       a.n[VY] -= v.n[VY];
+       a.n[VZ] -= v.n[VZ];
+       a.n[VW] -= v.n[VW];
+    return a;
+}
+
+c3vec4 c3vec4_mulf(c3vec4 a, c3f d)
+{
+    a.n[VX] *= d;
+    a.n[VY] *= d;
+    a.n[VZ] *= d;
+    a.n[VW] *= d;
+    return a;
+}
+
+c3vec4 c3vec4_divf(c3vec4 a, c3f d)
+{
+    c3f d_inv = 1.0f/d;
+    a.n[VX] *= d_inv;
+    a.n[VY] *= d_inv;
+    a.n[VZ] *= d_inv;
+    a.n[VW] *= d_inv;
+    return a;
+}
+
+// SPECIAL FUNCTIONS
+
+c3f c3vec4_length2(const c3vec4 a)
+{
+    return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY] + a.n[VZ]*a.n[VZ] + a.n[VW]*a.n[VW];
+}
+
+c3f c3vec4_length(const c3vec4 a)
+{
+    return (c3f) sqrt(c3vec4_length2(a));
+}
+
+c3vec4 c3vec4_normalize(c3vec4 a) // it is up to caller to avoid divide-by-zero
+{
+    return c3vec4_divf(a, c3vec4_length(a));
+}
+
+c3vec4 c3vec4_homogenize(c3vec4 a) // it is up to caller to avoid divide-by-zero
+{
+    a.n[VX] /= a.n[VW];
+    a.n[VY] /= a.n[VW];
+    a.n[VZ] /= a.n[VW];
+    a.n[VW] = 1.0;
+    return a;
+}
+
+c3vec4 c3vec4_apply(c3vec4 a, V_FCT_PTR fct)
+{
+    a.n[VX] = fct(a.n[VX]);
+    a.n[VY] = fct(a.n[VY]);
+    a.n[VZ] = fct(a.n[VZ]);
+    a.n[VW] = fct(a.n[VW]);
+    return a;
+}
+
+c3vec4 c3mat4_mulv4(const c3mat4p a, const c3vec4 v)
+{
+    #define ROWCOL(i) \
+        a->v[i].n[0]*v.n[VX] + \
+        a->v[i].n[1]*v.n[VY] + \
+        a->v[i].n[2]*v.n[VZ] + \
+        a->v[i].n[3]*v.n[VW]
+
+    return c3vec4f(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
+
+    #undef ROWCOL
+}
+
+c3vec4 c3vec4_mulm4(const c3vec4 v, const c3mat4p a)
+{
+       c3mat4 m = c3mat4_transpose(a);
+    return c3mat4_mulv4(&m, v);
+}
+
+c3vec3 c3mat4_mulv3(const c3mat4p a, const c3vec3 v)
+{
+       return c3vec3_vec4(c3mat4_mulv4(a, c3vec4_vec3(v)));
+}
+
+c3vec4 c3vec4_minus(const c3vec4 a)
+{
+    return c3vec4f(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
+}
+
+int c3vec4_equal(const c3vec4 a, const c3vec4 b)
+{
+    return
+        (a.n[VX] == b.n[VX]) &&
+        (a.n[VY] == b.n[VY]) &&
+        (a.n[VZ] == b.n[VZ]) &&
+        (a.n[VW] == b.n[VW]);
+}
+
+c3vec4 c3vec4_min(const c3vec4 a, const c3vec4 b)
+{
+    return c3vec4f(
+        MIN(a.n[VX], b.n[VX]),
+        MIN(a.n[VY], b.n[VY]),
+        MIN(a.n[VZ], b.n[VZ]),
+        MIN(a.n[VW], b.n[VW]));
+}
+
+c3vec4 c3vec4_max(const c3vec4 a, const c3vec4 b)
+{
+    return c3vec4f(
+        MAX(a.n[VX], b.n[VX]),
+        MAX(a.n[VY], b.n[VY]),
+        MAX(a.n[VZ], b.n[VZ]),
+        MAX(a.n[VW], b.n[VW]));
+}
+
+c3vec4 c3vec4_prod(const c3vec4 a, const c3vec4 b)
+{
+    return c3vec4f(
+        a.n[VX] * b.n[VX],
+        a.n[VY] * b.n[VY],
+        a.n[VZ] * b.n[VZ],
+        a.n[VW] * b.n[VW]);
+}
+
+/****************************************************************
+ *                                                              *
+ *          c3mat3 member functions                               *
+ *                                                              *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+c3mat3 c3mat3_identity()
+{
+       return identity2D();
+}
+
+c3mat3 c3mat3_vec3(const c3vec3 v0, const c3vec3 v1, const c3vec3 v2)
+{
+       c3mat3 m = { .v[0] = v0, .v[1] = v1, .v[2] = v2 };
+       return m;
+}
+
+c3mat3p c3mat3_add(const c3mat3p a, const c3mat3p m)
+{
+       a->v[0] = c3vec3_add(a->v[0], m->v[0]);
+       a->v[1] = c3vec3_add(a->v[1], m->v[1]);
+       a->v[2] = c3vec3_add(a->v[2], m->v[2]);
+    return a;
+}
+
+c3mat3p c3mat3_sub(const c3mat3p a, const c3mat3p m)
+{
+       a->v[0] = c3vec3_sub(a->v[0], m->v[0]);
+       a->v[1] = c3vec3_sub(a->v[1], m->v[1]);
+       a->v[2] = c3vec3_sub(a->v[2], m->v[2]);
+    return a;
+}
+
+c3mat3p c3mat3_mulf(const c3mat3p a, c3f d)
+{
+       a->v[0] = c3vec3_mulf(a->v[0], d);
+       a->v[1] = c3vec3_mulf(a->v[1], d);
+       a->v[2] = c3vec3_mulf(a->v[2], d);
+    return a;
+}
+
+c3mat3p c3mat3_divf(const c3mat3p a, c3f d)
+{
+       a->v[0] = c3vec3_divf(a->v[0], d);
+       a->v[1] = c3vec3_divf(a->v[1], d);
+       a->v[2] = c3vec3_divf(a->v[2], d);
+    return a;
+}
+
+// SPECIAL FUNCTIONS
+
+c3mat3 c3mat3_transpose(const c3mat3p a)
+{
+    return c3mat3_vec3(
+        c3vec3f(a->v[0].n[0], a->v[1].n[0], a->v[2].n[0]),
+        c3vec3f(a->v[0].n[1], a->v[1].n[1], a->v[2].n[1]),
+        c3vec3f(a->v[0].n[2], a->v[1].n[2], a->v[2].n[2]));
+}
+
+c3mat3 c3mat3_inverse(const c3mat3p m)   // Gauss-Jordan elimination with partial pivoting
+{
+       c3mat3 a = *m; // As a evolves from original mat into identity
+       c3mat3 b = c3mat3_identity(); // b evolves from identity into inverse(a)
+       int i, j, i1;
+
+       // Loop over cols of a from left to right, eliminating above and below diag
+       for (j = 0; j < 3; j++) { // Find largest pivot in column j among rows j..2
+               i1 = j; // Row with largest pivot candidate
+               for (i = j + 1; i < 3; i++)
+                       if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
+                               i1 = i;
+
+               // Swap rows i1 and j in a and b to put pivot on diagonal
+               c3vec3 _s;
+               _s = a.v[i1]; a.v[i1] = a.v[j]; a.v[j] = _s;  // swap(a.v[i1], a.v[j]);
+               _s = b.v[i1]; b.v[i1] = b.v[j]; b.v[j] = _s;  //swap(b.v[i1], b.v[j]);
+
+               // Scale row j to have a unit diagonal
+               if (a.v[j].n[j] == 0.) {
+               //      VEC_ERROR("c3mat3::inverse: singular matrix; can't invert\n");
+                       return *m;
+               }
+
+               b.v[j] = c3vec3_divf(b.v[j], a.v[j].n[j]);
+               a.v[j] = c3vec3_divf(a.v[j], a.v[j].n[j]);
+
+               // Eliminate off-diagonal elems in col j of a, doing identical ops to b
+               for (i = 0; i < 3; i++)
+                       if (i != j) {
+                               b.v[i] = c3vec3_sub(b.v[i], c3vec3_mulf(b.v[j], a.v[i].n[j]));
+                               a.v[i] = c3vec3_sub(a.v[i], c3vec3_mulf(a.v[j], a.v[i].n[j]));
+                       }
+       }
+
+       return b;
+}
+
+c3mat3p c3mat3_apply(c3mat3p a, V_FCT_PTR fct)
+{
+       a->v[0] = c3vec3_apply(a->v[0], fct);
+       a->v[1] = c3vec3_apply(a->v[1], fct);
+       a->v[2] = c3vec3_apply(a->v[2], fct);
+    return a;
+}
+
+
+c3mat3 c3mat3_minus(const c3mat3p a)
+{
+    return c3mat3_vec3(
+               c3vec3_minus(a->v[0]),
+               c3vec3_minus(a->v[1]),
+               c3vec3_minus(a->v[2]));
+}
+
+c3mat3 c3mat3_mul(const c3mat3p a, const c3mat3p b)
+{
+    #define ROWCOL(i, j) \
+    a->v[i].n[0]*b->v[0].n[j] + a->v[i].n[1]*b->v[1].n[j] + a->v[i].n[2]*b->v[2].n[j]
+
+    return c3mat3_vec3(
+        c3vec3f(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
+        c3vec3f(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
+        c3vec3f(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
+
+    #undef ROWCOL
+}
+
+int c3mat3_equal(const c3mat3p a, const c3mat3p b)
+{
+    return
+        c3vec3_equal(a->v[0], b->v[0]) &&
+        c3vec3_equal(a->v[1], b->v[1]) &&
+        c3vec3_equal(a->v[2], b->v[2]);
+}
+
+/****************************************************************
+ *                                                              *
+ *          c3mat4 member functions                               *
+ *                                                              *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+c3mat4 c3mat4_identity()
+{
+    return identity3D();
+}
+
+c3mat4 c3mat4_vec4(const c3vec4 v0, const c3vec4 v1, const c3vec4 v2, const c3vec4 v3)
+{
+       c3mat4 m = { .v[0] = v0, .v[1] = v1, .v[2] = v2, .v[3] = v3 };
+       return m;
+}
+
+c3mat4 c3mat4f(
+     c3f a00, c3f a01, c3f a02, c3f a03,
+     c3f a10, c3f a11, c3f a12, c3f a13,
+     c3f a20, c3f a21, c3f a22, c3f a23,
+     c3f a30, c3f a31, c3f a32, c3f a33 )
+{
+       c3mat4 m;
+       m.v[0] = c3vec4f(a00, a01, a01, a03);
+       m.v[1] = c3vec4f(a10, a11, a11, a13);
+       m.v[2] = c3vec4f(a20, a21, a21, a23);
+       m.v[3] = c3vec4f(a30, a31, a21, a33);
+       return m;
+}
+
+c3mat4p c3mat4p_add(c3mat4p a, const c3mat4p m)
+{
+    a->v[0] = c3vec4_add(a->v[0], m->v[0]);
+    a->v[1] = c3vec4_add(a->v[1], m->v[1]);
+    a->v[2] = c3vec4_add(a->v[2], m->v[2]);
+    a->v[3] = c3vec4_add(a->v[3], m->v[3]);
+    return a;
+}
+
+c3mat4p c3mat4p_sub(c3mat4p a, const c3mat4p m)
+{
+    a->v[0] = c3vec4_sub(a->v[0], m->v[0]);
+    a->v[1] = c3vec4_sub(a->v[1], m->v[1]);
+    a->v[2] = c3vec4_sub(a->v[2], m->v[2]);
+    a->v[3] = c3vec4_sub(a->v[3], m->v[3]);
+    return a;
+}
+
+c3mat4p c3mat4p_mulf(c3mat4p a, c3f d)
+{
+    a->v[0] = c3vec4_mulf(a->v[0], d);
+    a->v[1] = c3vec4_mulf(a->v[1], d);
+    a->v[2] = c3vec4_mulf(a->v[2], d);
+    a->v[3] = c3vec4_mulf(a->v[3], d);
+    return a;
+}
+
+c3mat4p c3mat4p_divf(c3mat4p a, c3f d)
+{
+    a->v[0] = c3vec4_divf(a->v[0], d);
+    a->v[1] = c3vec4_divf(a->v[1], d);
+    a->v[2] = c3vec4_divf(a->v[2], d);
+    a->v[3] = c3vec4_divf(a->v[3], d);
+    return a;
+}
+
+// SPECIAL FUNCTIONS;
+
+c3mat4 c3mat4_transpose(const c3mat4p a)
+{
+    return c3mat4_vec4(
+        c3vec4f(a->v[0].n[0], a->v[1].n[0], a->v[2].n[0], a->v[3].n[0]),
+        c3vec4f(a->v[0].n[1], a->v[1].n[1], a->v[2].n[1], a->v[3].n[1]),
+        c3vec4f(a->v[0].n[2], a->v[1].n[2], a->v[2].n[2], a->v[3].n[2]),
+        c3vec4f(a->v[0].n[3], a->v[1].n[3], a->v[2].n[3], a->v[3].n[3]));
+}
+
+c3mat4 c3mat4_inverse(const c3mat4p m)       // Gauss-Jordan elimination with partial pivoting
+{
+       c3mat4 a = *m; // As a evolves from original mat into identity
+       c3mat4 b = identity3D(); // b evolves from identity into inverse(a)
+       int i, j, i1;
+
+       // Loop over cols of a from left to right, eliminating above and below diag
+       for (j = 0; j < 4; j++) { // Find largest pivot in column j among rows j..3
+               i1 = j; // Row with largest pivot candidate
+               for (i = j + 1; i < 4; i++)
+                       if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
+                               i1 = i;
+
+               // Swap rows i1 and j in a and b to put pivot on diagonal
+               c3vec4 _s;
+               _s = a.v[i1]; a.v[i1] = a.v[j]; a.v[j] = _s; // swap(a.v[i1], a.v[j]);
+               _s = b.v[i1]; b.v[i1] = b.v[j]; b.v[j] = _s; // swap(b.v[i1], b.v[j]);
+
+               // Scale row j to have a unit diagonal
+               if (a.v[j].n[j] == 0.) {
+                       //    VEC_ERROR("c3mat4::inverse: singular matrix; can't invert\n");
+                       return a;
+               }
+               b.v[j] = c3vec4_divf(b.v[j], a.v[j].n[j]);
+               a.v[j] = c3vec4_divf(a.v[j], a.v[j].n[j]);
+
+               // Eliminate off-diagonal elems in col j of a, doing identical ops to b
+               for (i = 0; i < 4; i++)
+                       if (i != j) {
+                               b.v[i] = c3vec4_sub(b.v[i], c3vec4_mulf(b.v[j], a.v[i].n[j]));
+                               a.v[i] = c3vec4_sub(a.v[i], c3vec4_mulf(a.v[j], a.v[i].n[j]));
+                       }
+       }
+
+       return b;
+}
+
+c3mat4p c3mat4p_apply(c3mat4p a, V_FCT_PTR fct)
+{
+       a->v[0] = c3vec4_apply(a->v[0], fct);
+       a->v[1] = c3vec4_apply(a->v[1], fct);
+       a->v[2] = c3vec4_apply(a->v[2], fct);
+       a->v[3] = c3vec4_apply(a->v[3], fct);
+    return a;
+}
+
+c3mat4p c3mat4p_swap_rows(c3mat4p a, int i, int j)
+{
+    c3vec4 t;
+
+    t    = a->v[i];
+    a->v[i] = a->v[j];
+    a->v[j] = t;
+    return a;
+}
+
+c3mat4p c3mat4p_swap_cols(c3mat4p a, int i, int j)
+{
+       c3f t;
+
+       for (int k = 0; k < 4; k++) {
+               t = a->v[k].n[i];
+               a->v[k].n[i] = a->v[k].n[j];
+               a->v[k].n[j] = t;
+       }
+       return a;
+}
+
+
+// FRIENDS
+
+c3mat4 c3mat4_minus(const c3mat4p a)
+{
+    return c3mat4_vec4(
+               c3vec4_minus(a->v[0]),
+               c3vec4_minus(a->v[1]),
+               c3vec4_minus(a->v[2]),
+               c3vec4_minus(a->v[3]));
+}
+
+c3mat4 c3mat4_add(const c3mat4p a, const c3mat4p b)
+{
+    return c3mat4_vec4(
+        c3vec4_add(a->v[0], b->v[0]),
+        c3vec4_add(a->v[1], b->v[1]),
+        c3vec4_add(a->v[2], b->v[2]),
+        c3vec4_add(a->v[3], b->v[3]));
+}
+
+c3mat4 c3mat4_sub(const c3mat4p a, const c3mat4p b)
+{
+    return c3mat4_vec4(
+        c3vec4_sub(a->v[0], b->v[0]),
+        c3vec4_sub(a->v[1], b->v[1]),
+        c3vec4_sub(a->v[2], b->v[2]),
+        c3vec4_sub(a->v[3], b->v[3]));
+}
+
+c3mat4 c3mat4_mul(const c3mat4p a, const c3mat4p b)
+{
+    #define ROWCOL(i, j) \
+        a->v[i].n[0]*b->v[0].n[j] + \
+        a->v[i].n[1]*b->v[1].n[j] + \
+        a->v[i].n[2]*b->v[2].n[j] + \
+        a->v[i].n[3]*b->v[3].n[j]
+
+    return c3mat4_vec4(
+        c3vec4f(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
+        c3vec4f(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
+        c3vec4f(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
+        c3vec4f(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
+        );
+
+    #undef ROWCOL
+}
+
+c3mat4 c3mat4_mulf(const c3mat4p a, c3f d)
+{
+       c3mat4 r = *a;
+       return *c3mat4p_mulf(&r, d);
+}
+
+c3mat4 c3mat4_divf(const c3mat4p a, c3f d)
+{
+       c3mat4 r = *a;
+       return *c3mat4p_divf(&r, d);
+}
+
+int c3mat4_equal(const c3mat4p a, const c3mat4p b)
+{
+       return !memcmp(a->n, b->n, sizeof(a->n));
+#if 0
+    return
+        c3vec4_equal(a->v[0], b->v[0]) &&
+        c3vec4_equal(a->v[1], b->v[1]) &&
+        c3vec4_equal(a->v[2], b->v[2]) &&
+        c3vec4_equal(a->v[3], b->v[3]);
+#endif
+}
+
+/****************************************************************
+ *                                                              *
+ *         2D functions and 3D functions                        *
+ *                                                              *
+ ****************************************************************/
+
+c3mat3 identity2D()
+{
+    return c3mat3_vec3(
+        c3vec3f(1.0, 0.0, 0.0),
+        c3vec3f(0.0, 1.0, 0.0),
+        c3vec3f(0.0, 0.0, 1.0));
+}
+
+c3mat3 translation2D(const c3vec2 v)
+{
+    return c3mat3_vec3(
+        c3vec3f(1.0, 0.0, v.n[VX]),
+        c3vec3f(0.0, 1.0, v.n[VY]),
+        c3vec3f(0.0, 0.0, 1.0));
+}
+
+c3mat3 rotation2D(const c3vec2 Center, c3f angleDeg)
+{
+    c3f angleRad = (c3f) (angleDeg * M_PI / 180.0);
+    c3f c = (c3f) cos(angleRad);
+    c3f s = (c3f) sin(angleRad);
+
+    return c3mat3_vec3(
+        c3vec3f(c,    -s, Center.n[VX] * (1.0f-c) + Center.n[VY] * s),
+        c3vec3f(s,     c, Center.n[VY] * (1.0f-c) - Center.n[VX] * s),
+        c3vec3f(0.0, 0.0, 1.0));
+}
+
+c3mat3 scaling2D(const c3vec2 scaleVector)
+{
+    return c3mat3_vec3(
+        c3vec3f(scaleVector.n[VX], 0.0, 0.0),
+        c3vec3f(0.0, scaleVector.n[VY], 0.0),
+        c3vec3f(0.0, 0.0, 1.0));
+}
+
+c3mat4 identity3D()
+{
+    return c3mat4_vec4(
+        c3vec4f(1.0, 0.0, 0.0, 0.0),
+        c3vec4f(0.0, 1.0, 0.0, 0.0),
+        c3vec4f(0.0, 0.0, 1.0, 0.0),
+        c3vec4f(0.0, 0.0, 0.0, 1.0));
+}
+
+c3mat4 translation3D(const c3vec3 v)
+{
+    return c3mat4_vec4(
+        c3vec4f(1.0, 0.0, 0.0, v.n[VX]),
+        c3vec4f(0.0, 1.0, 0.0, v.n[VY]),
+        c3vec4f(0.0, 0.0, 1.0, v.n[VZ]),
+        c3vec4f(0.0, 0.0, 0.0, 1.0));
+}
+
+c3mat4 rotation3D(const c3vec3 Axis, c3f angleDeg)
+{
+    c3f angleRad = (c3f) (angleDeg * M_PI / 180.0);
+    c3f c = (c3f) cos(angleRad);
+    c3f s = (c3f) sin(angleRad);
+    c3f t = 1.0f - c;
+
+    c3vec3 axis = c3vec3_normalize(Axis);
+
+    return c3mat4_vec4(
+        c3vec4f(t * axis.n[VX] * axis.n[VX] + c,
+             t * axis.n[VX] * axis.n[VY] - s * axis.n[VZ],
+             t * axis.n[VX] * axis.n[VZ] + s * axis.n[VY],
+             0.0),
+        c3vec4f(t * axis.n[VX] * axis.n[VY] + s * axis.n[VZ],
+             t * axis.n[VY] * axis.n[VY] + c,
+             t * axis.n[VY] * axis.n[VZ] - s * axis.n[VX],
+             0.0),
+        c3vec4f(t * axis.n[VX] * axis.n[VZ] - s * axis.n[VY],
+             t * axis.n[VY] * axis.n[VZ] + s * axis.n[VX],
+             t * axis.n[VZ] * axis.n[VZ] + c,
+             0.0),
+        c3vec4f(0.0, 0.0, 0.0, 1.0));
+}
+
+c3mat4 rotation3Drad(const c3vec3 Axis, c3f angleRad)
+{
+    c3f c = (c3f) cos(angleRad);
+    c3f s = (c3f) sin(angleRad);
+    c3f t = 1.0f - c;
+
+    c3vec3 axis = c3vec3_normalize(Axis);
+
+    return c3mat4_vec4(
+        c3vec4f(t * axis.n[VX] * axis.n[VX] + c,
+             t * axis.n[VX] * axis.n[VY] - s * axis.n[VZ],
+             t * axis.n[VX] * axis.n[VZ] + s * axis.n[VY],
+             0.0),
+        c3vec4f(t * axis.n[VX] * axis.n[VY] + s * axis.n[VZ],
+             t * axis.n[VY] * axis.n[VY] + c,
+             t * axis.n[VY] * axis.n[VZ] - s * axis.n[VX],
+             0.0),
+        c3vec4f(t * axis.n[VX] * axis.n[VZ] - s * axis.n[VY],
+             t * axis.n[VY] * axis.n[VZ] + s * axis.n[VX],
+             t * axis.n[VZ] * axis.n[VZ] + c,
+             0.0),
+        c3vec4f(0.0, 0.0, 0.0, 1.0));
+}
+
+c3mat4 scaling3D(const c3vec3 scaleVector)
+{
+    return c3mat4_vec4(
+        c3vec4f(scaleVector.n[VX], 0.0, 0.0, 0.0),
+        c3vec4f(0.0, scaleVector.n[VY], 0.0, 0.0),
+        c3vec4f(0.0, 0.0, scaleVector.n[VZ], 0.0),
+        c3vec4f(0.0, 0.0, 0.0, 1.0));
+}
+
+c3mat4 perspective3D(c3f d)
+{
+    return c3mat4_vec4(
+        c3vec4f(1.0f, 0.0f, 0.0f,   0.0f),
+        c3vec4f(0.0f, 1.0f, 0.0f,   0.0f),
+        c3vec4f(0.0f, 0.0f, 1.0f,   0.0f),
+        c3vec4f(0.0f, 0.0f, 1.0f/d, 0.0f));
+}
+
diff --git a/examples/shared/libc3/src/c3algebra.h b/examples/shared/libc3/src/c3algebra.h
new file mode 100644 (file)
index 0000000..d2b71a1
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+       c3algebra.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       Derivative and inspiration from original C++:
+       Paul Rademacher & Jean-Francois DOUEG,
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3ALGEBRA_H___
+#define __C3ALGEBRA_H___
+
+
+#ifndef M_PI
+#define M_PI 3.141592654
+#endif
+
+enum {VX, VY, VZ, VW};           // axes
+enum {PA, PB, PC, PD};           // planes
+enum {RED, GREEN, BLUE, ALPHA};  // colors
+enum {KA, KD, KS, ES};           // phong coefficients
+
+typedef float c3f;
+typedef c3f (*V_FCT_PTR)(c3f);
+
+typedef union c3vec2 {
+       struct { c3f x,y; };
+       c3f n[2];
+} c3vec2;
+
+typedef union c3vec3 {
+       struct { c3f x,y,z; };
+       c3f n[3];
+} c3vec3;
+
+typedef union c3vec4 {
+       struct { c3f x,y,z,w; };
+       c3f n[4];
+} c3vec4, * c3vec4p;
+
+typedef union c3mat3 {
+       c3vec3 v[3];
+       c3f n[3*3];
+} c3mat3, * c3mat3p;
+
+typedef union c3mat4 {
+       c3vec4 v[4];
+       c3f n[4*4];
+} c3mat4, * c3mat4p;
+
+/*
+ * c3vec2 related
+ */
+
+c3vec2 c3vec2_zero();
+c3vec2 c3vec2f(c3f x, c3f y);
+
+c3vec2 c3vec2_add(c3vec2 a, const c3vec2 v);
+c3vec2 c3vec2_sub(c3vec2 a, const c3vec2 v);
+c3vec2 c3vec2_mulf(c3vec2 a, c3f d);
+c3vec2 c3vec2_divf(c3vec2 a, c3f d);
+
+c3f            c3vec2_length2(const c3vec2 a);
+c3f            c3vec2_length(const c3vec2 a);
+c3vec2 c3vec2_normalize(const c3vec2 a); // it is up to caller to avoid divide-by-zero
+c3vec2 c3vec2_apply(c3vec2 a, V_FCT_PTR fct);
+c3vec2 c3vec2_minus(const c3vec2 a);
+c3f            c3vec2_dot(const c3vec2 a, const c3vec2 b);
+c3vec2 c3vec2_min(const c3vec2 a, const c3vec2 b);
+c3vec2 c3vec2_max(const c3vec2 a, const c3vec2 b);
+c3vec2 c3vec2_prod(const c3vec2 a, const c3vec2 b);
+
+/*
+ * c3vec4 related
+ */
+
+c3vec3 c3vec3_zero();
+c3vec3 c3vec3f(c3f x, c3f y, c3f z);
+c3vec3 c3vec3_vec2f(const c3vec2 v, c3f d);
+c3vec3 c3vec3_vec2(const c3vec2 v);
+c3vec3 c3vec3_vec4(const c3vec4 v); // it is up to caller to avoid divide-by-zero
+
+c3vec3 c3vec3_add(const c3vec3 a, const c3vec3 v);
+c3vec3 c3vec3_sub(const c3vec3 a, const c3vec3 v);
+c3vec3 c3vec3_mulf(const c3vec3 a, c3f d);
+c3vec3 c3vec3_divf(const c3vec3 a, c3f d);
+
+c3f            c3vec3_length2(const c3vec3 a);
+c3f            c3vec3_length(const c3vec3 a);
+c3vec3 c3vec3_normalize(const c3vec3 a); // it is up to caller to avoid divide-by-zero
+c3vec3 c3vec3_homogenize(c3vec3 a); // it is up to caller to avoid divide-by-zero
+c3vec3 c3vec3_apply(c3vec3 a, V_FCT_PTR fct);
+c3vec3 c3vec3_minus(const c3vec3 a);
+c3f            c3vec3_dot(const c3vec3 a, const c3vec3 b);
+int            c3vec3_equal(const c3vec3 a, const c3vec3 b);
+c3vec3 c3vec3_min(const c3vec3 a, const c3vec3 b);
+c3vec3 c3vec3_max(const c3vec3 a, const c3vec3 b);
+c3vec3 c3vec3_prod(const c3vec3 a, const c3vec3 b);
+
+c3vec3 c3vec3_cross(const c3vec3 a, const c3vec3 b);
+c3vec3 c3vec2_cross(const c3vec2 a, const c3vec2 b);
+
+/*
+ * c3vec4 related
+ */
+
+c3vec4 c3vec4_zero();
+c3vec4 c3vec4f(c3f x, c3f y, c3f z, c3f w);
+c3vec4 c3vec4_vec3(const c3vec3 v);
+c3vec4 c3vec4_vec3f(const c3vec3 v, c3f d);
+
+c3vec4 c3vec4_add(c3vec4 a, const c3vec4 v);
+c3vec4 c3vec4_sub(c3vec4 a, const c3vec4 v);
+c3vec4 c3vec4_mulf(c3vec4 a, c3f d);
+c3vec4 c3vec4_divf(c3vec4 a, c3f d);
+
+c3f            c3vec4_length2(const c3vec4 a);
+c3f            c3vec4_length(const c3vec4 a);
+c3vec4 c3vec4_normalize(c3vec4 a); // it is up to caller to avoid divide-by-zero
+c3vec4 c3vec4_homogenize(c3vec4 a); // it is up to caller to avoid divide-by-zero
+c3vec4 c3vec4_apply(c3vec4 a, V_FCT_PTR fct);
+c3vec4 c3vec4_minus(const c3vec4 a);
+int            c3vec4_equal(const c3vec4 a, const c3vec4 b);
+c3vec4 c3vec4_min(const c3vec4 a, const c3vec4 b);
+c3vec4 c3vec4_max(const c3vec4 a, const c3vec4 b);
+c3vec4 c3vec4_prod(const c3vec4 a, const c3vec4 b);
+
+/*
+ * c3mat3 related
+ */
+
+c3mat3 c3mat3_identity();
+c3mat3 c3mat3_vec3(const c3vec3 v0, const c3vec3 v1, const c3vec3 v2);
+c3mat3p        c3mat3_add(const c3mat3p a, const c3mat3p m);
+c3mat3p        c3mat3_sub(const c3mat3p a, const c3mat3p m);
+c3mat3p        c3mat3_mulf(const c3mat3p a, c3f d);
+c3mat3p        c3mat3_divf(const c3mat3p a, c3f d);
+
+c3mat3 c3mat3_transpose(const c3mat3p a);
+c3mat3 c3mat3_inverse(const c3mat3p m);   // Gauss-Jordan elimination with partial pivoting
+c3mat3p        c3mat3_apply(c3mat3p a, V_FCT_PTR fct);
+c3mat3 c3mat3_minus(const c3mat3p a);
+
+c3mat3 c3mat3_mul(const c3mat3p a, const c3mat3p b);
+int            c3mat3_equal(const c3mat3p a, const c3mat3p b);
+
+c3vec2 c3mat3_mulv2(const c3mat3p a, const c3vec2 v);
+c3vec3 c3mat3_mulv3(const c3mat3p a, const c3vec3 v);
+c3vec2 c3vec2_mulm3(const c3vec2 v, const c3mat3p a);
+c3vec3 c3vec3_mulm3(const c3vec3 v, const c3mat3p a);
+
+c3mat3 identity2D();
+c3mat3 translation2D(const c3vec2 v);
+c3mat3 rotation2D(const c3vec2 Center, c3f angleDeg);
+c3mat3 scaling2D(const c3vec2 scaleVector);
+
+/*
+ * c3mat4 related
+ */
+
+c3mat4 c3mat4_identity();
+c3mat4 c3mat4_vec4(const c3vec4 v0, const c3vec4 v1, const c3vec4 v2, const c3vec4 v3);
+c3mat4 c3mat4f(
+     c3f a00, c3f a01, c3f a02, c3f a03,
+     c3f a10, c3f a11, c3f a12, c3f a13,
+     c3f a20, c3f a21, c3f a22, c3f a23,
+     c3f a30, c3f a31, c3f a32, c3f a33 );
+
+c3mat4 c3mat4_minus(const c3mat4p a);
+c3mat4p        c3mat4p_add(c3mat4p a, const c3mat4p m);
+c3mat4 c3mat4_add(const c3mat4p a, const c3mat4p b);
+c3mat4p        c3mat4p_sub(c3mat4p a, const c3mat4p m);
+c3mat4 c3mat4_sub(const c3mat4p a, const c3mat4p b);
+c3mat4p        c3mat4p_mulf(c3mat4p a, c3f d);
+c3mat4         c3mat4_mulf(const c3mat4p a, c3f d);
+c3mat4 c3mat4_mul(const c3mat4p a, const c3mat4p b);
+c3mat4p        c3mat4p_divf(c3mat4p a, c3f d);
+c3mat4 c3mat4_divf(const c3mat4p a, c3f d);
+
+c3mat4 c3mat4_transpose(const c3mat4p a);
+c3mat4 c3mat4_inverse(const c3mat4p m);       // Gauss-Jordan elimination with partial pivoting
+c3mat4p        c3mat4p_apply(c3mat4p a, V_FCT_PTR fct);
+c3mat4p        c3mat4p_swap_rows(c3mat4p a, int i, int j);
+c3mat4p        c3mat4p_swap_cols(c3mat4p a, int i, int j);
+int            c3mat4_equal(const c3mat4p a, const c3mat4p b);
+
+c3vec4 c3vec4_mulm4(const c3vec4 v, const c3mat4p a);
+c3vec4 c3mat4_mulv4(const c3mat4p a, const c3vec4 v);
+c3vec3 c3mat4_mulv3(const c3mat4p a, const c3vec3 v);
+
+c3mat4 identity3D();
+c3mat4 translation3D(const c3vec3 v);
+c3mat4 rotation3D(const c3vec3 Axis, c3f angleDeg);
+c3mat4 rotation3Drad(const c3vec3 Axis, c3f angleRad);
+c3mat4 scaling3D(const c3vec3 scaleVector);
+c3mat4 perspective3D(c3f d);
+
+#endif /* __C3ALGEBRA_H___ */
diff --git a/examples/shared/libc3/src/c3arcball.c b/examples/shared/libc3/src/c3arcball.c
new file mode 100644 (file)
index 0000000..f801651
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+       c3arcball.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <math.h>
+#include "c3arcball.h"
+
+
+/**************************************** c3arcball_init_mat4() ****/
+/* Takes as argument a c3mat4 to use instead of the internal rot  */
+
+void
+c3arcball_init_mat4(
+               c3arcballp a,
+               c3mat4p mtx )
+{
+    c3arcball_init(a);
+    a->rot_ptr = mtx;
+}
+
+
+/**************************************** c3arcball_init_center() ****/
+/* A constructor that accepts the screen center and arcball radius*/
+
+void
+c3arcball_init_center(
+               c3arcballp a,
+               const c3vec2 center,
+               c3f radius )
+{
+    c3arcball_init(a);
+    c3arcball_set_params(a, center, radius);
+}
+
+
+/************************************** c3arcball_set_params() ****/
+
+void
+c3arcball_set_params(
+               c3arcballp a,
+               const c3vec2 center,
+               c3f radius)
+{
+    a->center      = center;
+    a->radius      = radius;
+}
+
+/*************************************** c3arcball_init() **********/
+
+void
+c3arcball_init(
+               c3arcballp a )
+{
+    a->center = c3vec2f( 0.0, 0.0 );
+    a->radius         = 1.0;
+    a->q_now          = c3quat_identity();
+    a->rot_ptr         = &a->rot;
+    a->rot             = identity3D();
+    a->q_increment    = c3quat_identity();
+    a->rot_increment  = identity3D();
+    a->is_mouse_down  = false;
+    a->is_spinning    = false;
+    a->damp_factor    = 0.0;
+    a->zero_increment = true;
+}
+
+/*********************************** c3arcball_mouse_to_sphere() ****/
+
+c3vec3
+c3arcball_mouse_to_sphere(
+               c3arcballp a,
+               const c3vec2 p)
+{
+    c3f mag;
+    c3vec2  v2 = c3vec2_divf(c3vec2_sub(p, a->center), a->radius);
+    c3vec3  v3 = c3vec3f( v2.n[0], v2.n[1], 0.0 );
+
+    mag = c3vec2_dot(v2, v2);
+
+    if ( mag > 1.0 )
+        v3 = c3vec3_normalize(v3);
+    else
+        v3.n[VZ] = (c3f) sqrt( 1.0 - mag );
+
+    /* Now we add constraints - X takes precedence over Y */
+    if ( a->constraint_x ) {
+        v3 = c3arcball_constrain_vector( v3, c3vec3f( 1.0, 0.0, 0.0 ));
+    } else if ( a->constraint_y ) {
+       v3 = c3arcball_constrain_vector( v3, c3vec3f( 0.0, 1.0, 0.0 ));
+       }
+
+    return v3;
+}
+
+
+/************************************ c3arcball_constrain_vector() ****/
+
+c3vec3
+c3arcball_constrain_vector(
+               const c3vec3 vector,
+               const c3vec3 axis)
+{
+//    return (vector - (vector * axis) * axis).normalize();
+    return vector;
+}
+
+/************************************ c3arcball_mouse_down() **********/
+
+void
+c3arcball_mouse_down(
+               c3arcballp a,
+               int x,
+               int y)
+{
+    a->down_pt = c3vec2f( (c3f)x, (c3f) y );
+    a->is_mouse_down = true;
+
+    a->q_increment   = c3quat_identity();
+    a->rot_increment = identity3D();
+    a->zero_increment = true;
+}
+
+
+/************************************ c3arcball_mouse_up() **********/
+
+void
+c3arcball_mouse_up(
+               c3arcballp a)
+{
+    a->q_now = c3quat_mul(a->q_drag, a->q_now);
+    a->is_mouse_down = false;
+}
+
+
+/********************************** c3arcball_mouse_motion() **********/
+
+void
+c3arcball_mouse_motion(
+               c3arcballp a,
+               int x,
+               int y,
+               int shift,
+               int ctrl,
+               int alt)
+{
+    /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
+       c3arcball_set_constraints(a, ctrl != 0, alt != 0 );
+
+    c3vec2 new_pt = c3vec2f( (c3f)x, (c3f) y );
+    c3vec3 v0 = c3arcball_mouse_to_sphere(a, a->down_pt );
+    c3vec3 v1 = c3arcball_mouse_to_sphere(a, new_pt );
+
+    c3vec3 cross = c3vec3_cross(v0, v1);
+
+    a->q_drag = c3quat_vec3(cross, c3vec3_dot(v0, v1));
+
+    //    *rot_ptr = (q_drag * q_now).to_mat4();
+    c3mat4 temp = c3quat_to_mat4(a->q_drag);
+    *a->rot_ptr = c3mat4_mul(a->rot_ptr, &temp);
+
+    a->down_pt = new_pt;
+
+    /* We keep a copy of the current incremental rotation (= q_drag) */
+    a->q_increment   = a->q_drag;
+    a->rot_increment = c3quat_to_mat4(a->q_increment);
+
+    c3arcball_set_constraints(a, false, false);
+
+       if (a->q_increment.s < .999999) {
+               a->is_spinning = true;
+               a->zero_increment = false;
+       } else {
+               a->is_spinning = false;
+               a->zero_increment = true;
+       }
+}
+
+
+/********************************** c3arcball_mouse_motion() **********/
+#if 0
+void
+c3arcball_mouse_motion(
+               c3arcballp a,
+               int x,
+               int y)
+{
+    mouse_motion(x, y, 0, 0, 0);
+}
+#endif
+
+/***************************** c3arcball_set_constraints() **********/
+
+void
+c3arcball_set_constraints(
+               c3arcballp a,
+               bool _constraint_x,
+               bool _constraint_y)
+{
+    a->constraint_x = _constraint_x;
+    a->constraint_y = _constraint_y;
+}
+
+/***************************** c3arcball_idle() *********************/
+
+void
+c3arcball_idle(
+               c3arcballp a)
+{
+       if (a->is_mouse_down) {
+               a->is_spinning = false;
+               a->zero_increment = true;
+       }
+
+       if (a->damp_factor < 1.0f)
+               c3quat_scale_angle(&a->q_increment, 1.0f - a->damp_factor);
+
+       a->rot_increment = c3quat_to_mat4(a->q_increment);
+
+       if (a->q_increment.s >= .999999f) {
+               a->is_spinning = false;
+               a->zero_increment = true;
+       }
+}
+
+
+/************************ c3arcball_set_damping() *********************/
+
+void
+c3arcball_set_damping(
+               c3arcballp a,
+               c3f d)
+{
+    a->damp_factor = d;
+}
+
+
+
diff --git a/examples/shared/libc3/src/c3arcball.h b/examples/shared/libc3/src/c3arcball.h
new file mode 100644 (file)
index 0000000..d61c815
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+       c3arcball.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+       Copyright (c) 1998 Paul Rademacher
+    Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
+    Oct 2003, Nigel Stewart - GLUI Code Cleaning
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+       Arcball, as described by Ken
+       Shoemake in Graphics Gems IV.
+       This class takes as input mouse events (mouse down, mouse drag,
+       mouse up), and creates the appropriate quaternions and 4x4 matrices
+       to represent the rotation given by the mouse.
+
+       This class is used as follows:
+       - initialize [either in the constructor or with set_params()], the
+       center position (x,y) of the arcball on the screen, and the radius
+       - on mouse down, call mouse_down(x,y) with the mouse position
+       - as the mouse is dragged, repeatedly call mouse_motion() with the
+       current x and y positions.  One can optionally pass in the current
+       state of the SHIFT, ALT, and CONTROL keys (passing zero if keys
+       are not pressed, non-zero otherwise), which constrains
+       the rotation to certain axes (X for CONTROL, Y for ALT).
+       - when the mouse button is released, call mouse_up()
+
+       Axis constraints can also be explicitly set with the
+       set_constraints() function.
+
+       The current rotation is stored in the 4x4 float matrix 'rot'.
+       It is also stored in the quaternion 'q_now'.
+ */
+
+#ifndef __C3ARCBALL_H___
+#define __C3ARCBALL_H___
+
+#include "c3quaternion.h"
+
+typedef struct c3arcball {
+    int        is_mouse_down : 1,  /* true for down, false for up */
+               is_spinning : 1,
+               constraint_x : 1,
+               constraint_y : 1,
+               zero_increment : 1;
+    c3quat  q_now, q_down, q_drag, q_increment;
+    c3vec2  down_pt;
+    c3mat4  rot, rot_increment;
+    c3mat4  *rot_ptr;
+
+    c3vec2  center;
+    c3f                radius, damp_factor;
+} c3arcball, *c3arcballp;
+
+void
+c3arcball_init(
+               c3arcballp a );
+void
+c3arcball_init_mat4(
+               c3arcballp a,
+               c3mat4p mtx );
+void
+c3arcball_init_center(
+               c3arcballp a,
+               const c3vec2 center,
+               c3f radius );
+void
+c3arcball_set_params(
+               c3arcballp a,
+               const c3vec2 center,
+               c3f radius);
+c3vec3
+c3arcball_mouse_to_sphere(
+               c3arcballp a,
+               const c3vec2 p);
+c3vec3
+c3arcball_constrain_vector(
+               const c3vec3 vector,
+               const c3vec3 axis);
+void
+c3arcball_mouse_down(
+               c3arcballp a,
+               int x,
+               int y);
+void
+c3arcball_mouse_up(
+               c3arcballp a);
+
+void
+c3arcball_mouse_motion(
+               c3arcballp a,
+               int x,
+               int y,
+               int shift,
+               int ctrl,
+               int alt);
+void
+c3arcball_set_constraints(
+               c3arcballp a,
+               bool _constraint_x,
+               bool _constraint_y);
+void
+c3arcball_idle(
+               c3arcballp a);
+void
+c3arcball_set_damping(
+               c3arcballp a,
+               c3f d);
+
+#endif /* __C3ARCBALL_H___ */
diff --git a/examples/shared/libc3/src/c3cairo.c b/examples/shared/libc3/src/c3cairo.c
new file mode 100644 (file)
index 0000000..390a5c3
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+       c3cairo.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3cairo.h"
+#include "c3driver_geometry.h"
+
+#if CONFIG_C3_CAIRO
+
+void
+_c3cairo_dispose(
+               c3geometry_p g,
+               const c3driver_geometry_t * d)
+{
+       c3cairo_p c = (c3cairo_p)g;
+
+       if (c->cr)
+               cairo_destroy(c->cr);
+       if (c->surface)
+               cairo_surface_destroy(c->surface);
+       C3_DRIVER_INHERITED(g, d, dispose);
+}
+
+static void
+_c3cairo_project(
+               c3geometry_p g,
+               const struct c3driver_geometry_t *d,
+               c3mat4p m)
+{
+       C3_DRIVER_INHERITED(g, d, project, m);
+}
+
+const c3driver_geometry_t c3cairo_base_driver = {
+       .dispose = _c3cairo_dispose,
+       .project = _c3cairo_project,
+};
+const c3driver_geometry_t c3texture_driver;
+const c3driver_geometry_t c3geometry_driver;
+
+c3cairo_p
+c3cairo_new(
+               struct c3object_t * parent)
+{
+       c3cairo_p res = malloc(sizeof(*res));
+       return c3cairo_init(res, parent);
+}
+
+c3cairo_p
+c3cairo_init(
+               c3cairo_p o,
+               struct c3object_t * parent)
+{
+       memset(o, 0, sizeof(*o));
+       c3texture_init(&o->tex, parent);
+
+       static const c3driver_geometry_t * list[] = {
+                       &c3cairo_base_driver, &c3texture_driver, &c3geometry_driver, NULL,
+       };
+       ((c3geometry_p)o)->driver = list;
+
+       return o;
+}
+
+c3cairo_p
+c3cairo_new_offscreen(
+               struct c3object_t * parent,
+               int w, int h)
+{
+       c3cairo_p o = c3cairo_new(parent);
+
+       o->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
+       o->cr = cairo_create(o->surface);
+
+       c3pixels_p dst = c3pixels_new(w, h, 4,
+                       cairo_image_surface_get_stride(o->surface),
+                       cairo_image_surface_get_data(o->surface));
+       o->tex.geometry.mat.texture = dst;
+
+       return o;
+}
+
+#if 0
+cairo_surface_destroy(_surface);
+else
+cairo_surface_finish(_surface);
+#endif
+#endif // CONFIG_C3_CAIRO
diff --git a/examples/shared/libc3/src/c3cairo.h b/examples/shared/libc3/src/c3cairo.h
new file mode 100644 (file)
index 0000000..75d64b6
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+       c3cairo.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3CAIRO_H___
+#define __C3CAIRO_H___
+
+#include "c3config.h"
+#include "c3texture.h"
+#include "c3pixels.h"
+
+#if CONFIG_C3_CAIRO
+#include <pango/pangocairo.h>
+
+typedef struct c3cairo_t {
+       c3texture_t     tex;
+       cairo_t *       cr;
+       cairo_surface_t * surface;
+} c3cairo_t, *c3cairo_p;
+
+c3cairo_p
+c3cairo_new(
+               struct c3object_t * parent /* = NULL */);
+
+c3cairo_p
+c3cairo_init(
+               c3cairo_p o,
+               struct c3object_t * parent /* = NULL */);
+
+c3cairo_p
+c3cairo_new_offscreen(
+               struct c3object_t * parent /* = NULL */,
+               int w, int h);
+
+#endif // CONFIG_C3_CAIRO
+
+#endif /* __C3CAIRO_H___ */
diff --git a/examples/shared/libc3/src/c3camera.c b/examples/shared/libc3/src/c3camera.c
new file mode 100644 (file)
index 0000000..8e5fef1
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+       c3camera.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+       Copyright (c) 1998 Paul Rademacher
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3camera.h"
+
+
+void
+c3cam_set_distance(
+               c3camp c,
+               const c3f new_distance)
+{
+    if ( new_distance <= 0.0 )  /* Distance has to be positive */
+        return;
+
+    /* We find the current forward vector */
+//    forward = lookat - eye;
+    c->forward = c3vec3_normalize(c3vec3_sub(c->lookat, c->eye));
+
+    /* Set distance */
+    c->distance = new_distance;
+
+    /* Find new eye point */
+    c->eye = c3vec3_sub(c->lookat, c3vec3_mulf(c->forward, c->distance));
+    c3cam_update(c);
+}
+
+void
+c3cam_set_upv(
+               c3camp c,
+               const c3vec3 new_up)
+{
+    c->up = new_up;
+    c3cam_update(c);
+}
+
+void
+c3cam_set_upf(
+               c3camp c,
+               const c3f x,
+               const c3f y,
+               const c3f z)
+{
+       c3cam_set_upv(c, c3vec3f(x,y,z));
+}
+
+void
+c3cam_set_eyev(
+               c3camp c,
+               const c3vec3 new_eye)
+{
+    c->eye = new_eye;
+    c3cam_update(c);
+}
+
+void
+c3cam_set_eyef(
+               c3camp c,
+               const c3f x,
+               const c3f y,
+               const c3f z)
+{
+       c3cam_set_eyev(c, c3vec3f(x,y,z));
+}
+
+void
+c3cam_set_lookatv(
+               c3camp c,
+               const c3vec3 new_lookat)
+{
+    c->lookat = new_lookat;
+    c3cam_update(c);
+}
+
+void
+c3cam_set_lookatf(
+               c3camp c,
+               const c3f x,
+               const c3f y,
+               const c3f z)
+{
+       c3cam_set_lookatv(c, c3vec3f(x,y,z));
+}
+
+
+void
+c3cam_roll(
+               c3camp c,
+               const c3f angle)
+{
+    c3mat4 rot = rotation3D(c->forward, angle );
+    c->up = c3mat4_mulv3(&rot, c->up);
+    c3cam_update(c);
+}
+
+void
+c3cam_eye_yaw(
+               c3camp c,
+               const c3f angle)
+{
+    c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
+    c3mat4 rot    = rotation3D( c->up, angle );
+
+    eye_pt = c3mat4_mulv3(&rot, eye_pt);
+    c->eye    = c3vec3_add(c->lookat, eye_pt);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_eye_yaw_abs(
+               c3camp c,
+               const c3f angle,
+               const c3vec3 axis)
+{
+    c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
+    c3mat4 rot      = rotation3D( axis, angle );
+
+    eye_pt = c3mat4_mulv3(&rot, eye_pt);
+    c->eye    = c3vec3_add(c->lookat, eye_pt);
+
+    c->up = c3mat4_mulv3(&rot, c->up);
+
+    c3cam_update(c);
+}
+
+
+void
+c3cam_eye_pitch(
+               c3camp c,
+               const c3f angle)
+{
+    c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
+    c3mat4 rot    = rotation3D( c->side, angle );
+
+    eye_pt = c3mat4_mulv3(&rot, eye_pt);
+    c->eye    = c3vec3_add(c->lookat, eye_pt);
+
+    c->up = c3mat4_mulv3(&rot, c->up);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_lookat_yaw(
+               c3camp c,
+               const c3f angle)
+{
+    c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
+    c3mat4 rot = rotation3D( c->up, -angle );
+
+    lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
+    c->lookat = c3vec3_add(c->eye, lookat_pt);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_lookat_pitch(
+               c3camp c,
+               const c3f angle)
+{
+    c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
+    c3mat4 rot = rotation3D( c->side, -angle );
+
+    lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
+    c->lookat = c3vec3_add(c->eye, lookat_pt);
+
+    c->up = c3mat4_mulv3(&rot, c->up);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_reset_up_axis(
+               c3camp c,
+               const int axis_num)
+{
+    c3vec3 eye_pt = c3vec3_sub(c->lookat, c->eye); /* eye w/lookat at center */
+    c3f eye_distance = c3vec3_length(eye_pt);
+    c->eye.n[axis_num] = c->lookat.n[axis_num];
+    /* Bring eye to same level as lookat */
+
+    c3vec3 vector = c3vec3_sub(c->eye, c->lookat);
+    vector = c3vec3_normalize(vector);
+    vector = c3vec3_mulf(vector, eye_distance);
+
+    c->eye = c3vec3_add(c->lookat, vector);
+    c->up = c3vec3f( 0.0, 0.0, 0.0 );
+    c->up.n[axis_num] = 1.0;
+
+    c3cam_update(c);
+}
+
+void
+c3cam_reset_up(
+               c3camp c)
+{
+       c3cam_reset_up_axis(c, VY ); /* Resets to the Y axis */
+}
+
+void
+c3cam_movef(
+               c3camp c,
+               const c3f side_move,
+               const c3f up_move,
+               const c3f forw_move)
+{
+    c->eye    = c3vec3_add(c->eye, c3vec3_mulf(c->forward,             forw_move));
+    c->eye    = c3vec3_add(c->eye, c3vec3_mulf(c->side,                        side_move));
+    c->eye    = c3vec3_add(c->eye, c3vec3_mulf(c->up,                  up_move));
+    c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->forward,  forw_move));
+    c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->side,             side_move));
+    c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->up,               up_move));
+    c3cam_update(c);
+}
+
+void
+c3cam_movev(
+               c3camp c,
+               const c3vec3 v) /* A vector version of the above command */
+{
+       c3cam_movef(c, v.n[VX], v.n[VY], v.n[VZ] );
+}
+
+void
+c3cam_move_by_eye(
+               c3camp c,
+               const c3vec3 new_eye)
+{
+    c3vec3 diff = c3vec3_sub(new_eye, c->eye);
+
+    c->lookat = c3vec3_add(c->lookat, diff);
+    c->eye    = c3vec3_add(c->eye, diff);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_move_by_lookat(
+               c3camp c,
+               const c3vec3 new_lookat)
+{
+    c3vec3 diff = c3vec3_sub(new_lookat, c->lookat);
+
+    c->lookat = c3vec3_add(c->lookat, diff);
+    c->eye    = c3vec3_add(c->eye, diff);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_move_abs(
+               c3camp c,
+               const c3vec3 v)
+{
+    c->lookat = c3vec3_add(c->lookat, v);
+    c->eye    = c3vec3_add(c->eye, v);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_rot_about_eye(
+               c3camp c,
+               const c3mat4p rot)
+{
+    c3vec3  view = c3vec3_sub(c->lookat, c->eye);
+
+    view = c3mat4_mulv3(rot, view);
+    c->up   = c3mat4_mulv3(rot, c->up);
+
+    c->lookat = c3vec3_add(c->eye, view);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_rot_about_lookat(
+               c3camp c,
+               const c3mat4p rot)
+{
+    // NOT QUITE RIGHT YET
+
+    c3vec3 view = c3vec3_sub(c->eye, c->lookat);
+
+    view = c3mat4_mulv3(rot, view);
+    c->up   = c3mat4_mulv3(rot, c->up);
+
+    c->eye = c3vec3_add(c->lookat, view);
+
+    c3cam_update(c);
+}
+
+void
+c3cam_update_matrix(
+               c3camp c)
+{
+    c3cam_update(c);
+
+    c->mtx = c3mat4_vec4(
+               c3vec4f(c->side.n[VX],  c->up.n[VX],    c->forward.n[VX],       0.0),
+               c3vec4f(c->side.n[VY],  c->up.n[VY],    c->forward.n[VY],       0.0),
+               c3vec4f(c->side.n[VZ],  c->up.n[VZ],    c->forward.n[VZ],       0.0),
+               c3vec4f(0.0,                    0.0,                    0.0,                            1.0));
+}
+#if 0
+void
+c3cam_load_to_openGL(c3camp c)
+{
+    c3mat4  m;
+
+    make_mtx();
+
+    glMatrixMode( GL_MODELVIEW );
+    glLoadIdentity();
+    glMultMatrixf( (c3f*) &mtx[0][0]);
+    glTranslatef( -eye[VX], -eye[VY], -eye[VZ] );
+}
+
+void
+c3cam_load_to_openGL_noident(c3camp c)
+{
+    c3mat4  m;
+
+    make_mtx();
+
+    glMatrixMode( GL_MODELVIEW );
+    glMultMatrixf( (c3f*) &mtx[0][0]);
+    glTranslatef( -eye[VX], -eye[VY], -eye[VZ] );
+}
+#endif
+
+void
+c3cam_reset(
+               c3camp c)
+{
+    c->up = c3vec3f( 0.0, 1.0, 0.0 );
+    c->eye = c3vec3f(0.0, 0.0, 10.0);
+    c->lookat = c3vec3f(0.0,0.0,0.0);
+
+    c->mtx = identity3D();
+
+    c3cam_update(c);
+}
+
+c3cam
+c3cam_new()
+{
+       c3cam c;
+       c3cam_reset(&c);
+       return c;
+}
+
+void
+c3cam_update(
+               c3camp c)
+{
+       /* get proper side and forward vectors, and distance  */
+       c->forward = c3vec3_minus(c3vec3_sub(c->lookat, c->eye));
+       c->distance = c3vec3_length(c->forward);
+       c->forward = c3vec3_divf(c->forward, c->distance);
+
+       c->side = c3vec3_cross(c->up, c->forward);
+       c->up = c3vec3_cross(c->forward, c->side);
+
+       c->forward = c3vec3_normalize(c->forward);
+       c->up = c3vec3_normalize(c->up);
+       c->side = c3vec3_normalize(c->side);
+}
+
+# if 0
+void
+c3cam_dump(c3camp c, FILE *output) const
+{
+    fprintf( output, "Viewmodel: \n" );
+    eye.print(    output, "  eye"    );
+    lookat.print( output, "  lookat" );
+    up.print(     output, "  up"     );
+    side.print(   output, "  side"   );
+    forward.print(output, "  forward");
+    mtx.print(    output, "  mtx"    );
+}
+#endif
diff --git a/examples/shared/libc3/src/c3camera.h b/examples/shared/libc3/src/c3camera.h
new file mode 100644 (file)
index 0000000..1bfc66c
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ c3camera.h
+
+ Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+ Copyright (c) 1998 Paul Rademacher
+
+ This file is part of simavr.
+
+ simavr 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 3 of the License, or
+ (at your option) any later version.
+
+ simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __C3VIEW_H___
+#define __C3VIEW_H___
+
+#include "c3algebra.h"
+
+typedef struct c3cam {
+       c3vec3 eye, lookat;
+       c3vec3 up, side, forward;
+       c3mat4 mtx;
+       c3f distance;
+} c3cam, *c3camp;
+
+/******************************* set_distance() ***********/
+/* This readjusts the distance from the eye to the lookat */
+/* (changing the eye point in the process)                */
+/* The lookat point is unaffected                         */
+void
+c3cam_set_distance(
+               c3camp c,
+               const c3f new_distance);
+
+/******************************* set_up() ***************/
+void
+c3cam_set_upv(
+               c3camp c,
+               const c3vec3 new_up);
+void
+c3cam_set_upf(
+               c3camp c,
+               const c3f x,
+               const c3f y,
+               const c3f z);
+
+/******************************* set_eye() ***************/
+void
+c3cam_set_eyev(
+               c3camp c,
+               const c3vec3 new_eye);
+void
+c3cam_set_eyef(
+               c3camp c,
+               const c3f x,
+               const c3f y,
+               const c3f z);
+
+/******************************* set_lookat() ***************/
+void
+c3cam_set_lookatv(
+               c3camp c,
+               const c3vec3 new_lookat);
+void
+c3cam_set_lookatf(
+               c3camp c,
+               const c3f x,
+               const c3f y,
+               const c3f z);
+
+/******************************* roll() *****************/
+/* Rotates about the forward vector                     */
+/* eye and lookat remain unchanged                      */
+void
+c3cam_roll(
+               c3camp c,
+               const c3f angle);
+
+/******************************* eye_yaw() *********************/
+/* Rotates the eye about the lookat point, using the up vector */
+/* Lookat is unaffected                                        */
+void
+c3cam_eye_yaw(
+               c3camp c,
+               const c3f angle);
+
+/******************************* eye_yaw_abs() ******************/
+/* Rotates the eye about the lookat point, with a specific axis */
+/* Lookat is unaffected                                         */
+void
+c3cam_eye_yaw_abs(
+               c3camp c,
+               const c3f angle,
+               const c3vec3 axis);
+
+/******************************* eye_pitch() ************/
+/* Rotates the eye about the side vector                */
+/* Lookat is unaffected                                 */
+void
+c3cam_eye_pitch(
+               c3camp c,
+               const c3f angle);
+
+/******************************* lookat_yaw()************/
+/* This assumes the up vector is correct.               */
+/* Rotates the lookat about the side vector             */
+/* Eye point is unaffected                              */
+void
+c3cam_lookat_yaw(
+               c3camp c,
+               const c3f angle);
+
+/******************************* lookat_pitch() *********/
+/* Rotates the lookat point about the side vector       */
+/* This assumes the side vector is correct.             */
+/* Eye point is unaffected                              */
+void
+c3cam_lookat_pitch(
+               c3camp c,
+               const c3f angle);
+
+/******************************* reset_up() ******************/
+/* Resets the up vector to a specified axis (0=X, 1=Y, 2=Z)  */
+/* Also sets the eye point level with the lookat point,      */
+/* along the specified axis                                  */
+void
+c3cam_reset_up_axis(
+               c3camp c,
+               const int axis_num);
+void
+c3cam_reset_up(
+               c3camp c);
+
+/******************************* move() ********************/
+/* Moves a specified distance in the forward, side, and up */
+/* directions.  This function does NOT move by world       */
+/* coordinates.  To move by world coords, use the move_abs */
+/* function.                                               */
+void
+c3cam_movef(
+               c3camp c,
+               const c3f side_move,
+               const c3f up_move,
+               const c3f forw_move);
+void
+c3cam_movev(
+               c3camp c,
+               const c3vec3 v); /* A vector version of the above command */
+
+/******************************* move_by_eye() ***********/
+/* Sets the eye point, AND moves the lookat point by the */
+/* same amount as the eye is moved.                      */
+void
+c3cam_move_by_eye(
+               c3camp c,
+               const c3vec3 new_eye);
+
+/******************************* move_by_lookat() *********/
+/* Sets the lookat point, AND moves the eye point by the  */
+/* same amount as the lookat is moved.                    */
+void
+c3cam_move_by_lookat(
+               c3camp c,
+               const c3vec3 new_lookat);
+
+/******************************* move_abs() *****************/
+/* Move the eye and lookat in world coordinates             */
+void
+c3cam_move_abs(
+               c3camp c,
+               const c3vec3 v);
+
+/****************************** rot_about_eye() ************/
+/* Rotates the lookat point about the eye, based on a 4x4  */
+/* (pure) rotation matrix                                  */
+void
+c3cam_rot_about_eye(
+               c3camp c,
+               const c3mat4p rot);
+
+/****************************** rot_about_lookat() ************/
+/* Rotates the lookat point about the lookat, based on a 4x4  */
+/* (pure) rotation matrix                                  */
+void
+c3cam_rot_about_lookat(
+               c3camp c,
+               const c3mat4p rot);
+
+/******************************* make_mtx() *************/
+/* Constructs a 4x4 matrix - used by load_to_openGL()   */
+void
+c3cam_update_matrix(
+               c3camp c);
+
+/******************************* load_to_openGL() ********/
+/* Sets the OpenGL modelview matrix based on the current */
+/* camera coordinates                                    */
+//void c3cam_load_to_openGL();
+
+/******************************* load_to_openGL_noident() ******/
+/* Multiplies the current camera matrix by the existing openGL */
+/* modelview matrix.  This is same as above function, but      */
+/* does not set the OpenGL matrix to identity first            */
+//void c3cam_load_to_openGL_noident();
+
+/******************************* reset() ****************/
+/* Resets the parameters of this class                  */
+void
+c3cam_reset(
+               c3camp c);
+
+/******************************* ViewModel() ************/
+/* Constructor                                          */
+c3cam c3cam_new();
+
+/******************************* update() ****************/
+/* updates the view params.  Call this after making      */
+/* direct changes to the vectors or points of this class */
+void c3cam_update(
+               c3camp c);
+
+/******************************* dump() *******************/
+/* Prints the contents of this class to a file, typically */
+/* stdin or stderr                                        */
+//void c3cam_dump(FILE *output);
+
+#endif /* __C3VIEW_H___ */
diff --git a/examples/shared/libc3/src/c3config.h b/examples/shared/libc3/src/c3config.h
new file mode 100644 (file)
index 0000000..4457994
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __C3_CONFIG__
+#define __C3_CONFIG__
+#define CONFIG_C3_VERSION "0.1.0"
+#define CONFIG_C3_CAIRO 1
+#endif
diff --git a/examples/shared/libc3/src/c3context.c b/examples/shared/libc3/src/c3context.c
new file mode 100644 (file)
index 0000000..0ba8367
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+       c3context.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3context.h"
+#include "c3object.h"
+#include "c3driver_context.h"
+
+c3context_p
+c3context_new(
+               int w,
+               int h)
+{
+       c3context_p res = malloc(sizeof(*res));
+       return c3context_init(res, w, h);
+}
+
+c3context_p
+c3context_init(
+               c3context_p c,
+               int w,
+               int h)
+{
+       memset(c, 0, sizeof(*c));
+       c->size.x = w;
+       c->size.y = h;
+       c->root = c3object_new(NULL);
+       c->root->context = c;
+
+       c->cam = c3cam_new();
+
+       return c;
+}
+
+void
+c3context_dispose(
+               c3context_p c)
+{
+       c3object_dispose(c->root);
+       c3geometry_array_free(&c->projected);
+       free(c);
+}
+
+void
+c3context_project(
+               c3context_p c)
+{
+       if (!c->root || !c->root->dirty)
+               return;
+
+       c3mat4 m = identity3D();
+       c3object_project(c->root, &m);
+       c3geometry_array_clear(&c->projected);
+       c3object_get_geometry(c->root, &c->projected);
+}
+
+void
+c3context_draw(
+               c3context_p c)
+{
+       c3context_project(c);
+       for (int gi = 0; gi < c->projected.count; gi++) {
+               c3geometry_p g = c->projected.e[gi];
+               c3geometry_draw(g);
+       }
+}
diff --git a/examples/shared/libc3/src/c3context.h b/examples/shared/libc3/src/c3context.h
new file mode 100644 (file)
index 0000000..f659cf8
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+       c3context.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3CONTEXT_H___
+#define __C3CONTEXT_H___
+
+#include "c3algebra.h"
+#include "c3geometry.h"
+#include "c3pixels.h"
+#include "c3camera.h"
+
+//! c3context_t is a container for a 'scene' to be drawn
+/*!
+ * A c3context_t holds a root object, a list of already cached projected
+ * version of the geometry, and a driver that can be customized to draw it.
+ *
+ * This is a wrapper around a "top level object", the list of projected
+ * geometries is kept, purged and resorted if the root object becomes
+ * dirty
+ * TODO: Add the camera/eye/arcball control there
+ */
+typedef struct c3context_t {
+       c3vec2          size;
+       c3cam           cam;
+
+       struct c3object_t * root;       // root object
+       c3pixels_array_t        pixels; // pixels, textures...
+
+       c3geometry_array_t      projected;
+
+       const struct c3driver_context_t ** driver;
+} c3context_t, *c3context_p;
+
+//! Allocates a new context of size w=width, h=height
+c3context_p
+c3context_new(
+               int w,
+               int h);
+
+//! Initializes a new context 'c' of size w=width, h=height
+c3context_p
+c3context_init(
+               c3context_p c,
+               int w,
+               int h);
+
+//! Disposes the context, and everything underneath
+void
+c3context_dispose(
+               c3context_p c);
+
+//! Reproject geometry for dirty objects
+void
+c3context_project(
+               c3context_p c);
+//! Draws the context
+void
+c3context_draw(
+               c3context_p c);
+
+#endif /* __C3CONTEXT_H___ */
diff --git a/examples/shared/libc3/src/c3driver.h b/examples/shared/libc3/src/c3driver.h
new file mode 100644 (file)
index 0000000..901c32d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+       c3driver.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3DRIVER_H___
+#define __C3DRIVER_H___
+
+#define C3_DRIVER_CALL(__o, __callback, __args...) { \
+               if ((__o) && (__o)->driver) \
+                       for (int _di = 0; (__o)->driver[_di]; _di++) \
+                               if ((__o)->driver[_di]->__callback) { \
+                                       (__o)->driver[_di]->__callback(__o, (__o)->driver[_di], ##__args); \
+                                       break; \
+                               } \
+       }
+#define C3_DRIVER(__o, __callback, __args...) \
+               C3_DRIVER_CALL(__o, __callback, ##__args)
+#define C3_DRIVER_INHERITED(__o, __driver, __callback, __args...) { \
+               if ((__o) && (__o)->driver) \
+                       for (int _di = 0; (__o)->driver[_di]; _di++) \
+                               if ((__o)->driver[_di] == __driver && (__o)->driver[_di+1]) { \
+                                       (__o)->driver[_di+1]->__callback(__o, (__o)->driver[_di+1], ##__args); \
+                                       break; \
+                               } \
+       }
+#endif /* __C3DRIVER_H___ */
diff --git a/examples/shared/libc3/src/c3driver_context.h b/examples/shared/libc3/src/c3driver_context.h
new file mode 100644 (file)
index 0000000..98f34ab
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+       c3driver_context.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3DRIVER_CONTEXT_H___
+#define __C3DRIVER_CONTEXT_H___
+
+#include "c3driver.h"
+
+struct c3context_t;
+struct c3driver_context_t;
+struct c3geometry_t;
+
+typedef struct c3driver_context_t {
+       void (*geometry_project)(
+                       struct c3context_t * c,
+                       const struct c3driver_context_t *d,
+                       struct c3geometry_t * g,
+                       union c3mat4 * mat);
+       void (*geometry_draw)(
+                       struct c3context_t * c,
+                       const struct c3driver_context_t *d,
+                       struct c3geometry_t * g);
+} c3driver_context_t, *c3driver_context_p;
+
+#endif /* __C3DRIVER_CONTEXT_H___ */
diff --git a/examples/shared/libc3/src/c3driver_geometry.h b/examples/shared/libc3/src/c3driver_geometry.h
new file mode 100644 (file)
index 0000000..fa23eb5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+       c3driver_geometry.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3DRIVER_GEOMETRY_H___
+#define __C3DRIVER_GEOMETRY_H___
+
+#include "c3driver.h"
+
+struct c3geometry_t;
+
+typedef struct c3driver_geometry_t {
+       void (*dispose)(
+                       struct c3geometry_t * geometry,
+                       const struct c3driver_geometry_t *d);
+       void (*project)(
+                       struct c3geometry_t * geometry,
+                       const struct c3driver_geometry_t *d,
+                       union c3mat4 * mat);
+       void (*draw)(
+                       struct c3geometry_t * geometry,
+                       const struct c3driver_geometry_t *d);
+} c3driver_geometry_t, *c3driver_geometry_p;
+
+
+#endif /* __C3DRIVER_GEOMETRY_H___ */
diff --git a/examples/shared/libc3/src/c3driver_object.h b/examples/shared/libc3/src/c3driver_object.h
new file mode 100644 (file)
index 0000000..a809439
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+       c3driver_object.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3DRIVER_OBJECT_H___
+#define __C3DRIVER_OBJECT_H___
+
+#include "c3driver.h"
+
+struct c3object_t;
+struct c3geometry_array_t;
+union c3mat4;
+
+typedef struct c3driver_object_t {
+       /*
+        * Delete any object related to this object, geometry etc
+        * The object will still exist, just empty
+        */
+       void (*clear)(
+                       struct c3object_t * object,
+                       const struct c3driver_object_t * d);
+       /*
+        * Dispose of the remaining memory for an object, detaches it
+        * and frees remaining traces of it
+        */
+       void (*dispose)(
+                       struct c3object_t * object,
+                       const struct c3driver_object_t * d);
+       /*
+        * Adds sub objects geometry and self geometry to array 'out'
+        */
+       void (*get_geometry)(
+                       struct c3object_t * object,
+                       const struct c3driver_object_t * d,
+                       struct c3geometry_array_t * out);
+       /*
+        * Reproject geometry along matrix 'mat', applies our own
+        * transform and call down the chain for sub-objects
+        */
+       void (*project)(
+                       struct c3object_t * object,
+                       const struct c3driver_object_t * d,
+                       union c3mat4 * mat);
+} c3driver_object_t, *c3driver_object_p;
+
+
+#endif /* __C3DRIVER_OBJECT_H___ */
diff --git a/examples/shared/libc3/src/c3geometry.c b/examples/shared/libc3/src/c3geometry.c
new file mode 100644 (file)
index 0000000..3abaacc
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+       c3geometry.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3object.h"
+#include "c3context.h"
+#include "c3driver_geometry.h"
+#include "c3driver_context.h"
+
+static void
+_c3geometry_dispose(
+               c3geometry_p  g,
+               const struct c3driver_geometry_t *d)
+{
+       /*
+        * If we're still attached to an object, detach
+        */
+       if (g->object) {
+               for (int oi = 0; oi < g->object->geometry.count; oi++)
+                       if (g->object->geometry.e[oi] == g) {
+                               c3geometry_array_delete(&g->object->geometry, oi, 1);
+                               c3object_set_dirty(g->object, true);
+                               break;
+                       }
+               g->object = NULL;
+       }
+       str_free(g->name);
+       c3vertex_array_free(&g->vertice);
+       c3vertex_array_free(&g->projected);
+       c3tex_array_free(&g->textures);
+       c3colorf_array_free(&g->colorf);
+       free(g);
+//     C3_DRIVER_INHERITED(g, d, dispose);
+}
+
+static void
+_c3geometry_project(
+               c3geometry_p g,
+               const struct c3driver_geometry_t *d,
+               c3mat4p m)
+{
+       if (g->vertice.count) {
+               c3vertex_array_realloc(&g->projected, g->vertice.count);
+               g->projected.count = g->vertice.count;
+               for (int vi = 0; vi < g->vertice.count; vi++) {
+                       g->projected.e[vi] = c3mat4_mulv3(m, g->vertice.e[vi]);
+                       if (vi == 0)
+                               g->bbox.min = g->bbox.max = g->projected.e[vi];
+                       else {
+                               g->bbox.max = c3vec3_min(g->bbox.min, g->projected.e[vi]);
+                               g->bbox.max = c3vec3_max(g->bbox.max, g->projected.e[vi]);
+                       }
+               }
+       }
+
+       if (g->object && g->object->context)
+               C3_DRIVER(g->object->context, geometry_project, g, m);
+       g->dirty = 0;
+//     C3_DRIVER_INHERITED(g, d, project);
+}
+
+static void
+_c3geometry_draw(
+               c3geometry_p g,
+               const struct c3driver_geometry_t *d)
+{
+       if (g->object && g->object->context)
+               C3_DRIVER(g->object->context, geometry_draw, g);
+//     C3_DRIVER_INHERITED(g, d, draw);
+}
+
+const  c3driver_geometry_t c3geometry_driver = {
+       .dispose = _c3geometry_dispose,
+       .project = _c3geometry_project,
+       .draw = _c3geometry_draw,
+};
+
+c3geometry_p
+c3geometry_new(
+               c3geometry_type_t type,
+               c3object_p o /* = NULL */)
+{
+       c3geometry_p res = malloc(sizeof(c3geometry_t));
+       return c3geometry_init(res, type, o);
+}
+
+c3geometry_p
+c3geometry_init(
+               c3geometry_p g,
+               c3geometry_type_t type,
+               struct c3object_t * o /* = NULL */)
+{
+       memset(g, 0, sizeof(*g));
+       static const c3driver_geometry_t * list[] = {
+                       &c3geometry_driver, NULL,
+       };
+       g->driver = list;
+       g->type = type;
+       g->dirty = 1;
+       if (o)
+               c3object_add_geometry(o, g);
+       return g;
+}
+
+c3driver_geometry_p
+c3geometry_get_custom(
+               c3geometry_p g )
+{
+       if (g->custom)
+               return (c3driver_geometry_p)g->driver[0];
+       int cnt = 0;
+       for (int di = 0; g->driver[di]; di++)
+               cnt++;
+       c3driver_geometry_p * newd = malloc(sizeof(c3driver_geometry_p) * (cnt + 2));
+       memcpy(&newd[1], g->driver, (cnt + 1) * sizeof(c3driver_geometry_p));
+       newd[0] = malloc(sizeof(c3driver_geometry_t));
+       memset(newd[0], 0, sizeof(c3driver_geometry_t));
+       g->custom = 1;
+       g->driver = (typeof(g->driver))newd;
+       return newd[0];
+}
+
+void
+c3geometry_dispose(
+               c3geometry_p g)
+{
+       C3_DRIVER(g, dispose);
+}
+
+void
+c3geometry_project(
+               c3geometry_p g,
+               c3mat4p m)
+{
+       if (!g->dirty)
+               return;
+       C3_DRIVER(g, project, m);
+}
+
+void
+c3geometry_draw(
+               c3geometry_p g )
+{
+       C3_DRIVER(g, draw);
+}
+
+
diff --git a/examples/shared/libc3/src/c3geometry.h b/examples/shared/libc3/src/c3geometry.h
new file mode 100644 (file)
index 0000000..82b6156
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+       c3geometry.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * c3geometry is a structure containing one set of vertices and various
+ * bits related to it. Ultimately it contains a pre-cached projected
+ * version of the vertices that the drawing code can use directly.
+ * c3geometry is aways attached to a c3object as a parent.
+ */
+
+#ifndef __C3GEOMETRY_H___
+#define __C3GEOMETRY_H___
+
+#include "c3algebra.h"
+#include "c_utils.h"
+
+typedef c3vec3 c3vertex, *c3vertex_p;
+typedef c3vec4 c3colorf, *c3colorf_p;
+typedef c3vec2 c3tex, *c3tex_p;
+
+struct c3object_t;
+struct c3pixels_t;
+
+DECLARE_C_ARRAY(c3vertex, c3vertex_array, 16);
+DECLARE_C_ARRAY(c3tex, c3tex_array, 16);
+DECLARE_C_ARRAY(c3colorf, c3colorf_array, 16);
+
+//! Geometry material. TODO: Beef up. Add vertex/fragment programs..
+typedef struct c3material_t {
+       c3colorf        color;
+       struct c3pixels_t * texture;
+//     uint32_t        texmode;
+       struct {
+               uint32_t src, dst;
+       } blend;
+       struct {
+               uint32_t pid;
+       } program;
+} c3material_t;
+
+//! Bounding box. TODO: Move to a separate file?
+typedef struct c3bbox_t {
+       c3vec3  min, max;
+} c3bbox_t;
+
+//! Generic geometry type
+enum {
+       C3_RAW_TYPE = 0,
+       C3_LINES_TYPE,
+       C3_TRIANGLE_TYPE,
+       C3_TEXTURE_TYPE,
+};
+
+/*!
+ * geometry type.
+ * The type is used as non-opengl description of what the geometry
+ * contains, like "texture", and the subtype can be used to store the
+ * real format of the vertices. like GL_LINES etc
+ */
+typedef union c3geometry_type_t {
+       struct  { uint32_t type : 16, subtype : 16; };
+       uint32_t value;
+} c3geometry_type_t;
+
+/*!
+ * Geometry object. Describes a set of vertices, texture coordinates,
+ * normals, colors and material
+ * The projection is not set here, a geometry is always attached to a
+ * c3object that has the projection
+ */
+typedef struct c3geometry_t {
+       c3geometry_type_t       type;   // C3_TRIANGLE_TYPE, GL_LINES etc
+       int                                     dirty : 1,
+                                               custom : 1;             // has a custom driver
+       str_p                           name;   // optional
+       c3material_t            mat;
+       struct c3object_t * object;
+       const struct c3driver_geometry_t ** driver;
+
+       c3vertex_array_t        vertice;
+       c3tex_array_t           textures;
+       c3colorf_array_t        colorf;
+       c3vertex_array_t        normals;
+
+       // projected version of the vertice
+       c3vertex_array_t        projected;
+       c3bbox_t                        bbox;
+
+       /*
+        * Some shared attributes
+        */
+       union {
+               struct {
+                       float width;
+               } line;
+       };
+} c3geometry_t, *c3geometry_p;
+
+DECLARE_C_ARRAY(c3geometry_p, c3geometry_array, 4);
+
+//! Allocates a new geometry, init it, and attached it to parent 'o' (optional)
+c3geometry_p
+c3geometry_new(
+               c3geometry_type_t type,
+               struct c3object_t * o /* = NULL */);
+//! Init an existing new geometry, and attached it to parent 'o' (optional)
+c3geometry_p
+c3geometry_init(
+               c3geometry_p g,
+               c3geometry_type_t type,
+               struct c3object_t * o /* = NULL */);
+//! Disposes (via the driver interface) the geometry
+void
+c3geometry_dispose(
+               c3geometry_p g);
+
+//! Prepares a geometry. 
+/*!
+ * The project phase is called only when the container object is 'dirty'
+ * for example if it's projection has changed.
+ * The project call is responsible for reprojecting the geometry and that
+ * sort of things
+ */
+void
+c3geometry_project(
+               c3geometry_p g,
+               c3mat4p m);
+
+//! Draw the geometry
+/*
+ * Called when drawing the context. Typicaly this calls the geometry 
+ * driver, which in turn will call the 'context' draw method, and the 
+ * application to draw this particular geometry
+ */
+void
+c3geometry_draw(
+               c3geometry_p g );
+
+
+//! allocate (if not there) and return a custom driver for this geometry
+/*!
+ * Geometries come with a default, read only driver stack.. It is a constant
+ * global to save memory for each of the 'generic' object.
+ * This call will duplicate that stack and allocate (if not there) a read/write
+ * empty driver that the application can use to put their own, per object,
+ * callback. For example you can add your own project() or draw() function
+ * and have it called first
+ */
+struct c3driver_geometry_t *
+c3geometry_get_custom(
+               c3geometry_p g );
+
+IMPLEMENT_C_ARRAY(c3geometry_array);
+IMPLEMENT_C_ARRAY(c3vertex_array);
+IMPLEMENT_C_ARRAY(c3tex_array);
+IMPLEMENT_C_ARRAY(c3colorf_array);
+
+static inline c3geometry_type_t
+c3geometry_type(int type, int subtype)
+{
+       c3geometry_type_t r;// = { .type = type, .subtype = subtype }; // older gcc <4.6 doesn't like this
+       r.type = type; r.subtype = subtype;
+       return r;
+}
+
+#endif /* __C3GEOMETRY_H___ */
diff --git a/examples/shared/libc3/src/c3lines.c b/examples/shared/libc3/src/c3lines.c
new file mode 100644 (file)
index 0000000..9db9047
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+       c3lines.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3object.h"
+#include "c3context.h"
+#include "c3driver_geometry.h"
+#include "c3lines.h"
+
+
+void
+c3lines_prepare(
+               c3vertex_p  vertices,           // points A,B pairs
+               size_t          count,
+               c3vertex_array_p v,                     // triangles
+               c3tex_array_p tex,
+               c3f lineWidth,
+               c3mat4p m)
+{
+       c3tex_array_clear(tex);
+       c3vertex_array_clear(v);
+       for (int l = 0; l < count; l += 2) {
+               c3vec3 a = c3mat4_mulv3(m, vertices[l]);
+               c3vec3 b = c3mat4_mulv3(m, vertices[l+1]);
+
+               c3vec3 e = c3vec3_mulf(c3vec3_normalize(c3vec3_sub(b, a)), lineWidth);
+
+               c3vec3 N = c3vec3f(-e.y, e.x, 0);
+               c3vec3 S = c3vec3_minus(N);
+               c3vec3 NE = c3vec3_add(N, e);
+               c3vec3 NW = c3vec3_sub(N, e);
+               c3vec3 SW = c3vec3_minus(NE);
+               c3vec3 SE = c3vec3_minus(NW);
+#if 0
+               c3vertex_array_add(v, c3vec3_add(a, SW));
+               c3vertex_array_add(v, c3vec3_add(a, NW));
+               c3vertex_array_add(v, c3vec3_add(a, S));
+               c3vertex_array_add(v, c3vec3_add(a, N));
+               c3vertex_array_add(v, c3vec3_add(b, S));
+               c3vertex_array_add(v, c3vec3_add(b, N));
+               c3vertex_array_add(v, c3vec3_add(b, SE));
+               c3vertex_array_add(v, c3vec3_add(b, NE));
+#endif
+
+               const float ts = 1;
+
+               c3vertex_array_add(v, c3vec3_add(a, SW));
+               c3vertex_array_add(v, c3vec3_add(a, S));
+               c3vertex_array_add(v, c3vec3_add(a, NW));
+               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
+
+               c3vertex_array_add(v, c3vec3_add(a, S));
+               c3vertex_array_add(v, c3vec3_add(a, N));
+               c3vertex_array_add(v, c3vec3_add(a, NW));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0  , ts * 1  ));
+
+               c3vertex_array_add(v, c3vec3_add(a, N));
+               c3vertex_array_add(v, c3vec3_add(b, S));
+               c3vertex_array_add(v, c3vec3_add(b, N));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+
+               c3vertex_array_add(v, c3vec3_add(a, N));
+               c3vertex_array_add(v, c3vec3_add(a, S));
+               c3vertex_array_add(v, c3vec3_add(b, S));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+
+               c3vertex_array_add(v, c3vec3_add(b, N));
+               c3vertex_array_add(v, c3vec3_add(b, S));
+               c3vertex_array_add(v, c3vec3_add(b, SE));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
+
+               c3vertex_array_add(v, c3vec3_add(b, N));
+               c3vertex_array_add(v, c3vec3_add(b, SE));
+               c3vertex_array_add(v, c3vec3_add(b, NE));
+               c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1  ));
+               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 0  ));
+               c3tex_array_add(tex, c3vec2f(ts * 1  , ts * 1  ));
+
+       }
+}
+
+void
+c3lines_init(
+               c3geometry_p g,
+               c3vertex_p  vertices,           // points A,B pairs
+               size_t          count,
+               c3f             lineWidth)
+{
+       c3mat4 i = identity3D();
+       c3lines_prepare(vertices, count, &g->vertice, &g->textures, lineWidth, &i);
+       g->type.type = C3_LINES_TYPE;
+}
+
+#if 0
+static void
+_c3lines_project(
+               c3geometry_p g,
+               const struct c3driver_geometry_t *d,
+               c3mat4p m)
+
+const  c3driver_geometry_t c3lines_driver = {
+       .project = _c3lines_project,
+};
+
+const  c3driver_geometry_t c3geometry_driver;
+
+c3geometry_set_lines(
+               c3f lineWidth)
+{
+       static const c3driver_geometry_t * list[] = {
+                       &c3lines_driver, &c3geometry_driver, NULL,
+       };
+}
+#endif
diff --git a/examples/shared/libc3/src/c3lines.h b/examples/shared/libc3/src/c3lines.h
new file mode 100644 (file)
index 0000000..7befe47
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+       c3lines.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3LINES_H___
+#define __C3LINES_H___
+
+#include "c3geometry.h"
+
+/*
+ * Takes an array of points A,B and split it into 'fat' lines around
+ * lineWidth, generates an array of triangles and an array of corresponding
+ * texture cordinates. Can also do a projection at the same time
+ * TODO: Add array indexes
+ */
+void
+c3lines_prepare(
+               c3vertex_p  vertices,           // points A,B pairs
+               size_t          count,
+               c3vertex_array_p v,                     // triangles
+               c3tex_array_p tex,
+               c3f lineWidth,
+               c3mat4p m);
+
+void
+c3lines_init(
+               c3geometry_p g,
+               c3vertex_p  vertices,           // points A,B pairs
+               size_t          count,
+               c3f             lineWidth);
+
+#endif /* __C3LINES_H___ */
diff --git a/examples/shared/libc3/src/c3object.c b/examples/shared/libc3/src/c3object.c
new file mode 100644 (file)
index 0000000..52cbab3
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+       c3object.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3object.h"
+#include "c3driver_object.h"
+
+void
+_c3object_clear(
+               c3object_p o,
+               const c3driver_object_t * d)
+{
+       for (int oi = 0; oi < o->transform.count; oi++) {
+               o->transform.e[oi]->object = NULL;
+               c3transform_dispose(o->transform.e[oi]);
+       }
+       for (int oi = 0; oi < o->geometry.count; oi++) {
+               o->geometry.e[oi]->object = NULL;       // don't try to detach
+               c3geometry_dispose(o->geometry.e[oi]);
+       }
+       for (int oi = 0; oi < o->objects.count; oi++) {
+               o->objects.e[oi]->parent = NULL;        // don't try to detach
+               c3object_dispose(o->objects.e[oi]);
+       }
+       c3object_array_free(&o->objects);
+       c3geometry_array_free(&o->geometry);
+       c3transform_array_free(&o->transform);
+}
+
+void
+_c3object_dispose(
+               c3object_p o,
+               const c3driver_object_t * d)
+{
+       if (o->parent) {
+               for (int oi = 0; oi < o->parent->objects.count; oi++)
+                       if (o->parent->objects.e[oi] == o) {
+                               c3object_array_delete(&o->parent->objects, oi, 1);
+                               c3object_set_dirty(o->parent, true);
+                               break;
+                       }
+               o->parent = NULL;
+       }
+       //C3O_DRIVER_INHERITED(dispose, d);
+       free(o);
+}
+
+void
+_c3object_get_geometry(
+               c3object_p o,
+               const c3driver_object_t * d,
+               c3geometry_array_p out)
+{
+       for (int oi = 0; oi < o->geometry.count; oi++)
+               c3geometry_array_add(out, o->geometry.e[oi]);
+       for (int oi = 0; oi < o->objects.count; oi++)
+               c3object_get_geometry(o->objects.e[oi], out);
+}
+
+void
+_c3object_project(
+               c3object_p o,
+               const c3driver_object_t * d,
+               c3mat4p m)
+{
+       if (!o->dirty)
+               return;
+
+//     c3mat4 identity = identity3D();
+       c3mat4 p = *m;
+       for (int pi = 0; pi < o->transform.count; pi++)
+               p = c3mat4_mul(&p, &o->transform.e[pi]->matrix);
+//     bool is_identity = c3mat4_equal(m, &identity);
+       o->world = p;
+
+       for (int gi = 0; gi < o->geometry.count; gi++) {
+               c3geometry_p g = o->geometry.e[gi];
+               c3vertex_array_clear(&g->projected);
+
+               g->bbox.min = g->bbox.max = c3vec3f(0,0,0);
+               c3geometry_project(g, &p);
+       }
+       for (int oi = 0; oi < o->objects.count; oi++)
+               c3object_project(o->objects.e[oi], &p);
+       o->dirty = false;
+}
+
+const c3driver_object_t c3object_driver = {
+       .clear = _c3object_clear,
+       .dispose = _c3object_dispose,
+       .get_geometry = _c3object_get_geometry,
+       .project = _c3object_project,
+};
+
+
+c3object_p
+c3object_init(
+               c3object_p o /* = NULL */,
+               c3object_p parent)
+{
+       memset(o, 0, sizeof(*o));
+       o->parent = parent;
+       static const c3driver_object_t * list[] =
+                       { &c3object_driver, NULL };
+       o->driver = list;
+       if (parent) {
+               c3object_array_add(&parent->objects, o);
+               o->context = parent->context;
+       }
+       return o;
+}
+
+c3object_p
+c3object_new(
+               c3object_p o /* = NULL */)
+{
+       c3object_p res = malloc(sizeof(*o));
+       return c3object_init(res, o);
+}
+
+void
+c3object_clear(
+               c3object_p o)
+{
+       C3_DRIVER(o, clear);
+}
+
+void
+c3object_dispose(
+               c3object_p o)
+{
+       c3object_clear(o);
+       C3_DRIVER(o, dispose);
+}
+
+void
+c3object_set_dirty(
+               c3object_p o,
+               bool dirty)
+{
+       if (dirty) {
+               // also mark all our geometry dirty
+               for (int oi = 0; oi < o->geometry.count; oi++)
+                       if (o->geometry.e[oi])
+                               o->geometry.e[oi]->dirty = 1;
+               while (o) {
+                       o->dirty = true;
+                       o = o->parent;
+               }
+       } else {
+               for (int oi = 0; oi < o->objects.count; oi++)
+                       if (o->objects.e[oi]->dirty)
+                               c3object_set_dirty(o->objects.e[oi], false);
+               o->dirty = false;
+       }
+}
+
+void
+c3object_add_object(
+               c3object_p o,
+               c3object_p sub)
+{
+       if (sub->parent == o)
+               return;
+       if (sub->parent) {
+               for (int oi = 0; oi < sub->parent->objects.count; oi++) {
+                       if (sub->parent->objects.e[oi] == sub) {
+                               c3object_array_delete(&sub->parent->objects, oi, 1);
+                               c3object_set_dirty(sub->parent, true);
+                               break;
+                       }
+               }
+               sub->parent = NULL;
+       }
+       sub->parent = o;
+       if (o) {
+               c3object_array_add(&o->objects, sub);
+               c3object_set_dirty(o, true);
+       }
+}
+
+void
+c3object_add_geometry(
+               c3object_p o,
+               c3geometry_p g)
+{
+       if (g->object == o)
+               return;
+       if (g->object) {
+               for (int oi = 0; oi < g->object->geometry.count; oi++) {
+                       if (g->object->geometry.e[oi] == g) {
+                               c3geometry_array_delete(&g->object->geometry, oi, 1);
+                               c3object_set_dirty(g->object, true);
+                               break;
+                       }
+               }
+               g->object = NULL;
+       }
+       g->object = o;
+       if (o) {
+               c3geometry_array_add(&o->geometry, g);
+               c3object_set_dirty(o, true);
+       }
+}
+
+void
+c3object_get_geometry(
+               c3object_p o,
+               c3geometry_array_p array )
+{
+       C3_DRIVER(o, get_geometry, array);
+}
+
+void
+c3object_project(
+               c3object_p o,
+               const c3mat4p m)
+{
+       C3_DRIVER(o, project, m);
+}
diff --git a/examples/shared/libc3/src/c3object.h b/examples/shared/libc3/src/c3object.h
new file mode 100644 (file)
index 0000000..78122fa
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+       c3object.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3OBJECT_H___
+#define __C3OBJECT_H___
+
+#include <stdbool.h>
+#include "c3transform.h"
+#include "c3geometry.h"
+
+struct c3object_t;
+
+DECLARE_C_ARRAY(struct c3object_t*, c3object_array, 4);
+
+//! c3object is a container for child object, and geometry
+/*!
+ * a c3object is a node in a c3object tree, it contains sub-objects and/or
+ * geometry. It also contains it's own list of transform matrices, so can
+ * be seen as a "anchor" that can be moved around and where you can
+ * attach other objects or geometry.
+ *
+ * An object has a notion of 'dirty bit' -- something that signals that
+ * something has changed and deserved reprojection. the dirty bit
+ * is propagated upward when 1 (up to the root object) and downward when 0
+ * (to allow clearing the bit on a subtree)
+ */
+typedef struct c3object_t {
+       str_p                           name;   //! optional name
+       int                                     dirty : 1, 
+                                               visible : 1 /* TODO: Implement visible */;
+       struct c3context_t * context; //! context this object is attached to
+       struct c3object_t * parent;             //! Parent object
+       const struct c3driver_object_t ** driver;       //! Driver stack
+
+       c3mat4                          world;          // calculated world coordinates
+       c3transform_array_t     transform;
+       c3object_array_t        objects;        //! child object list
+       c3geometry_array_t      geometry;       //! Object geometri(es)
+} c3object_t, *c3object_p;
+
+//! Allocates and initialize an emty object, attaches it to parent 'o'
+c3object_p
+c3object_new(
+               c3object_p o /* = NULL */);
+//! Disposes of everything under this object
+void
+c3object_dispose(
+               c3object_p o);
+//! Clears every sub-object, geometry, and transform, but do not dispose of o
+void
+c3object_clear(
+               c3object_p o);
+//! Initializes 'o' as a new object, attaches it to parent (optional)
+c3object_p
+c3object_init(
+               c3object_p o,
+               c3object_p parent /* = NULL */);
+//! sets the dirty bit for 'o' and related tree
+/*!
+ * When dirty is 1, sets the dirty bit of this object and all the parent
+ * objects up to the root object.
+ * When dirty is 0, clear the dirty bit of this object, and all the
+ * sub objects.
+ */
+void
+c3object_set_dirty(
+               c3object_p o,
+               bool dirty);
+//! Adds a new geometry g to object o
+void
+c3object_add_geometry(
+               c3object_p o,
+               c3geometry_p g);
+//! Adds a new sub-object sub to object o
+void
+c3object_add_object(
+               c3object_p o,
+               c3object_p sub);
+//! Adds a new transform matrix, initialized as identity
+c3transform_p
+c3object_add_transform(
+               c3object_p o );
+//! Iterates all the sub-objects and collects all the geometries
+/*!
+ * This call iterates the sub-objects and collects all their 'projected'
+ * geometry, and add them to the array
+ */
+void
+c3object_get_geometry(
+               c3object_p o,
+               c3geometry_array_p array );
+//! Project object 'o' using it's own transformations, relative to matrix 'm'
+/*!
+ * Multiply this objects transformation(s) to matrix 'm' and calls
+ * reprojects the geometries using that matrix as an anchor. also call
+ * recursively to sub-objects to follow the projection down.
+ */
+void
+c3object_project(
+               c3object_p o,
+               const c3mat4p m);
+
+IMPLEMENT_C_ARRAY(c3object_array);
+
+#endif /* __C3OBJECT_H___ */
diff --git a/examples/shared/libc3/src/c3pixels.c b/examples/shared/libc3/src/c3pixels.c
new file mode 100644 (file)
index 0000000..cdaef7e
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+       c3pixels.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "c3pixels.h"
+
+c3pixels_p
+c3pixels_new(
+               uint32_t w,
+               uint32_t h,
+               int      psize /* in bytes */,
+               size_t row,
+               void * base)
+{
+       c3pixels_p p = malloc(sizeof(*p));
+       c3pixels_init(p, w, h, psize, row, base);
+       p->alloc = 1;
+       return p;
+}
+
+c3pixels_p
+c3pixels_init(
+               c3pixels_p p,
+               uint32_t w,
+               uint32_t h,
+               int      psize /* in bytes */,
+               size_t row,
+               void * base)
+{
+       memset (p, 0, sizeof(*p));
+       p->w = w;
+       p->h = h;
+       p->row = row;
+       p->psize = psize;
+       p->base = base;
+       c3pixels_alloc(p);
+       return p;
+}
+
+void
+c3pixels_dispose(
+               c3pixels_p p )
+{
+       if (p->own && p->base)
+               free(p->base);
+       if (p->alloc)
+               free(p);
+       else
+               memset(p, 0, sizeof(*p));
+}
+
+void
+c3pixels_alloc(
+               c3pixels_p p )
+{
+       if (p->base)
+               return;
+       p->base = malloc(p->row * p->h);
+       p->own = p->base != NULL;
+}
+
+void
+c3pixels_purge(
+               c3pixels_p p )
+{
+       if (!p->base)
+               return;
+       if (p->own)
+               free(p->base);
+       p->own = 0;
+       p->base = NULL;
+}
+
+void
+c3pixels_zero(
+               c3pixels_p p)
+{
+       if (!p->base)
+               return;
+       memset(p->base, 0, p->h * p->row);
+}
diff --git a/examples/shared/libc3/src/c3pixels.h b/examples/shared/libc3/src/c3pixels.h
new file mode 100644 (file)
index 0000000..1952123
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+       c3pixels.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3PIXELS_H___
+#define __C3PIXELS_H___
+
+#include <stdint.h>
+#include "c_utils.h"
+
+//! for format hint
+enum {
+       C3PIXEL_ARGB = 0,
+       C3PIXEL_RGB,
+       C3PIXEL_A
+};
+
+typedef struct c3pixels_t {
+       str_p name;             // optional
+       uint32_t w, h;  // width & height in pixels
+       size_t row;             // size of one row in bytes
+       void * base;    // base address
+
+       union {
+               struct {
+                       uint32_t        own : 1,        // is the base our own to delete
+                               alloc : 1,                      // is the c3pixels_p our own to delete
+                               dirty : 1,                      // pixels have been changed
+                               psize : 4,                      // pixel size in byte
+                               normalize : 1,          // texture coordinates are 0...1
+                               trace : 1,                      // debug
+                               format : 8;                     // not used internally
+               };
+               uint32_t flags;
+       };
+       uint32_t        texture;
+       int                     refCount;       // TODO: Implement reference counting ?
+} c3pixels_t, *c3pixels_p;
+
+DECLARE_C_ARRAY(c3pixels_p, c3pixels_array, 4);
+
+//! Allocates a new c3pixels, also allocates the pixels if row == NULL
+c3pixels_p
+c3pixels_new(
+               uint32_t w,
+               uint32_t h,
+               int      psize /* in bytes */,
+               size_t row,
+               void * base);
+
+//! Initializes p, also allocates the pixels if row == NULL
+c3pixels_p
+c3pixels_init(
+               c3pixels_p p,
+               uint32_t w,
+               uint32_t h,
+               int      psize /* in bytes */,
+               size_t row,
+               void * base);
+
+//! Dispose of the pixels, and potentially p if it was allocated with c3pixels_new
+void
+c3pixels_dispose(
+               c3pixels_p p );
+
+//! Disposes of the pixels, only
+void
+c3pixels_purge(
+               c3pixels_p p );
+
+//! (Re)allocate pixels if pixels had been purged
+void
+c3pixels_alloc(
+               c3pixels_p p );
+
+//! Get a pixel address
+static inline void *
+c3pixels_get(
+               c3pixels_p p,
+               int x, int y)
+{
+       return ((uint8_t*)p->base) + (y * p->row) + (x * p->psize);
+}
+
+//! Zeroes the pixels
+void
+c3pixels_zero(
+               c3pixels_p p);
+
+IMPLEMENT_C_ARRAY(c3pixels_array);
+
+#endif /* __C3PIXELS_H___ */
diff --git a/examples/shared/libc3/src/c3quaternion.c b/examples/shared/libc3/src/c3quaternion.c
new file mode 100644 (file)
index 0000000..10dd468
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+       c3quaternion.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <math.h>
+#include "c3quaternion.h"
+
+#ifndef DEG2RAD
+#define DEG2RAD(x) ((x)/180.0*M_PI)
+#define RAD2DEG(x) ((x)/M_PI*180.0)
+#endif
+#ifndef FUDGE
+#define FUDGE .00001
+#endif
+
+c3quat
+c3quat_new()
+{
+    return c3quat_identity();
+}
+
+/************************************************* c3quat_identity() *****/
+/* Returns quaternion identity element                                 */
+
+c3quat
+c3quat_identity()
+{
+    return c3quat_vec3( c3vec3f( 0.0, 0.0, 0.0 ), 1.0 );
+}
+
+c3quat
+c3quatf(
+               const c3f x,
+               const c3f y,
+               const c3f z,
+               const c3f w)
+{
+       c3quat q = { .v = c3vec3f(x,y,z), .s = w };
+       return q;
+}
+
+c3quat
+c3quat_vec3(
+               const c3vec3 v,
+               const c3f s)
+{
+       c3quat q = { .v = v, .s = s };
+    return q;
+}
+
+c3quat
+c3quat_vec4(
+               const c3vec4 v)
+{
+       c3quat q = { .v = c3vec3f(v.n[0], v.n[1], v.n[2]), .s = v.n[3] };
+    return q;
+}
+
+c3quat
+c3quat_double(
+               const double *d)
+{
+       c3quat q;
+    q.v.n[0] = (c3f) d[0];
+    q.v.n[1] = (c3f) d[1];
+    q.v.n[2] = (c3f) d[2];
+    q.s         = (c3f) d[3];
+    return q;
+}
+
+
+c3quat
+c3quat_add(
+               const c3quat a,
+               const c3quat b)
+{
+    return c3quat_vec3(c3vec3_add(a.v, b.v), a.s + b.s );
+}
+
+c3quat
+c3quat_sub(
+               const c3quat a,
+               const c3quat b)
+{
+    return c3quat_vec3(c3vec3_sub(a.v, b.v), a.s - b.s );
+}
+
+c3quat
+c3quat_minus(
+               const c3quat a )
+{
+    return c3quat_vec3(c3vec3_minus(a.v), -a.s);
+}
+
+c3quat
+c3quat_mul(
+               const c3quat a,
+               const c3quat b)
+{
+//    return c3quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + a.v^b.v );
+    return c3quat_vec3(
+               c3vec3_add(c3vec3_mulf(b.v, a.s), c3vec3_add(c3vec3_mulf(a.v, b.s), c3vec3_cross(a.v, b.v))),
+               (a.s * b.s) - c3vec3_dot(a.v, b.v));
+}
+
+c3quat
+c3quat_mulf( const c3quat a, const c3f t)
+{
+    return c3quat_vec3(c3vec3_mulf(a.v, t), a.s * t );
+}
+
+c3mat4
+c3quat_to_mat4(
+               const c3quat a )
+{
+    c3f xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
+
+    c3f t  = 2.0f / (c3vec3_dot(a.v, a.v) + (a.s * a.s));
+
+    xs = a.v.n[VX]*t;   ys = a.v.n[VY]*t;   zs = a.v.n[VZ]*t;
+    wx = a.s*xs;               wy = a.s*ys;            wz = a.s*zs;
+    xx = a.v.n[VX]*xs;  xy = a.v.n[VX]*ys;  xz = a.v.n[VX]*zs;
+    yy = a.v.n[VY]*ys;  yz = a.v.n[VY]*zs;  zz = a.v.n[VZ]*zs;
+
+    c3mat4 m = c3mat4_vec4(
+           c3vec4f(1.0f-(yy+zz), xy+wz,        xz-wy,        0.0f),
+           c3vec4f(xy-wz,        1.0f-(xx+zz), yz+wx,        0.0f),
+           c3vec4f(xz+wy,        yz-wx,        1.0f-(xx+yy), 0.0f),
+           c3vec4f(0.0f,         0.0f,         0.0f,         1.0f ));
+
+    return m;
+}
+
+
+/************************************************ quat_slerp() ********/
+/* Quaternion spherical interpolation                                 */
+
+c3quat
+quat_slerp(
+               const c3quat from,
+               const c3quat to,
+               c3f t)
+{
+    c3quat to1;
+    c3f omega, cosom, sinom, scale0, scale1;
+
+    /* calculate cosine */
+    cosom = c3vec3_dot(from.v, to.v) + from.s + to.s;
+
+       /* Adjust signs (if necessary) */
+       if (cosom < 0.0) {
+               cosom = -cosom;
+               to1 = c3quat_minus(to);
+       } else {
+               to1 = to;
+       }
+
+    /* Calculate coefficients */
+    if ((1.0 - cosom) > FUDGE ) {
+        /* standard case (slerp) */
+        omega =  (c3f) acos( cosom );
+        sinom =  (c3f) sin( omega );
+        scale0 = (c3f) sin((1.0 - t) * omega) / sinom;
+        scale1 = (c3f) sin(t * omega) / sinom;
+    } else {
+        /* 'from' and 'to' are very close - just do linear interpolation */
+        scale0 = 1.0f - t;
+        scale1 = t;
+    }
+
+    return c3quat_add(c3quat_mulf(from, scale0), c3quat_mulf(to1, scale1));
+}
+
+/********************************************** set_angle() ************/
+/* set rot angle (degrees)                                             */
+
+c3quatp
+c3quat_set_angle(
+               c3quatp a,
+               c3f f)
+{
+    c3vec3 axis = c3quat_get_axis(a);
+
+    a->s = (c3f) cos( DEG2RAD( f ) / 2.0 );
+
+    a->v = c3vec3_mulf(axis, (c3f) sin(DEG2RAD(f) / 2.0));
+    return a;
+}
+
+/********************************************** scale_angle() ************/
+/* scale rot angle (degrees)                                             */
+
+c3quatp
+c3quat_scale_angle(
+               c3quatp a,
+               c3f f)
+{
+       return c3quat_set_angle(a, f * c3quat_get_angle(a) );
+}
+
+/********************************************** get_angle() ************/
+/* get rot angle (degrees).  Assumes s is between -1 and 1             */
+
+c3f
+c3quat_get_angle(
+               const c3quatp a)
+{
+    return (c3f) RAD2DEG( 2.0 * acos( a->s ) );
+}
+
+/********************************************* get_axis() **************/
+
+c3vec3
+c3quat_get_axis(
+               c3quatp a)
+{
+    c3f scale = (c3f) sin( acos( a->s ) );
+
+    if ( scale < FUDGE && scale > -FUDGE )
+        return c3vec3f( 0.0, 0.0, 0.0 );
+    else
+        return  c3vec3_divf(a->v, scale);
+}
+
+/******************************************* c3quat_print() ************/
+#if 0
+void c3quat_print(FILE *dest, const char *name) const
+{
+    fprintf( dest, "%s:   v:<%3.2f %3.2f %3.2f>  s:%3.2f\n",
+        name, v[0], v[1], v[2], s );
+}
+#endif
diff --git a/examples/shared/libc3/src/c3quaternion.h b/examples/shared/libc3/src/c3quaternion.h
new file mode 100644 (file)
index 0000000..92bf35d
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+       c3quaternion.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3QUATERNION_H___
+#define __C3QUATERNION_H___
+
+#include <stdbool.h>
+#include "c3algebra.h"
+
+typedef struct c3quat {
+  c3vec3  v;   /* vector component */
+  c3f s;               /* scalar component */
+} c3quat, *c3quatp;
+
+c3quat
+c3quat_new();
+c3quat
+c3quat_identity();
+
+c3quat
+c3quatf(
+               const c3f x,
+               const c3f y,
+               const c3f z,
+               const c3f w);
+c3quat
+c3quat_vec3(
+               const c3vec3 v,
+               const c3f s);
+c3quat
+c3quat_vec4(
+               const c3vec4 v);
+
+c3quat
+c3quat_double(
+               const double *d);
+
+c3quat
+c3quat_add(
+               const c3quat a,
+               const c3quat b);
+c3quat
+c3quat_sub(
+               const c3quat a,
+               const c3quat b);
+c3quat
+c3quat_minus(
+               const c3quat a );
+
+c3quat
+c3quat_mul(
+               const c3quat a,
+               const c3quat b);
+
+c3mat4
+c3quat_to_mat4(
+               const c3quat a );
+
+c3quatp
+c3quat_set_angle(
+               c3quatp a,
+               c3f f);
+c3quatp
+c3quat_scale_angle(
+               c3quatp a,
+               c3f f);
+c3f
+c3quat_get_angle(
+               const c3quatp a);
+c3vec3
+c3quat_get_axis(
+               c3quatp a);
+
+#endif /* __C3QUATERNION_H___ */
diff --git a/examples/shared/libc3/src/c3stl.c b/examples/shared/libc3/src/c3stl.c
new file mode 100644 (file)
index 0000000..c42709b
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+       c3stl.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include "c3algebra.h"
+#include "c3geometry.h"
+#include "c3object.h"
+#include "c3stl.h"
+
+enum {
+       vertex_None = -1,
+       vertex_Vertex,
+       vertex_Normal,
+};
+
+static int
+_c3stl_read_vertex(
+               char * vt,
+               c3vec3 * out )
+{
+       int res = 1;
+       char *l = vt;
+       /*char * key =*/ strsep(&l, " \t");
+       char * x = strsep(&l, " \t");
+       char * y = strsep(&l, " \t");
+       char * z = strsep(&l, " \t");
+
+       if (x) sscanf(x, "%f", out->n);
+       if (y) sscanf(y, "%f", out->n + 1);
+       if (z) sscanf(z, "%f", out->n + 2);
+//     printf("'%s' '%s' '%s' '%s' = %.2f %.2f %.2f\n",
+//                     key, x, y, z, out->n[0], out->n[1], out->n[2]);
+       return res;
+}
+
+struct c3object_t *
+c3stl_load(
+               const char * filename,
+               c3object_p parent)
+{
+       FILE *f = fopen(filename, "r");
+       if (!f) {
+               perror(filename);
+               return NULL;
+       }
+
+       c3object_p              o = c3object_new(parent);
+       c3geometry_p    current_g = NULL;
+       o->name = str_new(filename);
+
+       int state = 0;
+       while (!feof(f)) {
+               char line[256];
+
+               fgets(line, sizeof(line), f);
+
+               int l = strlen(line);
+               while (l && line[l-1] < ' ')
+                       line[--l] = 0;
+               if (!l)
+                       continue;
+               char * keyword = line;
+               while (*keyword && *keyword <= ' ')
+                       keyword++;
+               l = strlen(keyword);
+       //      printf("%d>'%s'\n", state, keyword);
+
+               switch (state) {
+                       case 0: //
+                               if (!strncmp(keyword, "solid ", 6)) {
+                                       char * n = keyword + 6;
+                                       current_g = c3geometry_new(c3geometry_type(C3_TRIANGLE_TYPE, 0), o);
+                                       current_g->name = str_new(n);
+
+                                       state = 1;
+                               }
+                               break;
+                       case 1: //
+                               if (!strncmp(keyword, "facet ", 6)) {
+                                       c3vec3 normal;
+                                       _c3stl_read_vertex(keyword + 6, &normal);
+                                       c3vertex_array_add(&current_g->normals, normal);
+                                       c3vertex_array_add(&current_g->normals, normal);
+                                       c3vertex_array_add(&current_g->normals, normal);
+                                       state = 2;
+                               } else if (!strncmp(keyword, "endsolid ", 9))
+                                       state = 0;
+                               break;
+                       case 2:
+                               if (!strncmp(keyword, "outer loop", 10))
+                                       state = 3;
+                               else if (!strncmp(keyword, "endfacet", 8))
+                                       state = 1;
+                               break;
+                       case 3:
+                               if (!strncmp(keyword, "vertex ", 7)) {
+                                       c3vec3 v;
+                                       _c3stl_read_vertex(keyword, &v);
+                                       c3vertex_array_add(&current_g->vertice, v);
+                                       state = 3;
+                               } else if (!strncmp(keyword, "endloop", 7))
+                                       state = 2;
+                               break;
+               }
+       }
+
+       fclose(f);
+       return o;
+}
diff --git a/examples/shared/libc3/src/c3stl.h b/examples/shared/libc3/src/c3stl.h
new file mode 100644 (file)
index 0000000..d8bd250
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+       c3stl.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3STL_H___
+#define __C3STL_H___
+
+struct c3object_t *
+c3stl_load(
+               const char * filename,
+               struct c3object_t * parent);
+
+#endif /* __C3STL_H___ */
diff --git a/examples/shared/libc3/src/c3texture.c b/examples/shared/libc3/src/c3texture.c
new file mode 100644 (file)
index 0000000..9d9d427
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+       c3texture.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <stdio.h>
+#include "c3texture.h"
+#include "c3driver_geometry.h"
+
+void
+_c3texture_dispose(
+               c3geometry_p g,
+               const c3driver_geometry_t * d)
+{
+//     c3texture_p t = (c3texture_p)g;
+       C3_DRIVER_INHERITED(g, d, dispose);
+}
+
+void
+_c3texture_project(
+               c3geometry_p g,
+               const c3driver_geometry_t * d,
+               c3mat4p m)
+{
+       c3texture_p t = (c3texture_p)g;
+       c3pixels_p p = t->geometry.mat.texture;
+       if (!p) {
+               C3_DRIVER_INHERITED(g, d, project, m);
+               return;
+       }
+       c3vec2 qs = c3vec2f(
+                       t->size.x > 0 ? t->size.x : p->w,
+                       t->size.y > 0 ? t->size.y : p->h);
+       c3vec3 v[4] = {
+                       c3vec3f(0, 0, 0), c3vec3f(qs.x, 0, 0),
+                       c3vec3f(qs.x, qs.y, 0), c3vec3f(0, qs.y, 0)
+       };
+       c3vertex_array_clear(&g->vertice);
+       c3vertex_array_realloc(&g->vertice, 4);
+       c3vertex_array_insert(&g->vertice, 0, v, 4);
+
+       c3f tw = p->normalize ? 1.0 : p->w,
+               th = p->normalize ? 1.0 : p->h;
+       c3vec2 ti[4] = {
+                       c3vec2f(0, th), c3vec2f(tw, th),
+                       c3vec2f(tw, 0), c3vec2f(0, 0)
+       };
+       if (p->trace)
+               printf("%s size %.0fx%.0f tex %.0fx%.0f\n", __func__, qs.x, qs.y, tw, th);
+       c3tex_array_clear(&t->geometry.textures);
+       c3tex_array_realloc(&t->geometry.textures, 4);
+       c3tex_array_insert(&t->geometry.textures, 0, ti, 4);
+
+       C3_DRIVER_INHERITED(g, d, project, m);
+}
+
+const c3driver_geometry_t c3texture_driver = {
+               .dispose = _c3texture_dispose,
+               .project = _c3texture_project,
+};
+const c3driver_geometry_t c3geometry_driver;
+
+c3texture_p
+c3texture_new(
+               struct c3object_t * o /* = NULL */)
+{
+       c3texture_p res = malloc(sizeof(*res));
+       return c3texture_init(res, o);
+}
+
+c3texture_p
+c3texture_init(
+               c3texture_p t,
+               struct c3object_t * o /* = NULL */)
+{
+       memset(t, 0, sizeof(*t));
+       c3geometry_init(&t->geometry,
+                       c3geometry_type(C3_TEXTURE_TYPE, 0 /* GL_TRIANGLE_FAN */),
+                       o);
+       static const c3driver_geometry_t * list[] = {
+                       &c3texture_driver, &c3geometry_driver, NULL,
+       };
+       t->geometry.driver = list;
+
+       return t;
+}
+
+void
+c3texture_setpixels(
+               )
+{
+
+}
diff --git a/examples/shared/libc3/src/c3texture.h b/examples/shared/libc3/src/c3texture.h
new file mode 100644 (file)
index 0000000..1a3af62
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+       c3texture.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3TEXTURE_H___
+#define __C3TEXTURE_H___
+
+#include "c3geometry.h"
+#include "c3pixels.h"
+
+typedef struct c3texture_t {
+       c3geometry_t    geometry;
+//     c3pixels_t              pixels;
+//     int normalized : 1;     // use 0.. 1 texture coordinates
+       c3vec2 size;    // quad size
+} c3texture_t, *c3texture_p;
+
+c3texture_p
+c3texture_new(
+               struct c3object_t * parent /* = NULL */);
+c3texture_p
+c3texture_init(
+               c3texture_p t,
+               struct c3object_t * parent /* = NULL */);
+
+#endif /* __C3TEXTURE_H___ */
diff --git a/examples/shared/libc3/src/c3transform.c b/examples/shared/libc3/src/c3transform.c
new file mode 100644 (file)
index 0000000..a453ad7
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+       c3transform.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c3object.h"
+
+c3transform_p
+c3transform_new(
+               c3object_p o )
+{
+       c3transform_p res = malloc(sizeof(*res));
+       res->matrix = identity3D();
+       res->object = o;
+       res->name = NULL;
+       c3transform_array_add(&o->transform, res);
+       return res;
+}
+
+void
+c3transform_dispose(
+               c3transform_p t )
+{
+       if (t->object) {
+               for (int oi = 0; oi < t->object->transform.count; oi++)
+                       if (t->object->transform.e[oi] == t) {
+                               c3transform_array_delete(&t->object->transform, oi, 1);
+                               c3object_set_dirty(t->object, true);
+                               break;
+                       }
+               t->object = NULL;
+       }
+       str_free(t->name);
+       free(t);
+}
+
+void
+c3transform_set(
+               c3transform_p t,
+               const c3mat4p m )
+{
+       if (c3mat4_equal(m, &t->matrix))
+               return;
+       t->matrix = *m;
+       c3object_set_dirty(t->object, true);
+}
diff --git a/examples/shared/libc3/src/c3transform.h b/examples/shared/libc3/src/c3transform.h
new file mode 100644 (file)
index 0000000..63e8f38
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+       c3transform.h
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C3TRANSFORM_H___
+#define __C3TRANSFORM_H___
+
+#include "c3algebra.h"
+#include "c_utils.h"
+
+typedef struct c3transform_t {
+       str_p name;
+       struct c3object_t * object;
+       c3mat4  matrix;
+} c3transform_t, *c3transform_p;
+
+c3transform_p
+c3transform_new(
+               struct c3object_t * o );
+void
+c3transform_set(
+               c3transform_p t,
+               c3mat4p m );
+void
+c3transform_dispose(
+               c3transform_p t );
+
+DECLARE_C_ARRAY(c3transform_p, c3transform_array, 4);
+IMPLEMENT_C_ARRAY(c3transform_array);
+
+#endif /* __C3TRANSFORM_H___ */
diff --git a/examples/shared/libc3/src/c_array.h b/examples/shared/libc3/src/c_array.h
new file mode 100644 (file)
index 0000000..8c08efa
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+       c_array.h
+
+       Copyright 2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of gcodepp.
+
+       gcodepp 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 3 of the License, or
+       (at your option) any later version.
+
+       gcodepp 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 gcodepp.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __C_ARRAY_H___
+#define __C_ARRAY_H___
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef C_ARRAY_INLINE
+#define C_ARRAY_INLINE inline
+#endif
+#ifndef C_ARRAY_SIZE_TYPE
+#define C_ARRAY_SIZE_TYPE uint32_t
+#endif
+
+#define DECLARE_C_ARRAY(__type, __name, __page) \
+enum { __name##_page_size = __page }; \
+typedef __type __name##_element_t; \
+typedef C_ARRAY_SIZE_TYPE __name##_count_t; \
+typedef struct __name##_t {\
+       volatile __name##_count_t count;\
+       volatile __name##_count_t size;\
+       __name##_element_t * e;\
+} __name##_t, *__name##_p;
+
+#define C_ARRAY_NULL { 0, 0, NULL }
+
+#define IMPLEMENT_C_ARRAY(__name) \
+static const __name##_t __name##_zero = C_ARRAY_NULL; \
+static C_ARRAY_INLINE \
+       void __name##_free(\
+                       __name##_p a) \
+{\
+       if (!a) return;\
+       if (a->e) free(a->e);\
+       *a = __name##_zero;\
+}\
+static C_ARRAY_INLINE \
+       void __name##_clear(\
+                       __name##_p a) \
+{\
+       if (!a) return;\
+       a->count = 0;\
+}\
+static C_ARRAY_INLINE \
+       void __name##_realloc(\
+                       __name##_p a, __name##_count_t size) \
+{\
+       if (!a || a->size == size) return; \
+       a->e = realloc(a->e, size * sizeof(__name##_element_t));\
+       a->size = size; \
+}\
+static C_ARRAY_INLINE \
+       void __name##_trim(\
+                       __name##_p a) \
+{\
+       if (!a) return;\
+       __name##_count_t n = a->count + __name##_page_size;\
+       n -= (n % __name##_page_size);\
+       if (n != a->size)\
+               __name##_realloc(a, n);\
+}\
+static C_ARRAY_INLINE \
+       __name##_element_t * __name##_get_ptr(\
+                       __name##_p a, __name##_count_t index) \
+{\
+       if (!a) return NULL;\
+       if (index > a->count) index = a->count;\
+       return index < a->count ? a->e + index : NULL;\
+}\
+static C_ARRAY_INLINE \
+       __name##_count_t __name##_add(\
+                       __name##_p a, __name##_element_t e) \
+{\
+       if (!a) return 0;\
+       if (a->count + 1 >= a->size)\
+               __name##_realloc(a, a->size + __name##_page_size);\
+       a->e[a->count++] = e;\
+       return a->count;\
+}\
+static C_ARRAY_INLINE \
+       __name##_count_t __name##_insert(\
+                       __name##_p a, __name##_count_t index, \
+                       __name##_element_t * e, __name##_count_t count) \
+{\
+       if (!a) return 0;\
+       if (index > a->count) index = a->count;\
+       if (a->count + count >= a->size) \
+               __name##_realloc(a, (((a->count + count) / __name##_page_size)+1) * __name##_page_size);\
+       if (index < a->count)\
+               memmove(&a->e[index + count], &a->e[index], \
+                               (a->count - index + count) * sizeof(__name##_element_t));\
+       memmove(&a->e[index], e, count * sizeof(__name##_element_t));\
+       a->count += count;\
+       return a->count;\
+}\
+static C_ARRAY_INLINE \
+       __name##_count_t __name##_delete(\
+                       __name##_p a, __name##_count_t index, __name##_count_t count) \
+{\
+       if (!a) return 0;\
+       if (index > a->count) index = a->count;\
+       if (index + count > a->count) \
+               count = a->count - index;\
+       if (count && a->count - index) { \
+               memmove(&a->e[index], &a->e[index + count], \
+                               (a->count - index - count) * sizeof(__name##_element_t));\
+       }\
+       a->count -= count;\
+       return a->count;\
+}
+
+#endif /* __C_ARRAY_H___ */
diff --git a/examples/shared/libc3/src/c_utils.c b/examples/shared/libc3/src/c_utils.c
new file mode 100644 (file)
index 0000000..e3bb673
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+       c_utils.c
+
+       Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr 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 3 of the License, or
+       (at your option) any later version.
+
+       simavr 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 simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "c_utils.h"
+
+void
+str_hash_init(str_hash_p h)
+{
+       memset(h, 0, sizeof(*h));
+}
+
+void
+str_hash_add(
+       str_hash_p h,
+       str_p k,
+       void * v)
+{
+       uint16_t hv = str_hash(k);
+       hashval_array_p bin = &h->bin[hv & (STR_HASH_SIZE-1)];
+       int inserti = bin->count;
+
+       for (int i = 0; i < bin->count; i++)
+               if (bin->e[i].key->hash >= hv) {
+                       inserti = i;
+                       break;
+               }
+       str_hashval_t n = { .key = str_dup(k), .val = v };
+       hashval_array_insert(bin, inserti, &n, 1);
+       return;
+}
+
+void *
+str_hash_lookup(
+       str_hash_p h,
+       str_p k )
+{
+       uint16_t hv = str_hash(k);
+       hashval_array_p bin = &h->bin[hv & (STR_HASH_SIZE-1)];
+
+       for (int i = 0; i < bin->count; i++) {
+               uint16_t h = bin->e[i].key->hash;
+               if (h == hv && !str_cmp(k, bin->e[i].key))
+                       return bin->e[i].val;
+               else if (h > hv)
+                       break;
+       }
+       return NULL;
+}
diff --git a/examples/shared/libc3/src/c_utils.h b/examples/shared/libc3/src/c_utils.h
new file mode 100644 (file)
index 0000000..2360fd8
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+       c_utils.h
+
+       Copyright 2008-11 Michel Pollet <buserror@gmail.com>
+
+       This program cross examines a root filesystem, loads all the elf
+       files it can find, see what other library they load and then
+       find the orphans. In then remove the orphans as "user" for it's
+       dependencies and continues removing until everything has at least
+       one user, OR is a program itself (ie, not a shared library)
+
+       cross_linker 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 3 of the License, or
+       (at your option) any later version.
+
+       cross_linker 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 cross_linker.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __C_UTILS_H__
+#define __C_UTILS_H__
+
+#ifndef NO_ALLOCA
+#include <alloca.h>
+#endif
+#include "c_array.h"
+
+/********************************************************************
+ * CRC16
+ ********************************************************************/
+
+static uint8_t _crc16_lh[16] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
+        0x70, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1 };
+static uint8_t _crc16_ll[16] = { 0x00, 0x21, 0x42, 0x63, 0x84, 0xA5, 0xC6,
+        0xE7, 0x08, 0x29, 0x4A, 0x6B, 0x8C, 0xAD, 0xCE, 0xEF };
+
+static uint16_t crc16_u4(uint16_t crc, uint8_t val)
+{
+       uint8_t h = crc >> 8, l = crc & 0xff;
+       uint8_t t = (h >> 4) ^ val;
+
+       // Shift the CRC Register left 4 bits
+       h = (h << 4) | (l >> 4);
+       l = l << 4;
+       // Do the table lookups and XOR the result into the CRC Tables
+       h = h ^ _crc16_lh[t];
+       l = l ^ _crc16_ll[t];
+       return (h << 8) | l;
+}
+
+static uint16_t crc16_update(uint16_t crc, uint8_t val)
+{
+       crc = crc16_u4(crc, val >> 4); // High nibble first
+       crc = crc16_u4(crc, val & 0x0F); // Low nibble
+       return crc;
+}
+
+static uint16_t crc16_string(char * str)
+{
+       uint16_t crc = 0xffff;
+       while (*str)
+               crc = crc16_update(crc, *str++);
+       return crc;
+}
+
+/********************************************************************
+ * Hashed strings
+ ********************************************************************/
+
+#include <string.h>
+typedef struct str_t {
+       uint32_t hash : 16, rom : 1,  len : 15;
+       char str[0];
+} str_t, *str_p;
+
+static inline str_p str_new_i(const char *s, void * (*_alloc)(size_t))
+{
+       int l = s ? strlen(s) : 0;
+       str_p r = (str_p)_alloc(sizeof(*r) + l + 1);
+       r->hash = 0; r->len = l;
+       if (s)
+               strcpy(r->str, s);
+       return r;
+}
+static inline void str_free(str_p s)
+{
+       if (s && !s->rom)
+               free(s);
+}
+static inline str_p str_new(const char *s)
+{
+       return str_new_i(s, malloc);
+}
+static inline str_p str_anew(const char *s)
+{
+       str_p r = str_new_i(s, alloca);
+       r->rom = 1;
+       return r;
+}
+static inline str_p str_dup(const str_p s)
+{
+       size_t l = sizeof(*s) + s->len + 1;
+       str_p r = (str_p)malloc(l);
+       memcpy(r, s, l);
+       return r;
+}
+#ifndef NO_ALLOCA
+static inline str_p str_adup(const str_p s)
+{
+       size_t l = sizeof(*s) + s->len + 1;
+       str_p r = (str_p)alloca(l);
+       memcpy(r, s, l);
+       r->rom = 1;
+       return r;
+}
+#endif
+static inline uint16_t str_hash(str_p s)
+{
+       if (!s->hash) s->hash = crc16_string(s->str);
+       return s->hash;
+}
+static inline int str_cmp(str_p s1, str_p s2)
+{
+       if (s1 == s2) return 1;
+       if (s1->len != s2->len) return 1;
+       str_hash(s1);
+       str_hash(s2);
+       return s1->hash == s2->hash ? strcmp(s1->str, s2->str) : 1;
+}
+
+/********************************************************************
+ * Hash table of strings. Key/value pair
+ ********************************************************************/
+
+typedef struct str_hashval_t {
+       str_p key;
+       void * val;
+} str_hashval_t;
+
+DECLARE_C_ARRAY(str_hashval_t, hashval_array, 16);
+IMPLEMENT_C_ARRAY(hashval_array);
+
+#ifndef STR_HASH_SIZE
+#define STR_HASH_SIZE  512     // use 9 bits of the 16 of the CRC
+#endif
+/* uses bins to store the strings as per their hash values */
+typedef struct str_hash_t {
+       hashval_array_t bin[STR_HASH_SIZE];
+} str_hash_t, *str_hash_p;
+
+void
+str_hash_init(
+               str_hash_p h);
+void
+str_hash_add(
+       str_hash_p h, 
+       str_p k, 
+       void * v);
+
+void *
+str_hash_lookup(
+       str_hash_p h, 
+       str_p k );
+
+#endif /* __C_UTILS_H__ */