Merge with trunk r37546
authorMiika Hamalainen <blender@miikah.org>
Thu, 16 Jun 2011 12:00:03 +0000 (12:00 +0000)
committerMiika Hamalainen <blender@miikah.org>
Thu, 16 Jun 2011 12:00:03 +0000 (12:00 +0000)
48 files changed:
release/datafiles/blenderbuttons
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_physics_common.py
release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py [new file with mode: 0644]
release/scripts/startup/bl_ui/space_time.py
source/blender/blenkernel/BKE_bvhutils.h
source/blender/blenkernel/BKE_dynamicpaint.h [new file with mode: 0644]
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/bvhutils.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/dynamicpaint.c [new file with mode: 0644]
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/intern/math_geom.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/datafiles/blenderbuttons.c
source/blender/editors/include/UI_icons.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/physics/physics_intern.h
source/blender/editors/physics/physics_ops.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_dynamicpaint_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_dynamicpaint.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_space.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/MOD_modifiertypes.h
source/blender/modifiers/intern/MOD_dynamicpaint.c [new file with mode: 0644]
source/blender/modifiers/intern/MOD_util.c
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/include/voxeldata.h
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/voxeldata.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index 9872e53585e5bb25ce843dbe0b029de7f7c4cd73..74a6667624d487755f313211276a659a6dd2d9f4 100644 (file)
Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ
index bf63c6071b99695bcf068a30a94785f9cb7fafe3..49ff0c6925b7dc08ec620219b0acfb5a06d9203f 100644 (file)
@@ -43,6 +43,7 @@ _modules = (
     "properties_particle",
     "properties_physics_cloth",
     "properties_physics_common",
+    "properties_physics_dynamicpaint",
     "properties_physics_field",
     "properties_physics_fluid",
     "properties_physics_smoke",
index 586675f2ca013e296701420253fc3ab07e484e94..a82c4a479b870101c3da67fa8ce2552c6bc36304 100644 (file)
@@ -229,6 +229,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
         row.prop(md, "mid_level")
         row.prop(md, "strength")
 
+    def DYNAMIC_PAINT(self, layout, ob, md):
+        layout.label(text="See Dynamic Paint panel.")
+
     def EDGE_SPLIT(self, layout, ob, md):
         split = layout.split()
 
index f7cf8da184033d6a7a1a17f2dd60e7ae8897bd31..8ec9ffd0b83f9331d26d5de910869b280949e75f 100644 (file)
@@ -64,6 +64,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, bpy.types.Panel):
         if(ob.type == 'MESH'):
             physics_add(self, col, context.collision, "Collision", 'COLLISION', 'MOD_PHYSICS', False)
             physics_add(self, col, context.cloth, "Cloth", 'CLOTH', 'MOD_CLOTH', True)
+            physics_add(self, col, context.dynamic_paint, "Dynamic Paint", 'DYNAMIC_PAINT', 'MOD_DYNAMICPAINT', True)
 
         col = split.column()
 
@@ -105,7 +106,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
 
         layout.label(text=cache.info)
     else:
-        if cachetype == 'SMOKE':
+        if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}:
             if not bpy.data.is_saved:
                 layout.label(text="Cache is disabled until the file is saved")
                 layout.enabled = False
@@ -117,17 +118,17 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
 
         row = layout.row(align=True)
 
-        if cachetype != 'PSYS':
+        if cachetype not in {'PSYS', 'DYNAMIC_PAINT'}:
             row.enabled = enabled
             row.prop(cache, "frame_start")
             row.prop(cache, "frame_end")
-        if cachetype not in {'SMOKE', 'CLOTH'}:
+        if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT'}:
             row.prop(cache, "frame_step")
             row.prop(cache, "use_quick_cache")
         if cachetype != 'SMOKE':
             layout.label(text=cache.info)
 
-        if cachetype != 'SMOKE':
+        if cachetype not in {'SMOKE', 'DYNAMIC_PAINT'}:
             split = layout.split()
             split.enabled = enabled and bpy.data.is_saved
 
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
new file mode 100644 (file)
index 0000000..96f9b10
--- /dev/null
@@ -0,0 +1,330 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+
+from bl_ui.properties_physics_common import (
+    point_cache_ui,
+    )
+
+class PhysicButtonsPanel():
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "physics"
+
+    @classmethod
+    def poll(cls, context):
+        ob = context.object
+        rd = context.scene.render
+        return (ob and ob.type == 'MESH') and (not rd.use_game_engine) and (context.dynamic_paint)
+
+
+class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Dynamic Paint"
+
+    def draw(self, context):
+        layout = self.layout
+
+        md = context.dynamic_paint
+        ob = context.object
+
+        if md:
+            layout.prop(md, "dynamicpaint_type", expand=True)
+
+            if md.dynamicpaint_type == 'CANVAS':
+                canvas = md.canvas_settings
+                surface = canvas.active_surface
+                row = layout.row()
+                row.template_list(canvas, "canvas_surfaces", canvas, "active_index", rows=2)
+
+                col = row.column(align=True)
+                col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
+                col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="")
+                
+                if surface:
+                    layout.prop(surface, "name")
+                    layout.prop(surface, "surface_format", expand=False)
+                    
+                    if surface.surface_format != "VERTEX":
+                        col = layout.column()
+                        col.label(text="Quality:")
+                        col.prop(surface, "image_resolution")
+                        col.prop(surface, "use_anti_aliasing")
+                
+                    col = layout.column()
+                    col.label(text="Frames:")
+                    split = col.split()
+                
+                    col = split.column(align=True)
+                    col.prop(surface, "start_frame", text="Start")
+                    col.prop(surface, "end_frame", text="End")
+                
+                    col = split.column()
+                    col.prop(surface, "substeps")
+                
+
+            elif md.dynamicpaint_type == 'BRUSH':
+                brush = md.brush_settings
+                
+                layout.prop(brush, "brush_settings_context", expand=True, icon_only=True)
+                
+                if (brush.brush_settings_context == "GENERAL"):
+                    split = layout.split()
+
+                    col = split.column()
+                    col.prop(brush, "absolute_alpha")
+                    col.prop(brush, "paint_erase")
+                    col.prop(brush, "paint_wetness", text="Wetness")
+                
+                    col = split.column()
+                    sub = col.column()
+                    sub.active = (brush.paint_source != "PSYS");
+                    sub.prop(brush, "use_material")
+                    if brush.use_material and brush.paint_source != "PSYS":
+                        col.prop(brush, "material", text="")
+                        col.prop(brush, "paint_alpha", text="Alpha Factor")
+                    else:
+                        col.prop(brush, "paint_color", text="")
+                        col.prop(brush, "paint_alpha", text="Alpha")
+                
+                if (brush.brush_settings_context != "GENERAL"):
+                    layout.label(text="-WIP-")
+
+
+class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Dynamic Paint: Advanced"
+
+    @classmethod
+    def poll(cls, context):
+        md = context.dynamic_paint
+        return md and (md.dynamicpaint_type == 'CANVAS') and (context.dynamic_paint.canvas_settings.active_surface)
+
+    def draw(self, context):
+        layout = self.layout
+
+        canvas = context.dynamic_paint.canvas_settings
+        surface = canvas.active_surface
+        ob = context.object
+
+        layout.prop(surface, "surface_type", expand=False)
+
+        if (surface.surface_type == "PAINT"):
+            layout.prop(surface, "initial_color", expand=False)
+            col = layout.split(percentage=0.33)
+            col.prop(surface, "use_dissolve", text="Dissolve:")
+            sub = col.column()
+            sub.active = surface.use_dissolve
+            sub.prop(surface, "dissolve_speed", text="Time")
+
+        if (surface.surface_type == "DISPLACE"):
+            col = layout.split(percentage=0.33)
+            col.prop(surface, "use_dissolve", text="Flatten:")
+            sub = col.column()
+            sub.active = surface.use_dissolve
+            sub.prop(surface, "dissolve_speed", text="Time")
+            
+        layout.label(text="Brush Group:")
+        layout.prop(surface, "brush_group", text="")
+
+
+class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Dynamic Paint: Output"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        md = context.dynamic_paint
+        if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
+            return 0
+        surface = context.dynamic_paint.canvas_settings.active_surface
+        return (surface and (not (surface.surface_format=="VERTEX" and surface.surface_type=="DISPLACE") ))
+
+    def draw(self, context):
+        layout = self.layout
+
+        canvas = context.dynamic_paint.canvas_settings
+        surface = canvas.active_surface
+        ob = context.object
+        
+        # vertex format outputs
+        if (surface.surface_format == "VERTEX"):
+            if (surface.surface_type == "PAINT"):
+                row = layout.row()
+                row.prop_search(surface, "output_name", ob.data, "vertex_colors", text="Paintmap layer: ")
+                #col = row.column(align=True)
+                #col.operator("dpaint.output_add", icon='ZOOMIN', text="")
+                
+                row = layout.row()
+                row.prop_search(surface, "output_name2", ob.data, "vertex_colors", text="Wetmap layer: ")
+                #col = row.column(align=True)
+                #col.operator("dpaint.output_add", icon='ZOOMIN', text="")
+
+        # image format outputs
+        if (surface.surface_format == "IMAGE"):
+            col = layout.column()
+            col.label(text="UV layer:")
+            col.prop_search(surface, "uv_layer", ob.data, "uv_textures", text="")
+            
+            col = layout.column()
+            col.prop(surface, "image_output_path", text="Output directory")
+            if (surface.surface_type == "PAINT"):
+                col.prop(surface, "output_name", text="Paintmap: ")
+                col.prop(surface, "premultiply", text="Premultiply alpha")
+                col.prop(surface, "output_name2", text="Wetmap: ")
+            if (surface.surface_type == "DISPLACE"):
+                col.prop(surface, "output_name", text="Filename: ")
+            
+            layout.separator()
+            layout.operator("dpaint.bake", text="Bake Image Sequence", icon='MOD_DYNAMICPAINT')
+            if len(canvas.ui_info) != 0:
+                layout.label(text=canvas.ui_info)
+#            
+#            layout.separator()
+#
+#            col = layout.column()
+#            col.prop(surface, "output_wet")
+#            sub = col.column()
+#            sub.active = surface.output_wet
+#            sub.prop(surface, "wet_output_path", text="")
+#            
+#            layout.separator()
+#
+#            col = layout.column()
+#            col.prop(surface, "output_disp")
+#            sub = col.column()
+#            sub.active = surface.output_disp
+#            sub.prop(surface, "displace_output_path", text="")
+#            sub.prop(surface, "displacement", text="Strength")
+#
+#            split = sub.split()
+#            sub = split.column()
+#            sub.prop(surface, "disp_type", text="Type")
+#            sub = split.column()
+#            sub.prop(surface, "disp_format", text="Format")
+               
+
+class PHYSICS_PT_dp_effects(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Dynamic Paint: Effects"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        md = context.dynamic_paint
+        if ((not md) or (md.dynamicpaint_type != 'CANVAS')):
+            return False;
+        surface = context.dynamic_paint.canvas_settings.active_surface
+        return surface and (surface.surface_format != "VERTEX")
+
+    def draw(self, context):
+        layout = self.layout
+
+        canvas = context.dynamic_paint.canvas_settings
+        surface = canvas.active_surface
+
+        layout.prop(surface, "effect_ui", expand=True)
+
+        if surface.effect_ui == "SPREAD":
+            layout.prop(surface, "use_spread")
+            col = layout.column()
+            col.active = surface.use_spread
+            col.prop(surface, "spread_speed")
+
+        elif surface.effect_ui == "DRIP":
+            layout.prop(surface, "use_drip")
+            col = layout.column()
+            col.active = surface.use_drip
+            col.prop(surface, "drip_speed")
+
+        elif surface.effect_ui == "SHRINK":
+            layout.prop(surface, "use_shrink")
+            col = layout.column()
+            col.active = surface.use_shrink
+            col.prop(surface, "shrink_speed")
+                       
+
+class PHYSICS_PT_dp_cache(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Dynamic Paint: Cache"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        md = context.dynamic_paint
+        return md and (md.dynamicpaint_type == 'CANVAS') and \
+        (md.canvas_settings.active_surface) and (md.canvas_settings.active_surface.uses_cache)
+
+    def draw(self, context):
+        layout = self.layout
+
+        surface = context.dynamic_paint.canvas_settings.active_surface
+        cache = surface.point_cache
+        
+        point_cache_ui(self, context, cache, (cache.is_baked is False), 'DYNAMIC_PAINT')
+
+
+class PHYSICS_PT_dp_advanced_brush(PhysicButtonsPanel, bpy.types.Panel):
+    bl_label = "Dynamic Paint: Advanced"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        md = context.dynamic_paint
+        return md and (md.dynamicpaint_type == 'BRUSH')
+
+    def draw(self, context):
+        layout = self.layout
+
+        brush = context.dynamic_paint.brush_settings
+        ob = context.object
+               
+        split = layout.split()
+        col = split.column()
+        col.prop(brush, "paint_source")
+
+        if brush.paint_source == "PSYS":
+            col.prop_search(brush, "psys", ob, "particle_systems", text="")
+            if brush.psys:
+                col.label(text="Particle effect:")
+                sub = col.column()
+                sub.active = not brush.use_part_radius
+                sub.prop(brush, "solid_radius", text="Solid Radius")
+                col.prop(brush, "use_part_radius", text="Use Particle's Radius")
+                col.prop(brush, "smooth_radius", text="Smooth radius")
+
+        elif brush.paint_source == "DISTANCE" or brush.paint_source == "VOLDIST":
+            col.prop(brush, "paint_distance", text="Paint Distance")
+            split = layout.row().split()
+            sub = split.column()
+            sub.prop(brush, "prox_facealigned", text="Face Aligned")
+            sub = split.column()
+            sub.prop(brush, "prox_falloff", text="Falloff")
+            if brush.prox_falloff == "RAMP":
+                col = layout.row().column()
+                col.label(text="Falloff Ramp:")
+                col.prop(brush, "prox_ramp_alpha", text="Only Use Alpha")
+                col.template_color_ramp(brush, "paint_ramp", expand=True)
+
+def register():
+    bpy.utils.register_module(__name__)
+
+
+def unregister():
+    bpy.utils.register_module(__name__)
+
+if __name__ == "__main__":
+    register()
index 7e62465d1eef0cbb5155949757d7f4fa56c80351..d53a9c9a2a0dc990a735aeb3b79365ca5f6abbea 100644 (file)
@@ -134,6 +134,7 @@ class TIME_MT_cache(bpy.types.Menu):
         col.prop(st, "cache_particles")
         col.prop(st, "cache_cloth")
         col.prop(st, "cache_smoke")
+        col.prop(st, "cache_dynamicpaint")
 
 
 class TIME_MT_frame(bpy.types.Menu):
index 29487713ad4c4291e1a1c81df1147a20ab4e7fbd..8d373da689745aee6b3d355ae93639335f2d8187 100644 (file)
@@ -108,6 +108,11 @@ BVHTree* bvhtree_from_mesh_edges(struct BVHTreeFromMesh *data, struct DerivedMes
  */
 void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data);
 
+/*
+* Math functions used by callbacks
+*/
+float ray_tri_intersection(const BVHTreeRay *ray, const float m_dist, const float *v0, const float *v1, const float *v2);
+float nearest_point_in_tri_surface(const float *v0,const float *v1,const float *v2,const float *p, int *v, int *e, float *nearest );
 
 /*
  * BVHCache
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
new file mode 100644 (file)
index 0000000..791f218
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * Contributor(s): Miika Hämäläinen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_DYNAMIC_PAINT_H_
+#define BKE_DYNAMIC_PAINT_H_
+
+#include "DNA_dynamicpaint_types.h"
+
+/* Actual surface point        */
+typedef struct PaintSurfaceData {
+       /* surface format data */
+       void *format_data;
+       /* surface type data */
+       void *type_data;
+
+       unsigned int total_points;
+       short samples;
+
+} PaintSurfaceData;
+
+/* Paint type surface point    */
+typedef struct PaintPoint {
+
+       /* Wet paint is handled at effect layer only
+       *  and mixed to surface when drying */
+       float e_color[3];
+       float e_alpha;
+       float wetness;
+       short state;    /* -1 = doesn't exist (On UV mapped image
+                                       *           there can be points that doesn't exist on mesh surface)
+                                       *  0 = empty or dry
+                                       *  1 = wet paint
+                                       *  2 = new paint */
+       float color[3];
+       float alpha;
+} PaintPoint;
+
+/* iWave type surface point    */
+typedef struct PaintIWavePoint {               
+
+       float source;
+       float obstruction;
+       float height, previousHeight;
+
+       float foam;
+
+       float verticalDerivative;
+
+} PaintIWavePoint;
+
+struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
+void dynamicPaint_cacheUpdateFrames(struct DynamicPaintSurface *surface);
+int dynamicPaint_resetSurface(struct DynamicPaintSurface *surface);
+int dynamicPaint_surfaceHasPreview(DynamicPaintSurface *surface);
+void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface);
+void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, char *basename);
+void dynamicPaint_Modifier_free (struct DynamicPaintModifierData *pmd);
+void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd);
+void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tsmd);
+
+#endif /* BKE_DYNAMIC_PAINT_H_ */
index 346368a5958dbcba35bc55752248c60077843bbc..d7601b232c6dc8f363c7ea2c24993309f170bf22 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include "DNA_ID.h"
+#include "DNA_dynamicpaint_types.h"
 #include "DNA_object_force.h"
 #include "DNA_boid_types.h"
 #include <stdio.h> /* for FILE */
@@ -66,6 +67,7 @@
 #define PTCACHE_TYPE_CLOTH                             2
 #define PTCACHE_TYPE_SMOKE_DOMAIN              3
 #define PTCACHE_TYPE_SMOKE_HIGHRES             4
+#define PTCACHE_TYPE_DYNAMICPAINT              5
 
 /* high bits reserved for flags that need to be stored in file */
 #define PTCACHE_TYPEFLAG_COMPRESS              (1<<16)
@@ -90,6 +92,7 @@ struct PointCache;
 struct Scene;
 struct SmokeModifierData;
 struct SoftBody;
+struct DynamicPaintModifierData;
 
 /* temp structure for read/write */
 typedef struct PTCacheData {
@@ -139,7 +142,7 @@ typedef struct PTCacheID {
        /* copies point data to cache data */
        int (*write_stream)(PTCacheFile *pf, void *calldata);
        /* copies cache cata to point data */
-       void (*read_stream)(PTCacheFile *pf, void *calldata);
+       int (*read_stream)(PTCacheFile *pf, void *calldata);
 
        /* copies custom extradata to cache data */
        void (*write_extra_data)(void *calldata, struct PTCacheMem *pm, int cfra);
@@ -255,6 +258,7 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct Soft
 void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
 void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
 void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
+void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, struct Object *ob, struct DynamicPaintSurface *surface);
 
 void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob, struct Scene *scene, int duplis);
 
index 5078657588dc40ff36f0b975c68f5fc7d3c0c13b..8b6bca3805eb0d1cde081bd6e0897e7e75ee01ee 100644 (file)
@@ -94,6 +94,7 @@ set(SRC
        intern/deform.c
        intern/depsgraph.c
        intern/displist.c
+       intern/dynamicpaint.c
        intern/effect.c
        intern/fcurve.c
        intern/fluidsim.c
index cc45abb5998b61f9cf099d326789483be3f4906d..fa6a8239282338fef71845220e7f06717ace9480 100644 (file)
@@ -50,7 +50,7 @@
 
 /* Math stuff for ray casting on mesh faces and for nearest surface */
 
-static float ray_tri_intersection(const BVHTreeRay *ray, const float UNUSED(m_dist), const float *v0, const float *v1, const float *v2)
+float ray_tri_intersection(const BVHTreeRay *ray, const float UNUSED(m_dist), const float *v0, const float *v1, const float *v2)
 {
        float dist;
 
@@ -83,7 +83,7 @@ static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, con
  * Function adapted from David Eberly's distance tools (LGPL)
  * http://www.geometrictools.com/LibFoundation/Distance/Distance.html
  */
-static float nearest_point_in_tri_surface(const float *v0,const float *v1,const float *v2,const float *p, int *v, int *e, float *nearest )
+float nearest_point_in_tri_surface(const float *v0,const float *v1,const float *v2,const float *p, int *v, int *e, float *nearest )
 {
        float diff[3];
        float e0[3];
index 72ee9b55800ff13cc029f2d7d2982e16036fde3f..bf6fb15589673ca1590c8a8619d4517de06f49a5 100644 (file)
@@ -878,7 +878,9 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                                if(useColors && mc)
                                        cp = (unsigned char *)&mc[i * 4];
 
-                               glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+                               /* dont set shading mode to flat because
+                               *  normals are used to change shading */
+                               glShadeModel(GL_SMOOTH);
                                glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
 
                                if (!drawSmooth) {
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
new file mode 100644 (file)
index 0000000..79a4556
--- /dev/null
@@ -0,0 +1,3374 @@
+/**
+***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * Contributor(s): Miika Hämäläinen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_kdtree.h"
+#include "BLI_utildefines.h"
+
+/* Platform independend time   */
+#include "PIL_time.h"
+
+#include "BKE_animsys.h"
+#include "BKE_bvhutils.h"      /* bvh tree     */
+#include "BKE_blender.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_colortools.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_dynamicpaint.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_texture.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_dynamicpaint_types.h"
+#include "DNA_group_types.h" /*GroupObject*/
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h" /* to get temp file path        */
+
+/* for bake operator   */
+#include "ED_screen.h"
+#include "WM_types.h"
+#include "WM_api.h"
+
+/* for image output    */
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "BKE_image.h"
+#include "intern/IMB_filetype.h"
+#ifdef WITH_OPENEXR
+#include "intern/openexr/openexr_api.h"
+#endif
+
+/* uv validate */
+#include "intern/MOD_util.h"
+
+/* to read object material color       */
+#include "DNA_texture_types.h"
+#include "../render/intern/include/render_types.h"
+#include "../render/intern/include/voxeldata.h"
+#include "DNA_material_types.h"
+#include "RE_render_ext.h"
+
+
+#define DPOUTPUT_JPEG 0
+#define DPOUTPUT_PNG 1
+#define DPOUTPUT_OPENEXR 2
+
+struct Object;
+struct Scene;
+struct DerivedMesh;
+//struct DynamicPaintModifierData;
+
+/*
+*      Init predefined antialias jitter data
+*/
+float jitterDistances[5] = {0.0f,
+                                                       0.447213595f,
+                                                       0.447213595f,
+                                                       0.447213595f,
+                                                       0.5f};
+
+/* precalculated gaussian factors for 5x super sampling        */
+float gaussianFactors[5] = {   0.996849f,
+                                                               0.596145f,
+                                                               0.596145f,
+                                                               0.596145f,
+                                                               0.524141f};
+float gaussianTotal = 3.309425f;
+
+/*
+*      UV Image neighbouring pixel table x and y list
+*/
+int neighX[8] = {1,1,0,-1,-1,-1, 0, 1};
+int neighY[8] = {0,1,1, 1, 0,-1,-1,-1};
+
+static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe);
+static int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Object *cObject, int frame);
+
+/***************************** Internal Structs ***************************/
+
+typedef struct FaceAdv {
+       float no[3];
+       float no_q[3];
+} FaceAdv;
+
+typedef struct BB2d {
+       float min[2], max[2];
+} BB2d;
+
+typedef struct Vec3f {
+       float v[3];
+} Vec3f;
+
+/* Surface data used while processing a frame  */
+typedef struct PaintBakePoint {
+       float realCoord[3]; /* current pixel center world-space coordinates */
+       float invNorm[3];  /* current pixel world-space inverted normal. depends on face shading mode */
+       float normal_scale; /* normal directional scale for displace mapping */
+
+       /*
+       *       Effect / moving layer data
+       *       ! Only generated if effects enabled ! */                
+       float gravity_dir;      /* UV space direction of gravity */
+       float gravity_rate;             /* Gravity strength. (Depends on surface angle.) */
+} PaintBakePoint;
+
+/* UV Image sequence format point      */
+typedef struct PaintTexturePoint {
+
+       int neighbour[8];       /* Indexes of 8 neighbouring pixels if exist */
+       float neighbour_dist[8];        /*      Distances to all 8 neighbouring pixels */       
+
+
+       /* Pixel / mesh data */
+       int face_index, pixel_index;            /* face index on domain derived mesh */
+       int v1, v2, v3;         /* vertex indexes */
+
+       int neighbour_pixel;    /* If this pixel isn't uv mapped to any face,
+                                                       but it's neighbouring pixel is */
+       short quad;
+       struct Vec3f *barycentricWeights;       /* b-weights for all pixel samples */
+
+} PaintTexturePoint;
+
+/***************************** General Utils ******************************/
+
+/*
+*      Output error message to both ui and console
+*/
+static int printError(DynamicPaintCanvasSettings *canvas, char *string)
+{
+       if (strlen(string)>64) string[63] = '\0';
+
+       /* Add error to canvas ui info label */
+       sprintf(canvas->error, string);
+
+       /* Print console output */
+       printf("DynamicPaint bake failed: %s\n", canvas->error);
+
+       return 0;
+}
+
+/* Get number of surface points for cached types */
+static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
+{
+       if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) {
+               return 0; /* not supported atm */
+       }
+       else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+               if (!surface->canvas->dm) return 0; /* invalid derived mesh */
+               return surface->canvas->dm->getNumVerts(surface->canvas->dm);
+       }
+       else
+               return 0;
+}
+
+/* checks whether surface's format/type has realtime preview */
+int dynamicPaint_surfaceHasPreview(DynamicPaintSurface *surface) {
+       if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 0;
+       else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+               if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) return 0;
+               else return 1;
+       }
+       else return 1;
+}
+
+/* get currently active surface (in user interface) */
+static DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas)
+{
+       DynamicPaintSurface *surface = canvas->surfaces.first;
+       int i;
+
+       for(i=0; surface; surface=surface->next) {
+               if(i == canvas->active_sur)
+                       return surface;
+               i++;
+       }
+       return NULL;
+}
+
+/* set preview to first previewable surface */
+static void dynamicPaint_resetPreview(DynamicPaintCanvasSettings *canvas)
+{
+       DynamicPaintSurface *surface = canvas->surfaces.first;
+       int done=0;
+
+       for(; surface; surface=surface->next) {
+               if (!done && dynamicPaint_surfaceHasPreview(surface)) {
+                       surface->flags |= MOD_DPAINT_PREVIEW;
+                       done=1;
+               }
+               else
+                       surface->flags &= ~MOD_DPAINT_PREVIEW;
+       }
+}
+
+/* set preview to first previewable surface */
+static void dynamicPaint_setPreview(DynamicPaintSurface *t_surface)
+{
+       DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
+       for(; surface; surface=surface->next) {
+               if (surface == t_surface)
+                       surface->flags |= MOD_DPAINT_PREVIEW;
+               else
+                       surface->flags &= ~MOD_DPAINT_PREVIEW;
+       }
+}
+
+/* change surface data to defaults on new type */
+void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) {
+       if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
+               surface->output_name[0]='\0';
+               surface->output_name2[0]='\0';
+       }
+       else {
+               sprintf(surface->output_name, "dp_");
+               strcpy(surface->output_name2,surface->output_name);
+       }
+
+       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+               strcat(surface->output_name,"paintmap");
+               strcat(surface->output_name2,"wetmap");
+       }
+       else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+               strcat(surface->output_name,"displace");
+       }
+       else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+               strcat(surface->output_name,"weight");
+       }
+       else if (surface->type == MOD_DPAINT_SURFACE_T_IWAVE) {
+               strcat(surface->output_name,"iwave");
+               strcat(surface->output_name2,"foam");
+       }
+
+       /* update preview */
+       if (dynamicPaint_surfaceHasPreview(surface))
+               dynamicPaint_setPreview(surface);
+       else
+               dynamicPaint_resetPreview(surface->canvas);
+}
+
+static int surfaceDublicateNameExists(void *arg, const char *name)
+{
+       DynamicPaintSurface *t_surface = (DynamicPaintSurface*)arg;
+       DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
+
+       for(; surface; surface=surface->next) {
+               if (surface!=t_surface && !strcmp(name, surface->name)) return 1;
+       }
+       return 0;
+}
+
+void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, char *basename) {
+       char name[64];
+       strncpy(name, basename, 62); /* in case basename is surface->name use a copy */
+       BLI_uniquename_cb(surfaceDublicateNameExists, surface, name, '.', surface->name, sizeof(surface->name));
+}
+
+/***************************** Freeing data ******************************/
+
+/* Free brush data */
+static void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd)
+{
+       if(pmd->brush) {
+               if(pmd->brush->dm)
+                       pmd->brush->dm->release(pmd->brush->dm);
+               pmd->brush->dm = NULL;
+
+               if(pmd->brush->paint_ramp)
+                        MEM_freeN(pmd->brush->paint_ramp);
+               pmd->brush->paint_ramp = NULL;
+
+               MEM_freeN(pmd->brush);
+               pmd->brush = NULL;
+       }
+}
+
+static void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
+{
+       PaintSurfaceData *data = surface->data;
+       if (!data) return;
+
+       if (data->format_data) MEM_freeN(data->format_data);
+       if (data->type_data) MEM_freeN(data->type_data);
+
+       MEM_freeN(surface->data);
+       surface->data = NULL;
+}
+
+static void dynamicPaint_freeSurface(DynamicPaintSurface *surface)
+{
+       if (!surface) return;
+
+       /* point cache */
+       BKE_ptcache_free_list(&(surface->ptcaches));
+       surface->pointcache = NULL;
+
+       BLI_remlink(&(surface->canvas->surfaces), surface);
+       dynamicPaint_freeSurfaceData(surface);
+       MEM_freeN(surface);
+}
+
+/* Free canvas data */
+static void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd)
+{
+       if(pmd->canvas) {
+               /* Free surface data */
+               DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+               DynamicPaintSurface *next_surface = NULL;
+
+               while (surface) {
+                       next_surface = surface->next;
+                       dynamicPaint_freeSurface(surface);
+                       surface = next_surface;
+               }
+
+               /* free dm copy */
+               if (pmd->canvas->dm)
+                       pmd->canvas->dm->release(pmd->canvas->dm);
+               pmd->canvas->dm = NULL;
+
+               MEM_freeN(pmd->canvas);
+               pmd->canvas = NULL;
+       }
+}
+
+/* Free whole dp modifier */
+void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd)
+{
+       if(pmd) {
+               dynamicPaint_freeCanvas(pmd);
+               dynamicPaint_freeBrush(pmd);
+       }
+}
+
+
+/***************************** Initialize and reset ******************************/
+
+/*
+*      Creates a new surface and adds it to the list
+*      A pointer to this surface is returned
+*/
+static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas)
+{
+       DynamicPaintSurface *surface= MEM_callocN(sizeof(DynamicPaintSurface), "DynamicPaintSurface");
+       if (!surface) return NULL;
+
+       surface->canvas = canvas;
+       surface->format = MOD_DPAINT_SURFACE_F_VERTEX;
+       surface->type = MOD_DPAINT_SURFACE_T_PAINT;
+
+       /* cache */
+       surface->pointcache = BKE_ptcache_add(&(surface->ptcaches));
+       surface->pointcache->flag |= PTCACHE_DISK_CACHE;
+       surface->pointcache->step = 1;
+
+       /* Set initial values */
+       surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW;
+       surface->effect = 0;
+       surface->effect_ui = 1;
+
+       surface->diss_speed = 300;
+       surface->dry_speed = 300;
+       surface->disp_depth = 1.0f;
+       surface->disp_type = MOD_DPAINT_DISP_DISPLACE;
+       surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG;
+
+       surface->image_resolution = 256;
+       surface->start_frame = 1;
+       surface->end_frame = 250;
+       surface->substeps = 0;
+
+       surface->spread_speed = 1.0f;
+       surface->drip_speed = 1.0f;
+       surface->shrink_speed = 1.0f;
+
+       sprintf(surface->image_output_path, "%sdynamicpaint/", "/tmp/");
+       dynamicPaintSurface_setUniqueName(surface, "Surface");
+
+
+       dynamicPaintSurface_updateType(surface);
+
+       BLI_addtail(&canvas->surfaces, surface);
+
+       return surface;
+}
+
+/*
+*      Initialize modifier data
+*/
+void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd)
+{
+       if(pmd)
+       {
+               if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+               {
+                       if(pmd->canvas)
+                               dynamicPaint_freeCanvas(pmd);
+
+                       pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas");
+                       pmd->canvas->pmd = pmd;
+                       pmd->canvas->dm = NULL;
+
+                       /* Create one surface */
+                       dynamicPaint_createNewSurface(pmd->canvas);
+
+                       pmd->canvas->ui_info[0] = '\0';
+
+               }
+               else if(pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH)
+               {
+                       if(pmd->brush)
+                               dynamicPaint_freeBrush(pmd);
+
+                       pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint");
+                       pmd->brush->pmd = pmd;
+
+                       pmd->brush->psys = NULL;
+
+                       pmd->brush->flags = 0;
+                       pmd->brush->collision = MOD_DPAINT_COL_VOLUME;
+                       
+                       pmd->brush->mat = NULL;
+                       pmd->brush->r = 1.0f;
+                       pmd->brush->g = 1.0f;
+                       pmd->brush->b = 1.0f;
+                       pmd->brush->alpha = 1.0f;
+                       pmd->brush->wetness = 1.0f;
+
+                       pmd->brush->paint_distance = 0.1f;
+                       pmd->brush->proximity_falloff = MOD_DPAINT_PRFALL_SHARP;
+
+                       pmd->brush->displace_distance = 0.5f;
+                       pmd->brush->prox_displace_strength = 0.5f;
+
+                       pmd->brush->particle_radius = 0.2;
+                       pmd->brush->particle_smooth = 0.05;
+
+                       pmd->brush->dm = NULL;
+
+                       /*
+                       *       Paint proximity falloff colorramp.
+                       */
+                       {
+                               CBData *ramp;
+
+                               pmd->brush->paint_ramp = add_colorband(0);
+                               ramp = pmd->brush->paint_ramp->data;
+                               /* Add default smooth-falloff ramp.     */
+                               ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
+                               ramp[0].pos = 0.0f;
+                               ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].pos = 1.0f;
+                               ramp[1].a = 0.0f;
+                               pmd->brush->paint_ramp->tot = 2;
+                       }
+               }
+       }
+}
+
+void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tpmd)
+{
+       /* Init modifier        */
+       tpmd->type = pmd->type;
+       dynamicPaint_Modifier_createType(tpmd);
+
+       /* Copy data    */
+       if (tpmd->canvas) {
+               pmd->canvas->pmd = tpmd;
+
+               tpmd->canvas->ui_info[0] = '\0';
+
+               /*tpmd->canvas->flags = pmd->canvas->flags;
+               tpmd->canvas->output = pmd->canvas->output;
+               tpmd->canvas->disp_type = pmd->canvas->disp_type;
+               tpmd->canvas->disp_format = pmd->canvas->disp_format;
+               tpmd->canvas->effect = pmd->canvas->effect;
+               tpmd->canvas->effect_ui = 1;
+
+               tpmd->canvas->resolution = pmd->canvas->resolution;
+               tpmd->canvas->start_frame = pmd->canvas->start_frame;
+               tpmd->canvas->end_frame = pmd->canvas->end_frame;
+               tpmd->canvas->substeps = pmd->canvas->substeps;
+
+               tpmd->canvas->dry_speed = pmd->canvas->dry_speed;
+               tpmd->canvas->diss_speed = pmd->canvas->diss_speed;
+               tpmd->canvas->disp_depth = pmd->canvas->disp_depth;
+               tpmd->canvas->dflat_speed = pmd->canvas->dflat_speed;
+
+               strncpy(tpmd->canvas->paint_output_path, pmd->canvas->paint_output_path, 240);
+               strncpy(tpmd->canvas->wet_output_path, pmd->canvas->wet_output_path, 240);
+               strncpy(tpmd->canvas->displace_output_path, pmd->canvas->displace_output_path, 240);
+
+               tpmd->canvas->spread_speed = pmd->canvas->spread_speed;
+               tpmd->canvas->drip_speed = pmd->canvas->drip_speed;
+               tpmd->canvas->shrink_speed = pmd->canvas->shrink_speed;
+
+               strncpy(tpmd->canvas->uvlayer_name, tpmd->canvas->uvlayer_name, 32);*/
+
+       } else if (tpmd->brush) {
+               pmd->brush->pmd = tpmd;
+
+               tpmd->brush->flags = pmd->brush->flags;
+               tpmd->brush->collision = pmd->brush->collision;
+
+               tpmd->brush->r = pmd->brush->r;
+               tpmd->brush->g = pmd->brush->g;
+               tpmd->brush->b = pmd->brush->b;
+               tpmd->brush->alpha = pmd->brush->alpha;
+               tpmd->brush->wetness = pmd->brush->wetness;
+
+               tpmd->brush->particle_radius = pmd->brush->particle_radius;
+               tpmd->brush->particle_smooth = pmd->brush->particle_smooth;
+               tpmd->brush->paint_distance = pmd->brush->paint_distance;
+               tpmd->brush->psys = pmd->brush->psys;
+               tpmd->brush->displace_distance = pmd->brush->displace_distance;
+               tpmd->brush->prox_displace_strength = pmd->brush->prox_displace_strength;
+
+               tpmd->brush->paint_ramp = pmd->brush->paint_ramp;
+
+               tpmd->brush->proximity_falloff = pmd->brush->proximity_falloff;
+       }
+}
+
+/* allocates surface data depending on surface type */
+static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface)
+{
+       PaintSurfaceData *sData = surface->data;
+
+       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+               sData->type_data = MEM_callocN(sizeof(PaintPoint)*sData->total_points, "DynamicPaintSurface Data");
+       }
+       else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+               sData->type_data = MEM_callocN(sizeof(float)*sData->total_points, "DynamicPaintSurface DepthData");
+       }
+       else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+               sData->type_data = MEM_callocN(sizeof(float)*sData->total_points, "DynamicPaintSurface WeightData");
+       }
+       else if (surface->type == MOD_DPAINT_SURFACE_T_IWAVE) {
+               sData->type_data = MEM_callocN(sizeof(PaintIWavePoint)*sData->total_points, "DynamicPaintSurface iWaveData");
+       }
+       else return;
+
+       if (sData->type_data == NULL) printError(surface->canvas, "Not enough memory!");
+}
+
+static void dynamicPaint_surfaceSetInitialValues(DynamicPaintSurface *surface) {
+       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+               PaintPoint* pPoint = (PaintPoint*)surface->data->type_data;
+               int i;
+               for (i=0; i<surface->data->total_points; i++) {
+                       memcpy(pPoint[i].color, surface->intitial_color, sizeof(float)*4);
+               }
+       }
+}
+
+/* (re)initialize surface data (only for point cache types)*/
+int dynamicPaint_resetSurface(DynamicPaintSurface *surface)
+{
+       int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface);
+       /* dont touch image sequence types. they get handled only on bake */
+       if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1;
+
+       if (surface->data) dynamicPaint_freeSurfaceData(surface);
+       if (numOfPoints < 1) return 0;
+
+       /* allocate memory */
+       surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
+       if (!surface->data) return 0;
+
+       /* allocate data depending on surface type and format */
+       surface->data->total_points = numOfPoints;
+       dynamicPaint_allocateSurfaceType(surface);
+       dynamicPaint_surfaceSetInitialValues(surface);
+
+       return 1;
+}
+
+/* make sure allocated surface size matches current requirements */
+static void dynamicPaint_checkSurfaceData(DynamicPaintSurface *surface)
+{
+       if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) {
+               dynamicPaint_resetSurface(surface);
+       }
+}
+
+
+/***************************** Modifier processing ******************************/
+
+
+/* update cache frame range */
+void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) {
+       if (surface->pointcache) {
+               surface->pointcache->startframe = surface->start_frame;
+               surface->pointcache->endframe = surface->end_frame;
+       }
+}
+
+/*
+*      Updates derived mesh copy and processes dynamic paint step / caches.
+*/
+static void dynamicPaint_canvasUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+{
+       if((pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS) && pmd->canvas) {
+               DynamicPaintCanvasSettings *canvas = pmd->canvas;
+               DynamicPaintSurface *surface = canvas->surfaces.first;
+
+               /* update derived mesh copy */
+               if (canvas->dm) canvas->dm->release(canvas->dm);
+                       canvas->dm = CDDM_copy(dm);
+
+               /* in case image sequence baking, stop here */
+               if (canvas->flags & MOD_DPAINT_BAKING) return;
+
+               /* loop through surfaces */
+               for (; surface; surface=surface->next) {
+                       int current_frame = (int)scene->r.cfra;
+
+                       /* image sequences are handled by bake operator */
+                       if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) continue;
+                       if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue;
+
+                       /* make sure surface is valid */
+                       dynamicPaint_checkSurfaceData(surface);
+
+                       /* limit frame range */
+                       CLAMP(current_frame, surface->start_frame, surface->end_frame);
+
+                       if (current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
+                               PointCache *cache = surface->pointcache;
+                               PTCacheID pid;
+                               surface->current_frame = current_frame;
+
+                               /* read point cache */
+                               BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
+                               pid.cache->startframe = surface->start_frame;
+                               pid.cache->endframe = surface->end_frame;
+                               BKE_ptcache_id_time(&pid, scene, scene->r.cfra, NULL, NULL, NULL);
+
+                               /* reset non-baked cache at first frame */
+                               if((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED))
+                               {
+                                       cache->flag |= PTCACHE_REDO_NEEDED;
+                                       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+                                       cache->flag &= ~PTCACHE_REDO_NEEDED;
+                               }
+
+                               /* try to read from cache */
+                               if(BKE_ptcache_read(&pid, (float)scene->r.cfra)) {
+                                       BKE_ptcache_validate(cache, (int)scene->r.cfra);
+                               }
+                               /* if read failed and we're on surface range do recalculate */
+                               else if ((int)scene->r.cfra == current_frame) {
+                                       /* calculate surface frame */
+                                       dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
+
+                                       BKE_ptcache_validate(cache, surface->current_frame);
+                                       BKE_ptcache_write(&pid, surface->current_frame);
+                               }
+                       }
+               }
+       }
+       else if((pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd->brush) {
+
+               if (pmd->brush->dm) pmd->brush->dm->release(pmd->brush->dm);
+               pmd->brush->dm = CDDM_copy(dm);
+       }
+}
+
+/*
+*      Apply canvas data to the object derived mesh
+*/
+struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+{      
+       DerivedMesh *result = CDDM_copy(dm);
+
+       if((pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS) && pmd->canvas &&
+               !(pmd->canvas->flags & MOD_DPAINT_BAKING)) {
+
+               DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+               pmd->canvas->flags &= ~MOD_DPAINT_PREVIEW_READY;
+
+               /* loop through surfaces */
+               for (; surface; surface=surface->next) {
+
+                       if (surface && surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
+                               if (!(surface->flags & (MOD_DPAINT_ACTIVE))) continue;
+
+                               /* process vertex surface previews */
+                               if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+
+                                       /* vertex color paint */
+                                       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+
+                                               MFace *mface = result->getFaceArray(result);
+                                               int numOfFaces = result->getNumFaces(result);
+                                               int i,j;
+                                               PaintPoint* pPoint = (PaintPoint*)surface->data->type_data;
+                                               MCol *col;
+
+                                               /* paint is stored on dry and wet layers, so mix final color first */
+                                               float *fcolor = MEM_callocN(sizeof(float)*surface->data->total_points*4, "Temp paint color");
+                                               for (i=0; i<surface->data->total_points; i++) {
+                                                       j=i*4;
+                                                       /* If dry layer already has a color, blend it */
+                                                       if (pPoint[i].alpha) {
+                                                               float invAlpha = 1.0f - pPoint[i].e_alpha;
+                                                               fcolor[j]   = pPoint[i].color[0] * invAlpha + pPoint[i].e_color[0] * pPoint[i].e_alpha;
+                                                               fcolor[j+1] = pPoint[i].color[1] * invAlpha + pPoint[i].e_color[1] * pPoint[i].e_alpha;
+                                                               fcolor[j+2] = pPoint[i].color[2] * invAlpha + pPoint[i].e_color[2] * pPoint[i].e_alpha;
+                                                       }
+                                                       else {
+                                                               /* Else use effect layer color  */
+                                                               fcolor[j]   = pPoint[i].e_color[0];
+                                                               fcolor[j+1] = pPoint[i].e_color[1];
+                                                               fcolor[j+2] = pPoint[i].e_color[2];
+                                                       }
+                                                       /* Set use highest alpha        */
+                                                       fcolor[j+3] = (pPoint[i].e_alpha > pPoint[i].alpha) ? pPoint[i].e_alpha : pPoint[i].alpha;
+                                               }
+
+                                               /* viewport preview */
+                                               if (surface->flags & MOD_DPAINT_PREVIEW) {
+                                                       /* Save preview results to weight layer, to be
+                                                       *   able to share same drawing methods */
+                                                       col = result->getFaceDataArray(result, CD_WEIGHT_MCOL);
+                                                       if (!col) col = CustomData_add_layer(&result->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numOfFaces);
+
+                                                       if (col) {
+                                                               for (i=0; i<numOfFaces; i++) {
+                                                                       int j=0;
+                                                                       float invAlpha;
+                                                                       Material *material = give_current_material(ob, mface[i].mat_nr+1);
+
+                                                                       for (; j<((mface[i].v4)?4:3); j++) {
+                                                                               int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
+                                                                               index *= 4;
+                                                                               invAlpha = 1.0f - fcolor[index+3];
+
+                                                                               /* Apply material color as base vertex color for preview */
+                                                                               col[i*4+j].a = 255;
+                                                                               if (material) {
+                                                                                       col[i*4+j].r = (unsigned char)(material->b*255);
+                                                                                       col[i*4+j].g = (unsigned char)(material->g*255);
+                                                                                       col[i*4+j].b = (unsigned char)(material->r*255);
+                                                                               }
+                                                                               else {
+                                                                                       col[i*4+j].r = 165;
+                                                                                       col[i*4+j].g = 165;
+                                                                                       col[i*4+j].b = 165;
+                                                                               }
+
+                                                                               /* mix surface color */
+                                                                               col[i*4+j].r = (char)(((float)col[i*4+j].r)*invAlpha + (fcolor[index+2]*255*fcolor[index+3]));
+                                                                               col[i*4+j].g = (char)(((float)col[i*4+j].g)*invAlpha + (fcolor[index+1]*255*fcolor[index+3]));
+                                                                               col[i*4+j].b = (char)(((float)col[i*4+j].b)*invAlpha + (fcolor[index]*255*fcolor[index+3]));
+                                                                       }
+                                                               }
+                                                               pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY;
+                                                       }
+                                               }
+
+
+                                               /* save layer data to output layer */
+
+                                               /* paint layer */
+                                               col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->output_name);
+                                               if (col) {
+                                                       for (i=0; i<numOfFaces; i++) {
+                                                               int j=0;
+                                                               for (; j<((mface[i].v4)?4:3); j++) {
+                                                                       int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
+                                                                       index *= 4;
+
+                                                                       col[i*4+j].a = (char)(fcolor[index+3]*255);
+                                                                       col[i*4+j].r = (char)(fcolor[index+2]*255);
+                                                                       col[i*4+j].g = (char)(fcolor[index+1]*255);
+                                                                       col[i*4+j].b = (char)(fcolor[index]*255);
+                                                               }
+                                                       }
+                                               }
+                                               MEM_freeN(fcolor);
+
+                                               /* wet layer */
+                                               col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->output_name2);
+                                               if (col) {
+                                                       for (i=0; i<numOfFaces; i++) {
+                                                               int j=0;
+
+                                                               for (; j<((mface[i].v4)?4:3); j++) {
+                                                                       int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
+
+                                                                       col[i*4+j].a = 255;
+                                                                       col[i*4+j].r = (char)(pPoint[index].wetness*255);
+                                                                       col[i*4+j].g = (char)(pPoint[index].wetness*255);
+                                                                       col[i*4+j].b = (char)(pPoint[index].wetness*255);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       /* displace paint */
+                                       else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+                                               MVert *mvert = result->getVertArray(result);
+                                               int i;
+                                               float normal[3];
+                                               float* value = (float*)surface->data->type_data;
+
+                                               for (i=0; i<surface->data->total_points; i++) {
+                                                       normal_short_to_float_v3(normal, mvert[i].no);
+                                                       normalize_v3(normal);
+
+                                                       mvert[i].co[0] -= normal[0]*value[i];
+                                                       mvert[i].co[1] -= normal[1]*value[i];
+                                                       mvert[i].co[2] -= normal[2]*value[i];
+                                               }
+
+                                               CDDM_calc_normals(result);
+                                       }
+                                       /* vertex group paint */
+                                       else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return result;
+}
+
+/* Modifier call. Processes dynamic paint modifier step. */
+struct DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
+{      
+       /* Update derived mesh data to modifier if baking       */
+       dynamicPaint_canvasUpdate(pmd, scene, ob, dm);
+
+       /* Return output mesh */
+       return dynamicPaint_Modifier_apply(pmd, scene, ob, dm);
+}
+
+
+/***************************** Image Sequence / UV Image Canvas Calls ******************************/
+
+#if 0
+/*
+*      Tries to find the neighbouring pixel in given (uv space) direction.
+*      Result is used by effect system to move paint on the surface.
+*
+*   px,py : origin pixel x and y
+*      n_index : lookup direction index (use neighX,neighY to get final index)
+*/
+static int dynamicPaint_findNeighbourPixel(DynamicPaintSurface *surface, int px, int py, int n_index)
+{
+       /* Note: Current method only uses polygon edges to detect neighbouring pixels.
+       *  -> It doesn't always lead to the optimum pixel but is accurate enough
+       *  and faster/simplier than including possible face tip point links)
+       */
+
+       int x,y;
+       DynamicPaintSurfacePoint *tPoint = NULL;
+       DynamicPaintSurfacePoint *cPoint = NULL;
+       PaintSurfaceData *sData = surface->data;
+
+       x = px + neighX[n_index];
+       y = py + neighY[n_index];
+
+       if (x<0 || x>=surface->image_resolution) return -1;
+       if (y<0 || y>=surface->image_resolution) return -1;
+
+       tPoint = &((PaintTexturePoint*)sData->format_data)[x+surface->image_resolution*y];              /* UV neighbour */
+       
+       cPoint = &((PaintTexturePoint*)sData->format_data)[px+surface->image_resolution*py];            /* Origin point */
+
+       /*
+       *       Check if target point is on same face -> mark it as neighbour
+       *   (and if it isn't marked as an "edge pixel")
+       */
+       if ((tPoint->index == cPoint->index) && (tPoint->neighbour_pixel == -1)) {
+               /* If it's on the same face, it has to be a correct neighbour   */
+               return (x+surface->w*y);
+       }
+
+
+       /*
+       *       If the uv neighbour is mapped directly to
+       *       a face -> use this point.
+       *       
+       *       !! Replace with "is uv faces linked" check !!
+       *       This should work fine as long as uv island
+       *       margin is > 1 pixel.
+       */
+       if ((tPoint->index != -1) && (tPoint->neighbour_pixel == -1)) {
+               return (x+surface->w*y);
+       }
+
+       /*
+       *       If we get here, the actual neighbouring pixel
+       *       points to a non-linked uv face, and we have to find
+       *       it's "real" neighbour.
+       *
+       *       Simple neighbouring face finding algorithm:
+       *       - find closest uv edge to that pixel and get
+       *         the other face connected to that edge on actual mesh
+       *       - find corresponding position of that new face edge
+       *         in uv space
+       *
+       *       TODO: Implement something more accurate / optimized?
+       */
+       {
+               int numOfFaces = canvas->dm->getNumFaces(canvas->dm);
+               MVert *mvert = NULL;
+               MFace *mface = NULL;
+               MTFace *tface = NULL;
+
+               mvert = canvas->dm->getVertArray(canvas->dm);
+               mface = canvas->dm->getFaceArray(canvas->dm);
+               tface = DM_get_face_data_layer(canvas->dm, CD_MTFACE);
+
+               /* Get closest edge to that subpixel on UV map  */
+               {
+                       float pixel[2], dist, t_dist;
+                       int i, uindex[2], edge1_index, edge2_index, e1_index, e2_index, target_face;
+
+                       float closest_point[2], lambda, dir_vec[2];
+                       int target_uv1, target_uv2, final_pixel[2], final_index;
+
+                       float (*s_uv1),(*s_uv2), (*t_uv1), (*t_uv2);
+
+                       pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)surface->w;
+                       pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)surface->h;
+
+                       /* Get uv indexes for current face part */
+                       if (cPoint->quad) {
+                               uindex[0] = 0; uindex[1] = 2; uindex[2] = 3;
+                       }
+                       else {
+                               uindex[0] = 0; uindex[1] = 1; uindex[2] = 2;
+                       }
+
+                       /*
+                       *       Find closest edge to that pixel
+                       */
+                       /* Dist to first edge   */
+                       e1_index = cPoint->v1; e2_index = cPoint->v2; edge1_index = uindex[0]; edge2_index = uindex[1];
+                       dist = dist_to_line_segment_v2(pixel, tface[cPoint->index].uv[edge1_index], tface[cPoint->index].uv[edge2_index]);
+
+                       /* Dist to second edge  */
+                       t_dist = dist_to_line_segment_v2(pixel, tface[cPoint->index].uv[uindex[1]], tface[cPoint->index].uv[uindex[2]]);
+                       if (t_dist < dist) {e1_index = cPoint->v2; e2_index = cPoint->v3; edge1_index = uindex[1]; edge2_index = uindex[2]; dist = t_dist;}
+
+                       /* Dist to third edge   */
+                       t_dist = dist_to_line_segment_v2(pixel, tface[cPoint->index].uv[uindex[2]], tface[cPoint->index].uv[uindex[0]]);
+                       if (t_dist < dist) {e1_index = cPoint->v3; e2_index = cPoint->v1;  edge1_index = uindex[2]; edge2_index = uindex[0]; dist = t_dist;}
+
+
+                       /*
+                       *       Now find another face that is linked to that edge
+                       */
+                       target_face = -1;
+
+                       for (i=0; i<numOfFaces; i++) {
+                               /*
+                               *       Check if both edge vertices share this face
+                               */
+                               int v4 = -1;
+                               if (mface[i].v4) v4 = mface[i].v4;
+
+                               if ((e1_index == mface[i].v1 || e1_index == mface[i].v2 || e1_index == mface[i].v3 || e1_index == v4) &&
+                                       (e2_index == mface[i].v1 || e2_index == mface[i].v2 || e2_index == mface[i].v3 || e2_index == v4)) {
+                                       if (i == cPoint->index) continue;
+
+                                       target_face = i;
+
+                                       /*
+                                       *       Get edge UV index
+                                       */
+                                       if (e1_index == mface[i].v1) target_uv1 = 0;
+                                       else if (e1_index == mface[i].v2) target_uv1 = 1;
+                                       else if (e1_index == mface[i].v3) target_uv1 = 2;
+                                       else target_uv1 = 3;
+
+                                       if (e2_index == mface[i].v1) target_uv2 = 0;
+                                       else if (e2_index == mface[i].v2) target_uv2 = 1;
+                                       else if (e2_index == mface[i].v3) target_uv2 = 2;
+                                       else target_uv2 = 3;
+
+                                       break;
+                               }
+                       }
+
+                       /* If none found return -1      */
+                       if (target_face == -1) return -1;
+
+                       /*
+                       *       If target face is connected in UV space as well, just use original index
+                       */
+                       s_uv1 = (float *)tface[cPoint->index].uv[edge1_index];
+                       s_uv2 = (float *)tface[cPoint->index].uv[edge2_index];
+                       t_uv1 = (float *)tface[target_face].uv[target_uv1];
+                       t_uv2 = (float *)tface[target_face].uv[target_uv2];
+
+                       //printf("connected UV : %f,%f & %f,%f - %f,%f & %f,%f\n", s_uv1[0], s_uv1[1], s_uv2[0], s_uv2[1], t_uv1[0], t_uv1[1], t_uv2[0], t_uv2[1]);
+
+                       if (((s_uv1[0] == t_uv1[0] && s_uv1[1] == t_uv1[1]) &&
+                                (s_uv2[0] == t_uv2[0] && s_uv2[1] == t_uv2[1]) ) ||
+                               ((s_uv2[0] == t_uv1[0] && s_uv2[1] == t_uv1[1]) &&
+                                (s_uv1[0] == t_uv2[0] && s_uv1[1] == t_uv2[1]) )) return ((px+neighX[n_index]) + surface->w*(py+neighY[n_index]));
+
+                       /*
+                       *       Find a point that is relatively at same edge position
+                       *       on this other face UV
+                       */
+                       lambda = closest_to_line_v2(closest_point, pixel, tface[cPoint->index].uv[edge1_index], tface[cPoint->index].uv[edge2_index]);
+                       if (lambda < 0.0f) lambda = 0.0f;
+                       if (lambda > 1.0f) lambda = 1.0f;
+
+                       sub_v2_v2v2(dir_vec, tface[target_face].uv[target_uv2], tface[target_face].uv[target_uv1]);
+
+                       mul_v2_fl(dir_vec, lambda);
+
+                       copy_v2_v2(pixel, tface[target_face].uv[target_uv1]);
+                       add_v2_v2(pixel, dir_vec);
+                       pixel[0] = (pixel[0] * (float)surface->w) - 0.5f;
+                       pixel[1] = (pixel[1] * (float)surface->h) - 0.5f;
+
+                       final_pixel[0] = (int)floor(pixel[0]);
+                       final_pixel[1] = (int)floor(pixel[1]);
+
+                       /* If current pixel uv is outside of texture    */
+                       if (final_pixel[0] < 0 || final_pixel[0] >= surface->w) return -1;
+                       if (final_pixel[1] < 0 || final_pixel[1] >= surface->h) return -1;
+
+                       final_index = final_pixel[0] + surface->w * final_pixel[1];
+
+                       /* If we ended up to our origin point ( mesh has smaller than pixel sized faces)        */
+                       if (final_index == (px+surface->w*py)) return -1;
+                       /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces)   */
+                       if (surface->point[final_index].index != target_face) return -1;
+
+                       /*
+                       *       If final point is an "edge pixel", use it's "real" neighbour instead
+                       */
+                       if (surface->point[final_index].neighbour_pixel != -1) final_index = cPoint->neighbour_pixel;
+
+                       return final_index;
+               }
+       }
+}
+#endif
+
+/*
+*      Create a surface for image sequence format
+*/
+static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
+{
+       /* Antialias jitter point relative coords       */
+       float jitter5sample[10] =  {0.0f, 0.0f,
+                                                       -0.2f, -0.4f,
+                                                       0.2f, 0.4f,
+                                                       0.4f, -0.2f,
+                                                       -0.4f, 0.3f};
+       int yy;
+       int w,h;
+       int numOfFaces;
+       char uvname[32];
+       int active_points = 0;
+
+       PaintSurfaceData *sData;
+       DynamicPaintCanvasSettings *canvas = surface->canvas;
+       DerivedMesh *dm = canvas->dm;
+
+       PaintTexturePoint *tempPoints = NULL;
+       MVert *mvert = NULL;
+       MFace *mface = NULL;
+       MTFace *tface = NULL;
+       BB2d *faceBB = NULL;
+
+       if (!dm) return printError(canvas, "Canvas mesh not updated.");
+       if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) return printError(canvas, "Can't bake non-\"image sequence\" formats.");
+
+       numOfFaces = dm->getNumFaces(dm);
+       mvert = dm->getVertArray(dm);
+       mface = dm->getFaceArray(dm);
+
+       /* get uv layer */
+       validate_layer_name(&dm->faceData, CD_MTFACE, surface->uvlayer_name, uvname);
+       tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
+
+       /* Check for validity   */
+       if (!tface) return printError(canvas, "No UV data on canvas.");
+       if (surface->image_resolution < 16 || surface->image_resolution > 8096) return printError(canvas, "Invalid resolution.");
+
+       w = h = surface->image_resolution;
+
+       /*
+       *       Start generating the surface
+       */
+       printf("DynamicPaint: Preparing UV surface of %ix%i pixels and %i faces.\n", w, h, numOfFaces);
+
+       /* Init data struct */
+       if (surface->data) dynamicPaint_freeSurfaceData(surface);
+       sData = surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
+       if (!surface->data) return printError(canvas, "Not enough free memory.");
+
+       sData->samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
+       tempPoints = (struct PaintTexturePoint *) MEM_callocN(w*h*sizeof(struct PaintTexturePoint), "PaintTexturePoint");
+       if (tempPoints == NULL) return printError(canvas, "Not enough free memory.");
+
+       /*
+       *       Generate a temporary bounding box array for UV faces to optimize
+       *       the pixel-inside-a-face search.
+       */
+       faceBB = (struct BB2d *) MEM_mallocN(numOfFaces*sizeof(struct BB2d), "MPCanvasFaceBB");
+       if (faceBB == NULL) return printError(canvas, "Not enough free memory.");
+
+       for (yy=0; yy<numOfFaces; yy++) {
+               int numOfVert = (mface[yy].v4) ? 4 : 3;
+               int i;
+
+               VECCOPY2D(faceBB[yy].min, tface[yy].uv[0]);
+               VECCOPY2D(faceBB[yy].max, tface[yy].uv[0]);
+
+               for (i = 1; i<numOfVert; i++) {
+                       if (tface[yy].uv[i][0] < faceBB[yy].min[0]) faceBB[yy].min[0] = tface[yy].uv[i][0];
+                       if (tface[yy].uv[i][1] < faceBB[yy].min[1]) faceBB[yy].min[1] = tface[yy].uv[i][1];
+                       if (tface[yy].uv[i][0] > faceBB[yy].max[0]) faceBB[yy].max[0] = tface[yy].uv[i][0];
+                       if (tface[yy].uv[i][1] > faceBB[yy].max[1]) faceBB[yy].max[1] = tface[yy].uv[i][1];
+
+               }
+       }
+
+       /*
+       *       Allocate antialias sample data (without threads due to malloc)
+       *       (Non threadable?)
+       */
+       for (yy = 0; yy < h; yy++)
+       {
+               int xx;
+               for (xx = 0; xx < w; xx++)
+               {
+                       int index = xx+w*yy;
+                       PaintTexturePoint *tPoint = &tempPoints[index];
+
+                       /* Initialize barycentricWeights        */
+                       tPoint->barycentricWeights = (struct Vec3f *) malloc( sData->samples * sizeof(struct Vec3f ));
+                       if (tPoint->barycentricWeights == NULL) return printError(canvas, "Not enough free memory.");
+
+               }
+       }
+
+       /*
+       *       Loop through every pixel and check
+       *       if pixel is uv-mapped on a canvas face.
+       */
+       #pragma omp parallel for schedule(static)
+       for (yy = 0; yy < h; yy++)
+       {
+               int xx;
+               for (xx = 0; xx < w; xx++)
+               {
+                       int i, sample;
+                       int index = xx+w*yy;
+                       PaintTexturePoint *tPoint = (&tempPoints[index]);
+
+                       short isInside = 0;     /* if point is inside a uv face */
+
+                       float d1[2], d2[2], d3[2], point[5][2];
+                       float dot00,dot01,dot02,dot11,dot12, invDenom, u,v;
+
+                       /* Init per pixel settings */
+                       tPoint->face_index = -1;
+                       tPoint->pixel_index = index;
+
+                       /* Actual pixel center, used when collision is found    */
+                       point[0][0] = ((float)xx + 0.5f) / w;
+                       point[0][1] = ((float)yy + 0.5f) / h;
+
+                       /*
+                       * A pixel middle sample isn't enough to find very narrow polygons
+                       * So using 4 samples of each corner too
+                       */
+                       point[1][0] = ((float)xx) / w;
+                       point[1][1] = ((float)yy) / h;
+
+                       point[2][0] = ((float)xx+1) / w;
+                       point[2][1] = ((float)yy) / h;
+
+                       point[3][0] = ((float)xx) / w;
+                       point[3][1] = ((float)yy+1) / h;
+
+                       point[4][0] = ((float)xx+1) / w;
+                       point[4][1] = ((float)yy+1) / h;
+
+
+                       /* Loop through samples, starting from middle point     */
+                       for (sample=0; sample<5; sample++) {
+                               
+                               /* Loop through every face in the mesh  */
+                               for (i=0; i<numOfFaces; i++) {
+
+                                       /* Check uv bb  */
+                                       if (faceBB[i].min[0] > (point[sample][0])) continue;
+                                       if (faceBB[i].min[1] > (point[sample][1])) continue;
+                                       if (faceBB[i].max[0] < (point[sample][0])) continue;
+                                       if (faceBB[i].max[1] < (point[sample][1])) continue;
+
+                                       /*  Calculate point inside a triangle check
+                                       *       for uv0,1,2 */
+                                       VECSUB2D(d1,  tface[i].uv[2], tface[i].uv[0]);  // uv2 - uv0
+                                       VECSUB2D(d2,  tface[i].uv[1], tface[i].uv[0]);  // uv1 - uv0
+                                       VECSUB2D(d3,  point[sample], tface[i].uv[0]);   // point - uv0
+
+                                       dot00 = d1[0]*d1[0] + d1[1]*d1[1];
+                                       dot01 = d1[0]*d2[0] + d1[1]*d2[1];
+                                       dot02 = d1[0]*d3[0] + d1[1]*d3[1];
+                                       dot11 = d2[0]*d2[0] + d2[1]*d2[1];
+                                       dot12 = d2[0]*d3[0] + d2[1]*d3[1];
+
+                                       invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+                                       u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+                                       v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+                                       if ((u > 0) && (v > 0) && (u + v < 1)) {isInside=1;} /* is inside a triangle */
+
+                                       /*  If collision wasn't found but the face is a quad
+                                       *       do another check for the second half */
+                                       if ((!isInside) && mface[i].v4)
+                                       {
+
+                                               /* change d2 to test the other half     */
+                                               VECSUB2D(d2,  tface[i].uv[3], tface[i].uv[0]);  // uv3 - uv0
+
+                                               /* test again   */
+                                               dot00 = d1[0]*d1[0] + d1[1]*d1[1];
+                                               dot01 = d1[0]*d2[0] + d1[1]*d2[1];
+                                               dot02 = d1[0]*d3[0] + d1[1]*d3[1];
+                                               dot11 = d2[0]*d2[0] + d2[1]*d2[1];
+                                               dot12 = d2[0]*d3[0] + d2[1]*d3[1];
+
+                                               invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+                                               u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+                                               v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+                                               if ((u > 0) && (v > 0) && (u + v < 1)) {isInside=2;} /* is inside the second half of the quad */
+
+                                       }
+
+                                       /*
+                                       *       If point was inside the face
+                                       */
+                                       if (isInside != 0) {
+
+                                               float uv1co[2], uv2co[2], uv3co[2], uv[2];
+                                               int j;
+
+                                               /* Get triagnle uvs     */
+                                               if (isInside==1) {
+                                                       VECCOPY2D(uv1co, tface[i].uv[0]);
+                                                       VECCOPY2D(uv2co, tface[i].uv[1]);
+                                                       VECCOPY2D(uv3co, tface[i].uv[2]);
+                                               }
+                                               else {
+                                                       VECCOPY2D(uv1co, tface[i].uv[0]);
+                                                       VECCOPY2D(uv2co, tface[i].uv[2]);
+                                                       VECCOPY2D(uv3co, tface[i].uv[3]);
+                                               }
+
+                                               /* Add b-weights per anti-aliasing sample       */
+                                               for (j=0; j<sData->samples; j++) {
+                                                       uv[0] = point[0][0] + jitter5sample[j*2] / w;
+                                                       uv[1] = point[0][1] + jitter5sample[j*2+1] / h;
+
+                                                       barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tPoint->barycentricWeights[j].v);
+                                               }
+
+                                               /* Set surface point face values        */
+                                               tPoint->face_index = i;                                                 /* face index */
+                                               tPoint->quad = (isInside == 2) ? 1 : 0;         /* quad or tri part*/
+
+                                               /* save vertex indexes  */
+                                               tPoint->v1 = (isInside == 2) ? mface[i].v1 : mface[i].v1;
+                                               tPoint->v2 = (isInside == 2) ? mface[i].v3 : mface[i].v2;
+                                               tPoint->v3 = (isInside == 2) ? mface[i].v4 : mface[i].v3;
+                                               
+                                               sample = 5;     /* make sure we exit sample loop as well */
+                                               break;
+                                       }
+                               }
+                       } /* sample loop */
+               }
+       }
+
+
+
+       /*
+       *       Now loop through every pixel that was left without index
+       *       and find if they have neighbouring pixels that have an index.
+       *       If so use that polygon as pixel surface.
+       *       (To avoid seams on uv island edges)
+       */
+       #pragma omp parallel for schedule(static)
+       for (yy = 0; yy < h; yy++)
+       {
+               int xx;
+               for (xx = 0; xx < w; xx++)
+               {
+                       int index = xx+w*yy;
+                       PaintTexturePoint *tPoint = (&tempPoints[index]);
+
+                       /* If point isnt't on canvas mesh       */
+                       if (tPoint->face_index == -1) {
+                               int u_min, u_max, v_min, v_max;
+                               int u,v, ind;
+                               float point[2];
+
+                               /* get loop area        */
+                               u_min = (xx > 0) ? -1 : 0;
+                               u_max = (xx < (w-1)) ? 1 : 0;
+                               v_min = (yy > 0) ? -1 : 0;
+                               v_max = (yy < (h-1)) ? 1 : 0;
+
+                               point[0] = ((float)xx + 0.5f) / w;
+                               point[1] = ((float)yy + 0.5f) / h;
+
+                               /* search through defined area for neighbour    */
+                               for (u=u_min; u<=u_max; u++)
+                                       for (v=v_min; v<=v_max; v++) {
+                                               /* if not this pixel itself     */
+                                               if (u!=0 || v!=0) {
+                                                       ind = (xx+u)+w*(yy+v);
+
+                                                       /* if neighbour has index       */
+                                                       if (tempPoints[ind].face_index != -1) {
+
+                                                               float uv1co[2], uv2co[2], uv3co[2], uv[2];
+                                                               int i = tempPoints[ind].face_index, j;
+
+                                                               /* Now calculate pixel data for this pixel as it was on polygon surface */
+                                                               if (!tempPoints[ind].quad) {
+                                                                       VECCOPY2D(uv1co, tface[i].uv[0]);
+                                                                       VECCOPY2D(uv2co, tface[i].uv[1]);
+                                                                       VECCOPY2D(uv3co, tface[i].uv[2]);
+                                                               }
+                                                               else {
+                                                                       VECCOPY2D(uv1co, tface[i].uv[0]);
+                                                                       VECCOPY2D(uv2co, tface[i].uv[2]);
+                                                                       VECCOPY2D(uv3co, tface[i].uv[3]);
+                                                               }
+
+                                                               /* Add b-weights per anti-aliasing sample       */
+                                                               for (j=0; j<sData->samples; j++) {
+
+                                                                       uv[0] = point[0] + jitter5sample[j*2] / w;
+                                                                       uv[1] = point[1] + jitter5sample[j*2+1] / h;
+                                                                       barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tPoint->barycentricWeights[j].v);
+                                                               }
+
+                                                               /* Set values   */
+                                                               tPoint->neighbour_pixel = ind;                          // face index
+                                                               tPoint->quad = tempPoints[ind].quad;            // quad or tri
+
+                                                               /* save vertex indexes  */
+                                                               tPoint->v1 = (tPoint->quad) ? mface[i].v1 : mface[i].v1;
+                                                               tPoint->v2 = (tPoint->quad) ? mface[i].v3 : mface[i].v2;
+                                                               tPoint->v3 = (tPoint->quad) ? mface[i].v4 : mface[i].v3;
+
+                                                               u = u_max + 1;  /* make sure we exit outer loop as well */
+                                                               break;
+                                                       }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /*
+       *       When base loop is over convert found neighbour indexes to real ones
+       *       Also count the final number of active surface points
+       */
+
+       #pragma omp parallel for schedule(static)
+       for (yy = 0; yy < h; yy++)
+       {
+               int xx;
+               for (xx = 0; xx < w; xx++)
+               {
+                       int index = xx+w*yy;
+                       PaintTexturePoint *tPoint = (&tempPoints[index]);
+
+                       if (tPoint->face_index == -1 && tPoint->neighbour_pixel != -1) tPoint->face_index = tempPoints[tPoint->neighbour_pixel].face_index;
+                       if (tPoint->face_index != -1) active_points++;
+               }
+       }
+
+#if 0
+       /*  -----------------------------------------------------------------
+       *       For debug, output pixel statuses to the color map
+       *       -----------------------------------------------------------------*/
+       #pragma omp parallel for schedule(static)
+       for (yy = 0; yy < h; yy++)
+       {
+               int xx;
+               for (xx = 0; xx < w; xx++)
+               {
+                       int index = xx+w*yy;
+                       DynamicPaintSurfacePoint *cPoint = (&surface->point[index]);
+                       cPoint->alpha=1.0f;
+
+                       /* Every pixel that is assigned as "edge pixel" gets blue color */
+                       if (cPoint->neighbour_pixel != -1) cPoint->color[2] = 1.0f;
+                       /* and every pixel that finally got an polygon gets red color   */
+                       if (cPoint->index != -1) cPoint->color[0] = 1.0f;
+                       /* green color shows pixel face index hash      */
+                       if (cPoint->index != -1) cPoint->color[1] = (float)(cPoint->index % 255)/256.0f;
+               }
+       }
+
+#endif
+
+#if 0 /* Currently disabled */
+       /*      If any effect enabled, create surface effect / wet layer
+       *       neighbour lists. Processes possibly moving data. */
+       if (surface->effect) {
+
+               #pragma omp parallel for schedule(static)
+               for (yy = 0; yy < h; yy++)
+               {
+                       int xx;
+                       for (xx = 0; xx < w; xx++)
+                       {
+                               int i;
+                               DynamicPaintSurfacePoint *cPoint = (&surface->point[xx+w*yy]);
+
+                               /* If current point exists find all it's neighbouring pixels    */
+                               if (cPoint->index != -1)
+                               for (i=0; i<8; i++) {
+
+                                       /* Try to find a neighbouring pixel in defined direction
+                                       *  If not found, -1 is returned */
+                                       cPoint->neighbours[i] = dynamicPaint_findNeighbourPixel(canvas, xx, yy, i);
+                               }
+                       }
+               }
+       }
+#endif
+
+       MEM_freeN(faceBB);
+
+       /* Create final surface data without inactive points */
+       {
+               int index, cursor = 0;
+               PaintTexturePoint *tPoint = (struct PaintTexturePoint *) MEM_callocN(active_points*sizeof(struct PaintTexturePoint), "PaintTexturePoint");
+
+               sData->format_data = tPoint;
+               if (sData->format_data == NULL) return printError(canvas, "Not enough free memory.");
+               sData->total_points = active_points;
+
+               for(index = 0; index < (w*h); index++) {
+                       if (tempPoints[index].face_index != -1) {
+                               memcpy(&tPoint[cursor], &tempPoints[index], sizeof(PaintTexturePoint));
+                               cursor++;
+                       }
+               }
+               MEM_freeN(tempPoints);
+       }
+
+       /* Init surface type data */
+       dynamicPaint_allocateSurfaceType(surface);
+
+       return 1;
+}
+
+#define DPOUTPUT_PAINT 0
+#define DPOUTPUT_WET 1
+#define DPOUTPUT_DISPLACE 2
+#define DPOUTPUT_IWAVE 3
+
+/*
+*      Outputs an image file from uv surface data.
+*/
+void dynamicPaint_outputImage(DynamicPaintSurface *surface, char* filename, short format, short type)
+{
+       int index;
+       ImBuf* mhImgB = NULL;
+       PaintSurfaceData *sData = surface->data;
+       PaintTexturePoint *tPoint = (PaintTexturePoint*)sData->format_data;
+       char output_file[250];
+
+       if (sData == NULL || sData->type_data == NULL) {printError(surface->canvas, "Image save failed: Invalid surface.");return;}
+
+       if (format == DPOUTPUT_JPEG) sprintf(output_file,"%s.jpg",filename);
+       else if (format == DPOUTPUT_OPENEXR) sprintf(output_file,"%s.exr",filename);
+       else sprintf(output_file,"%s.png",filename);
+
+       /* Validate output file path    */
+       BLI_path_abs(output_file, G.main->name);
+       BLI_make_existing_file(output_file);
+
+       /* Init image buffer    */
+       mhImgB = IMB_allocImBuf(surface->image_resolution, surface->image_resolution, 32, IB_rectfloat);
+       if (mhImgB == NULL) {printError(surface->canvas, "Image save failed: Not enough free memory.");return;}
+
+       #pragma omp parallel for schedule(static)
+       for (index = 0; index < sData->total_points; index++)
+       {
+               int pos=tPoint[index].pixel_index*4;    /* image buffer position */
+               
+
+               /* Set values of preferred type */
+               if (type == DPOUTPUT_WET) {
+                       PaintPoint *point = &((PaintPoint*)sData->type_data)[index];
+                       float value = (point->wetness > 1.0f) ? 1.0f : point->wetness;
+
+                       mhImgB->rect_float[pos]=value;
+                       mhImgB->rect_float[pos+1]=value;
+                       mhImgB->rect_float[pos+2]=value;
+                       mhImgB->rect_float[pos+3]=1.0f;
+               }
+               else if (type == DPOUTPUT_PAINT) {
+                       PaintPoint *point = &((PaintPoint*)sData->type_data)[index];
+                       float invAlpha = 1.0f - point->e_alpha;
+
+                       /* If base layer already has a color, blend it  */
+                       if (point->alpha) {
+                               mhImgB->rect_float[pos]   = point->color[0] * invAlpha + point->e_color[0] * point->e_alpha;
+                               mhImgB->rect_float[pos+1] = point->color[1] * invAlpha + point->e_color[1] * point->e_alpha;
+                               mhImgB->rect_float[pos+2] = point->color[2] * invAlpha + point->e_color[2] * point->e_alpha;
+                       }
+                       else {
+                               /* Else use effect layer color  */
+                               mhImgB->rect_float[pos]   = point->e_color[0];
+                               mhImgB->rect_float[pos+1] = point->e_color[1];
+                               mhImgB->rect_float[pos+2] = point->e_color[2];
+                       }
+
+                       /* use highest alpha    */
+                       mhImgB->rect_float[pos+3] = (point->e_alpha > point->alpha) ? point->e_alpha : point->alpha;
+
+                       /* Multiply color by alpha if enabled   */
+                       if (surface->flags & MOD_DPAINT_MULALPHA) {
+                               mhImgB->rect_float[pos]   *= mhImgB->rect_float[pos+3];
+                               mhImgB->rect_float[pos+1] *= mhImgB->rect_float[pos+3];
+                               mhImgB->rect_float[pos+2] *= mhImgB->rect_float[pos+3];
+                       }
+               }
+               else if (type == DPOUTPUT_DISPLACE) {
+                       float depth = ((float*)sData->type_data)[index];
+
+                       if (surface->disp_type == MOD_DPAINT_DISP_DISPLACE) {
+                               depth = (0.5f - depth);
+                               if (depth < 0.0f) depth = 0.0f;
+                               if (depth > 1.0f) depth = 1.0f;
+                       }
+
+                       mhImgB->rect_float[pos]=depth;
+                       mhImgB->rect_float[pos+1]=depth;
+                       mhImgB->rect_float[pos+2]=depth;
+                       mhImgB->rect_float[pos+3]=1.0f;
+               }
+       }
+
+       /* Save image buffer    */
+       if (format == DPOUTPUT_JPEG) {  /* JPEG */
+               mhImgB->ftype= JPG|95;
+               IMB_rect_from_float(mhImgB);
+               imb_savejpeg(mhImgB, output_file, IB_rectfloat);
+       }
+#ifdef WITH_OPENEXR
+       else if (format == DPOUTPUT_OPENEXR) {  /* OpenEXR 32-bit float */
+               mhImgB->ftype = OPENEXR | OPENEXR_COMPRESS;
+               IMB_rect_from_float(mhImgB);
+               imb_save_openexr(mhImgB, output_file, IB_rectfloat);
+       }
+#endif
+       else {  /* DPOUTPUT_PNG */
+               mhImgB->ftype= PNG|95;
+               IMB_rect_from_float(mhImgB);
+               imb_savepng(mhImgB, output_file, IB_rectfloat);
+       }
+
+       IMB_freeImBuf(mhImgB);
+}
+
+
+/***************************** Material / Texture Sampling ******************************/
+
+/*
+*      Update animated textures and calculate inverse matrices
+*      for material related objects in case texture is mapped to an object.
+*      (obj->imat isn't auto-updated)
+*/
+static void dynamicPaint_updateMaterial(Material *mat, int frame)
+{
+       MTex *mtex = NULL;
+       Tex *tex = NULL;
+       int tex_nr;
+       if (mat == NULL) return;
+
+       /*
+       *       Loop through every material texture and check
+       *       if they are mapped by other object
+       */
+       for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
+               /* separate tex switching */
+               if(mat->septex & (1<<tex_nr)) continue;
+       
+               if(mat->mtex[tex_nr]) {
+                       mtex= mat->mtex[tex_nr];
+                       tex= mtex->tex;
+
+                       if(tex==0) continue;
+                       
+                       /* which coords */
+                       if(mtex->texco==TEXCO_OBJECT) { 
+                               Object *ob= mtex->object;
+                               if(ob) {                                                
+                                       invert_m4_m4(ob->imat, ob->obmat);
+                               }
+                       }
+
+                       /* update cache if voxel data */
+                       if(tex->id.us && tex->type==TEX_VOXELDATA) {
+                               cache_voxeldata(tex, frame);
+                       }
+                       /* update image sequences and movies */
+                       if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+                               if(tex->iuser.flag & IMA_ANIM_ALWAYS)
+                                       BKE_image_user_calc_frame(&tex->iuser, frame, 0);
+                       }
+               }
+       }
+}
+
+/* Initialize materials for object:
+*   Calculates inverce matrices for linked objects, updates
+*   volume caches etc. */
+static void dynamicPaint_initObjectMaterials(Object *brushOb, Material *ui_mat, int frame)
+{
+       /* Calculate inverse transformation matrix
+       *  for this object */
+       invert_m4_m4(brushOb->imat, brushOb->obmat);
+
+       /* Now process every material linked to this brush object */
+       if ((ui_mat == NULL) && brushOb->mat && brushOb->totcol) {
+               int i, tot=(*give_totcolp(brushOb))+1;
+               for (i=1; i<tot; i++) {
+                       dynamicPaint_updateMaterial(give_current_material(brushOb,i), frame);
+               }
+       }
+       else {
+               dynamicPaint_updateMaterial(ui_mat, frame);
+       }
+}
+
+/* A modified part of shadeinput.c -> shade_input_set_uv() / shade_input_set_shade_texco()
+*  Used for sampling UV mapped texture color */
+static void textured_face_generate_uv(float *uv, float *normal, float *hit, float *v1, float *v2, float *v3)
+{
+
+       float detsh, t00, t10, t01, t11, xn, yn, zn;
+       int axis1, axis2;
+
+       /* find most stable axis to project */
+       xn= fabs(normal[0]);
+       yn= fabs(normal[1]);
+       zn= fabs(normal[2]);
+
+       if(zn>=xn && zn>=yn) { axis1= 0; axis2= 1; }
+       else if(yn>=xn && yn>=zn) { axis1= 0; axis2= 2; }
+       else { axis1= 1; axis2= 2; }
+
+       /* compute u,v and derivatives */
+       t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
+       t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
+
+       detsh= 1.0f/(t00*t11-t10*t01);
+       t00*= detsh; t01*=detsh; 
+       t10*=detsh; t11*=detsh;
+
+       uv[0] = (hit[axis1]-v3[axis1])*t11-(hit[axis2]-v3[axis2])*t10;
+       uv[1] = (hit[axis2]-v3[axis2])*t00-(hit[axis1]-v3[axis1])*t01;
+
+       /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
+       CLAMP(uv[0], -2.0f, 1.0f);
+       CLAMP(uv[1], -2.0f, 1.0f);
+}
+
+/* a modified part of shadeinput.c -> shade_input_set_uv() / shade_input_set_shade_texco()
+*  Used for sampling UV mapped texture color */
+static void textured_face_get_uv(float *uv_co, float *normal, float *uv, int faceIndex, short quad, MTFace *tface)
+{
+       float *uv1, *uv2, *uv3;
+       float l;
+
+       l= 1.0f+uv[0]+uv[1];
+               
+       uv1= tface[faceIndex].uv[0];
+       uv2= (quad) ? tface[faceIndex].uv[2] : tface[faceIndex].uv[1];
+       uv3= (quad) ? tface[faceIndex].uv[3] : tface[faceIndex].uv[2];
+                               
+       uv_co[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]);
+       uv_co[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]);
+       uv_co[2]= 0.0f; /* texture.c assumes there are 3 coords */
+}
+
+/*
+*      Edited version of do_material_tex()
+*
+*      Samples color and alpha from a "Surface" type material
+*      on a given point, without need for ShadeInput.
+*
+*      Keep up-to-date with new mapping settings
+*
+*      also see shade_input_set_shade_texco() for ORCO settings
+*      and shade_input_set_uv() for face uv calculation
+*/
+void dynamicPaint_sampleSolidMaterial(float color[3], float *alpha, Material *mat, Object *brushOb, float xyz[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
+{
+       MTex *mtex = NULL;
+       Tex *tex = NULL;
+       TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
+       float co[3], xyz_local[3];
+       float fact, stencilTin=1.0;
+       float texvec[3];
+       int tex_nr, rgbnor= 0;
+       float uv[3], normal[3];
+       MFace *mface;
+       int v1, v2, v3;
+       MVert *mvert;
+       
+       /* Get face data        */
+       mvert = orcoDm->getVertArray(orcoDm);
+       mface = orcoDm->getFaceArray(orcoDm);
+       v1=mface[faceIndex].v1, v2=mface[faceIndex].v2, v3=mface[faceIndex].v3;
+       if (isQuad) {v2=mface[faceIndex].v3; v3=mface[faceIndex].v4;}
+       normal_tri_v3( normal, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+
+       /* Assign material base values  */
+       color[0] = mat->r;
+       color[1] = mat->g;
+       color[2] = mat->b;
+       *alpha = mat->alpha;
+
+       VECCOPY(xyz_local, xyz);
+       mul_m4_v3(brushOb->imat, xyz_local);
+
+       for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
+               
+               /* separate tex switching */
+               if(mat->septex & (1<<tex_nr)) continue;
+               
+               if(mat->mtex[tex_nr]) {
+                       mtex= mat->mtex[tex_nr];
+                       tex= mtex->tex;
+                       
+                       tex= mtex->tex;
+                       if(tex==0) continue;
+
+                       /* which coords */
+                       if(mtex->texco==TEXCO_ORCO) {
+                               float l;
+                               /* Get generated UV */
+                               textured_face_generate_uv(uv, normal, xyz_local, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+                               l= 1.0f+uv[0]+uv[1];
+
+                               /* calculate generated coordinate
+                               *  ** Keep up-to-date with shadeinput.c -> shade_input_set_shade_texco() **/
+                               co[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0];
+                               co[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1];
+                               co[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2];
+                       }
+                       else if(mtex->texco==TEXCO_OBJECT) {
+                               Object *ob= mtex->object;
+
+                               VECCOPY(co, xyz);
+                               /* convert from world space to paint space */
+                               mul_m4_v3(brushOb->imat, co);
+                               if(ob) {
+                                       mul_m4_v3(ob->imat, co);
+                               }
+                       }
+                       else if(mtex->texco==TEXCO_GLOB) {
+                               VECCOPY(co, xyz);
+                       }
+                       else if(mtex->texco==TEXCO_UV) {
+                               MTFace *tface;
+
+                               /* Get UV layer */
+                               if(mtex->uvname[0] != 0)
+                                       tface = CustomData_get_layer_named(&orcoDm->faceData, CD_MTFACE, mtex->uvname);
+                               else
+                                       tface = DM_get_face_data_layer(orcoDm, CD_MTFACE);
+                               /* Get generated coordinates to calculate UV from */
+                               textured_face_generate_uv(uv, normal, xyz_local, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+                               /* Get UV mapping coordinate */
+                               textured_face_get_uv(co, normal, uv, faceIndex, isQuad, tface);
+                       }
+                       else continue;  /* non-supported types get just skipped:
+                                                       TEXCO_REFL, TEXCO_NORM, TEXCO_TANGENT
+                                                       TEXCO_WINDOW, TEXCO_STRAND, TEXCO_STRESS etc.
+                                                       */
+
+                       /* get texture mapping */
+                       texco_mapping_ext(normal, tex, mtex, co, 0, 0, texvec);
+
+                       if(tex->use_nodes && tex->nodetree) {
+                               /* No support for nodes (yet). */
+                               continue;
+                       }
+                       else {
+                               rgbnor = multitex_ext(mtex->tex, co, 0, 0, 0, &texres);
+                       }
+
+                       /* texture output */
+                       if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
+                               texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
+                               rgbnor-= TEX_RGB;
+                       }
+
+                       /* Negate and stencil masks */
+                       if(mtex->texflag & MTEX_NEGATIVE) {
+                               if(rgbnor & TEX_RGB) {
+                                       texres.tr= 1.0-texres.tr;
+                                       texres.tg= 1.0-texres.tg;
+                                       texres.tb= 1.0-texres.tb;
+                               }
+                               texres.tin= 1.0-texres.tin;
+                       }
+                       if(mtex->texflag & MTEX_STENCIL) {
+                               if(rgbnor & TEX_RGB) {
+                                       fact= texres.ta;
+                                       texres.ta*= stencilTin;
+                                       stencilTin*= fact;
+                               }
+                               else {
+                                       fact= texres.tin;
+                                       texres.tin*= stencilTin;
+                                       stencilTin*= fact;
+                               }
+                       }
+
+                       /* mapping */
+                       if(mtex->mapto & (MAP_COL)) {
+                               float tcol[3];
+                               /* stencil maps on the texture control slider, not texture intensity value */
+                               tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb;
+                               if((rgbnor & TEX_RGB)==0) {
+                                       tcol[0]= mtex->r;
+                                       tcol[1]= mtex->g;
+                                       tcol[2]= mtex->b;
+                               }
+                               else if(mtex->mapto & MAP_ALPHA) {
+                                       texres.tin= stencilTin;
+                               }
+                               else texres.tin= texres.ta;
+                               if(mtex->mapto & MAP_COL) {
+                                       float colfac= mtex->colfac*stencilTin;
+                                       texture_rgb_blend(color, tcol, color, texres.tin, colfac, mtex->blendtype);
+                               }
+                       }
+
+                       if(mtex->mapto & MAP_VARS) {
+                               /* stencil maps on the texture control slider, not texture intensity value */
+                               if(rgbnor & TEX_RGB) {
+                                       if(texres.talpha) texres.tin= texres.ta;
+                                       else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
+                               }
+
+                               if(mtex->mapto & MAP_ALPHA) {
+                                       float alphafac= mtex->alphafac*stencilTin;
+                                       *alpha= texture_value_blend(mtex->def_var, *alpha, texres.tin, alphafac, mtex->blendtype);
+                                       if(*alpha<0.0) *alpha= 0.0;
+                                       else if(*alpha>1.0) *alpha= 1.0;
+                               }
+                       }
+               }
+       }
+}
+
+
+/*
+*      Edited version of texture.c -> do_volume_tex()
+*
+*      Samples color and density from a volume type texture
+*      without need for ShadeInput.
+*
+*      Keep up-to-date with new mapping settings
+*/
+void dynamicPaint_sampleVolumeMaterial(float color[3], float *alpha, Material *mat, Object *brushOb, float xyz[3])
+{
+       int mapto_flag  = MAP_DENSITY | MAP_REFLECTION_COL | MAP_TRANSMISSION_COL;
+       float *col = color;
+
+       MTex *mtex = NULL;
+       Tex *tex = NULL;
+       TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
+       int tex_nr, rgbnor= 0;
+       float co[3], texvec[3];
+       float fact, stencilTin=1.0;
+
+       /* set base color */
+       color[0] = mat->vol.reflection_col[0];
+       color[1] = mat->vol.reflection_col[1];
+       color[2] = mat->vol.reflection_col[2];
+       *alpha = mat->vol.density;
+       
+       for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
+
+               /* separate tex switching */
+               if(mat->septex & (1<<tex_nr)) continue;
+               
+               if(mat->mtex[tex_nr]) {
+                       mtex= mat->mtex[tex_nr];
+                       tex= mtex->tex;
+                       if(tex==0) continue;
+
+                       /* only process if this texture is mapped 
+                               * to one that we're interested in */
+                       if (!(mtex->mapto & mapto_flag)) continue;
+                       texres.nor= NULL;
+                       
+                       /* which coords */
+                       if(mtex->texco==TEXCO_OBJECT) { 
+                               Object *ob= mtex->object;
+                               ob= mtex->object;
+                               if(ob) {                                                
+                                       VECCOPY(co, xyz);
+                                       mul_m4_v3(ob->imat, co);
+                               }
+                       }
+                       else if(mtex->texco==TEXCO_ORCO) {
+                               {
+                                       Object *ob= brushOb;
+                                       VECCOPY(co, xyz);
+                                       mul_m4_v3(ob->imat, co);
+                               }
+                       }
+                       else if(mtex->texco==TEXCO_GLOB) {                                                      
+                               VECCOPY(co, xyz);
+                       }
+                       else continue;  /* Skip unsupported types */
+
+                       if(tex->type==TEX_IMAGE) {
+                               continue;       /* not supported yet */                         
+                       }
+                       else {
+                               /* placement */
+                               if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
+                               else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
+
+                               if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
+                               else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
+
+                               if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
+                               else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
+                       }
+                       rgbnor= multitex_ext(tex, texvec, NULL, NULL, 0, &texres);
+                       
+                       /* texture output */
+                       if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
+                               texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
+                               rgbnor-= TEX_RGB;
+                       }
+                       /* Negate and stencil */
+                       if(mtex->texflag & MTEX_NEGATIVE) {
+                               if(rgbnor & TEX_RGB) {
+                                       texres.tr= 1.0-texres.tr;
+                                       texres.tg= 1.0-texres.tg;
+                                       texres.tb= 1.0-texres.tb;
+                               }
+                               texres.tin= 1.0-texres.tin;
+                       }
+                       if(mtex->texflag & MTEX_STENCIL) {
+                               if(rgbnor & TEX_RGB) {
+                                       fact= texres.ta;
+                                       texres.ta*= stencilTin;
+                                       stencilTin*= fact;
+                               }
+                               else {
+                                       fact= texres.tin;
+                                       texres.tin*= stencilTin;
+                                       stencilTin*= fact;
+                               }
+                       }
+                       
+                       /* Map values */
+                       if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) {
+                               float tcol[3];
+                               /* stencil maps on the texture control slider, not texture intensity value */
+                               if((rgbnor & TEX_RGB)==0) {
+                                       tcol[0]= mtex->r;
+                                       tcol[1]= mtex->g;
+                                       tcol[2]= mtex->b;
+                               } else {
+                                       tcol[0]=texres.tr;
+                                       tcol[1]=texres.tg;
+                                       tcol[2]=texres.tb;
+                                       if(texres.talpha)
+                                               texres.tin= texres.ta;
+                               }
+                               
+                               /* used for emit */
+                               if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) {
+                                       float colemitfac= mtex->colemitfac*stencilTin;
+                                       texture_rgb_blend(col, tcol, col, texres.tin, colemitfac, mtex->blendtype);
+                               }
+                               if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) {
+                                       float colreflfac= mtex->colreflfac*stencilTin;
+                                       texture_rgb_blend(col, tcol, col, texres.tin, colreflfac, mtex->blendtype);
+                               }
+                               if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) {
+                                       float coltransfac= mtex->coltransfac*stencilTin;
+                                       texture_rgb_blend(col, tcol, col, texres.tin, coltransfac, mtex->blendtype);
+                               }
+                       }
+                       
+                       if((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) {
+                               /* stencil maps on the texture control slider, not texture intensity value */
+                               
+                               /* convert RGB to intensity if intensity info isn't provided */
+                               if (!(rgbnor & TEX_INT)) {
+                                       if (rgbnor & TEX_RGB) {
+                                               if(texres.talpha) texres.tin= texres.ta;
+                                               else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
+                                       }
+                               }
+                               if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) {
+                                       float densfac= mtex->densfac*stencilTin;
+
+                                       *alpha = texture_value_blend(mtex->def_var, *alpha, texres.tin, densfac, mtex->blendtype);
+                                       CLAMP(*alpha, 0.0, 1.0);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+*      Get material diffuse color and alpha (including linked textures) in given coordinates
+*      
+*      color,paint : input/output color values
+*      pixelCoord : canvas pixel coordinates in global space. used if material is volumetric
+*      paintHit : ray hit point on paint object surface in global space. used by "surface" type materials
+*      faceIndex : ray hit face index
+*      orcoDm : orco state derived mesh of paint object
+*      ui_mat : force material. if NULL, material linked to mesh face is used.
+*
+*      *"brush object" = object to sample material color from
+*/
+void dynamicPaint_getMaterialColor(float *color, float *alpha, Object *brushOb, float pixelCoord[3], float paintHit[3], int faceIndex, short isQuad, DerivedMesh *orcoDm, Material *ui_mat)
+{
+       Material *material = ui_mat;
+
+       /* Get face material */
+       if (material == NULL) {
+               MFace *mface = NULL;
+               mface = orcoDm->getFaceArray(orcoDm);
+               material = give_current_material(brushOb, mface[faceIndex].mat_nr+1);
+
+               if (material == NULL) return;   /* No material assigned */
+       }
+
+       /* Sample textured material color in given position depending on material type */
+       if (material->material_type == MA_TYPE_SURFACE) {
+               /* Solid material */
+               dynamicPaint_sampleSolidMaterial(color, alpha, material, brushOb, paintHit, faceIndex, isQuad, orcoDm);
+       }
+       else if (material->material_type == MA_TYPE_VOLUME) {
+               /* Volumetric material */
+               dynamicPaint_sampleVolumeMaterial(color, alpha, material, brushOb, pixelCoord);
+       }
+       else if (material->material_type == MA_TYPE_HALO) {
+               /* Halo type not supported */
+       }
+}
+
+
+/***************************** Ray / Nearest Point Utils ******************************/
+
+
+/*  A modified callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces.
+*   userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
+*  
+*      To optimize brush detection speed this doesn't calculate hit coordinates or normal.
+*      If ray hit the second half of a quad, no[0] is set to 1.0f.
+*/
+static void mesh_faces_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+       const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
+       MVert *vert     = data->vert;
+       MFace *face = data->face + index;
+       short quad = 0;
+
+       float *t0, *t1, *t2, *t3;
+       t0 = vert[ face->v1 ].co;
+       t1 = vert[ face->v2 ].co;
+       t2 = vert[ face->v3 ].co;
+       t3 = face->v4 ? vert[ face->v4].co : NULL;
+
+       do
+       {       
+               float dist;
+               dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
+
+               if(dist >= 0 && dist < hit->dist)
+               {
+                       hit->index = index;
+                       hit->dist = dist;
+                       hit->no[0] = (quad) ? 1.0f : 0.0f;
+               }
+
+               t1 = t2;
+               t2 = t3;
+               t3 = NULL;
+               quad = 1;
+
+       } while(t2);
+}
+
+/* A modified callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces.
+*  userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
+*  
+*      To optimize brush detection speed this doesn't calculate hit normal.
+*      If ray hit the second half of a quad, no[0] is set to 1.0f, else 0.0f
+*/
+static void mesh_faces_nearest_point_dp(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
+{
+       const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
+       MVert *vert     = data->vert;
+       MFace *face = data->face + index;
+       short quad = 0;
+
+       float *t0, *t1, *t2, *t3;
+       t0 = vert[ face->v1 ].co;
+       t1 = vert[ face->v2 ].co;
+       t2 = vert[ face->v3 ].co;
+       t3 = face->v4 ? vert[ face->v4].co : NULL;
+
+       do
+       {       
+               float nearest_tmp[3], dist;
+               int vertex, edge;
+               
+               dist = nearest_point_in_tri_surface(t0, t1, t2, co, &vertex, &edge, nearest_tmp);
+               if(dist < nearest->dist)
+               {
+                       nearest->index = index;
+                       nearest->dist = dist;
+                       VECCOPY(nearest->co, nearest_tmp);
+                       nearest->no[0] = (quad) ? 1.0f : 0.0f;
+               }
+
+               t1 = t2;
+               t2 = t3;
+               t3 = NULL;
+               quad = 1;
+
+       } while(t2);
+}
+
+
+/***************************** Painting Calls ******************************/
+
+/*
+*      Mix color values to canvas point.
+*
+*      surface : canvas surface
+*      index : surface point index
+*      paintFlags : paint object flags
+*   paintColor,Alpha,Wetness : to be mixed paint values
+*      timescale : value used to adjust time dependand
+*                          operations when using substeps
+*/
+void dynamicPaint_mixPaintColors(DynamicPaintSurface *surface, int index, int paintFlags, float *paintColor, float *paintAlpha, float *paintWetness, float *timescale)
+{
+       PaintPoint *pPoint = &((PaintPoint*)surface->data->type_data)[index];
+
+       /* Add paint    */
+       if (!(paintFlags & MOD_DPAINT_ERASE)) {
+               float wetness;
+
+               /* If point has previous paint  */
+               if (pPoint->e_alpha > 0)
+               {
+                       /*
+                       *       Mix colors by the factor, use timescale
+                       */
+                       float factor = (*paintAlpha) * (*timescale);
+                       float invFact = 1.0f - factor;
+                       pPoint->e_color[0] = pPoint->e_color[0]*invFact + paintColor[0]*factor;
+                       pPoint->e_color[1] = pPoint->e_color[1]*invFact + paintColor[1]*factor;
+                       pPoint->e_color[2] = pPoint->e_color[2]*invFact + paintColor[2]*factor;
+               }
+               else
+               {
+                       /* else set first color value straight to paint color   */
+                       pPoint->e_color[0] = paintColor[0];
+                       pPoint->e_color[1] = paintColor[1];
+                       pPoint->e_color[2] = paintColor[2];
+               }
+
+               /* alpha */
+               if (paintFlags & MOD_DPAINT_ABS_ALPHA) {
+                       if (pPoint->e_alpha < (*paintAlpha)) pPoint->e_alpha = (*paintAlpha);
+               }
+               else {
+                       pPoint->e_alpha += (*paintAlpha) * (*timescale);
+                       if (pPoint->e_alpha > 1.0f) pPoint->e_alpha = 1.0f;
+               }
+
+               /* only increase wetness if it's below paint level      */
+               wetness = (*paintWetness) * pPoint->e_alpha;
+               if (pPoint->wetness < wetness) pPoint->wetness = wetness;
+       }
+       /* Erase paint  */
+       else {
+               float a_ratio, a_highest;
+               float wetness;
+               float invFact = 1.0f - (*paintAlpha);
+
+               /*
+               *       Make highest alpha to match erased value
+               *       but maintain alpha ratio
+               */
+               if (paintFlags & MOD_DPAINT_ABS_ALPHA) {
+                       a_highest = (pPoint->e_alpha > pPoint->alpha) ? pPoint->e_alpha : pPoint->alpha;
+                       if (a_highest > invFact) {
+                               a_ratio = invFact / a_highest;
+
+                               pPoint->e_alpha *= a_ratio;
+                               pPoint->alpha *= a_ratio;
+                       }
+               }
+               else {
+                       pPoint->e_alpha -= (*paintAlpha) * (*timescale);
+                       if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
+                       pPoint->alpha -= (*paintAlpha) * (*timescale);
+                       if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
+               }
+
+               wetness = (1.0f - (*paintWetness)) * pPoint->e_alpha;
+               if (pPoint->wetness > wetness) pPoint->wetness = wetness;
+       }
+}
+
+/*
+*      Paint a brush object mesh to the surface
+*/
+static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakePoint *bPoint, DynamicPaintBrushSettings *brush, Object *canvasOb, Object *brushOb, float timescale)
+{
+       DerivedMesh *dm = NULL;
+       MVert *mvert = NULL;
+       MFace *mface = NULL;
+       PaintSurfaceData *sData = surface->data;
+
+       if (!brush->dm) return 0;
+
+       /* If using material color, we prepare required stuff on texture related objects first  */
+       if (brush->flags & MOD_DPAINT_USE_MATERIAL) dynamicPaint_initObjectMaterials(brushOb, brush->mat, surface->current_frame);
+
+       {
+               BVHTreeFromMesh treeData = {0};
+               int index;
+
+               int numOfVerts;
+               int ii;
+
+               /*
+               *       Transform collider vertices to world space
+               *       (Faster than transforming per pixel
+               *   coordinates and normals to object space)
+               */
+               dm = CDDM_copy(brush->dm);
+               mvert = dm->getVertArray(dm);
+               mface = dm->getFaceArray(dm);
+               numOfVerts = dm->getNumVerts(dm);
+
+               for (ii=0; ii<numOfVerts; ii++) {
+                       mul_m4_v3(brushOb->obmat, mvert[ii].co);
+               }
+
+               /* Build a bvh tree from transformed vertices   */
+               bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6);
+
+               if(treeData.tree) {
+                       #pragma omp parallel for schedule(static)
+                       for (index = 0; index < sData->total_points; index++)
+                       {
+                               {
+                                       //DynamicPaintSurfacePoint *cPoint = (&surface->point[xx+tWidth*yy]);
+
+                                       int ss;
+                                       float ssFactor = 0.0f;  /* super-sampling factor */
+                                       float depth = 0.0f;             /* displace depth */
+
+                                       float paintColor[3] = {0.0f, 0.0f, 0.0f};
+                                       int numOfHits = 0;
+                                       float paintAlpha = 0.0f;
+
+                                       /* Supersampling        */
+                                       for (ss=0; ss<1; ss++)
+                                       {
+
+                                               float ray_start[3], ray_dir[3];
+                                               float gaus_factor;
+                                               BVHTreeRayHit hit;
+                                               BVHTreeNearest nearest;
+                                               short hit_found = 0;
+
+                                               /* If it's a proximity hit, store distance rate */
+                                               float distRate = -1.0f;
+
+                                               /* hit data     */
+                                               float hitCoord[3];              /* mid-sample hit coordinate */
+                                               int hitFace = -1;               /* mid-sample hit face */
+                                               short hitQuad;                  /* mid-sample hit quad status */
+
+                                               /* Supersampling factor */
+                                               /*if (surface->pixelSamples > 1) {
+                                                       gaus_factor = gaussianFactors[ss];
+                                               }
+                                               else */{
+                                                       gaus_factor = 1.0f;
+                                               }
+
+                                               /* Get current sample position in world coordinates     */
+                                               /*interp_v3_v3v3v3(realPos,
+                                                                               canvasVerts[cPoint->v1].v,
+                                                                               canvasVerts[cPoint->v2].v,
+                                                                               canvasVerts[cPoint->v3].v, cPoint->barycentricWeights[ss].v);*/
+                                               VECCOPY(ray_start, bPoint[index].realCoord);
+                                               VECCOPY(ray_dir, bPoint[index].invNorm);
+
+                                               hit.index = -1;
+                                               hit.dist = 9999;
+                                               nearest.index = -1;
+                                               nearest.dist = brush->paint_distance * brush->paint_distance; /* find_nearest search uses squared distance */
+
+                                               /* Check volume collision       */
+                                               if (brush->collision == MOD_DPAINT_COL_VOLUME || brush->collision == MOD_DPAINT_COL_VOLDIST)
+                                               if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1)
+                                               {
+                                                       /* We hit a triangle, now check if collision point normal is facing the point   */
+
+
+                                                       /*      For optimization sake, hit point normal isn't calculated in ray cast loop       */
+                                                       int v1=mface[hit.index].v1, v2=mface[hit.index].v2, v3=mface[hit.index].v3, quad=(hit.no[0] == 1.0f);
+                                                       float dot;
+
+                                                       if (quad) {v2=mface[hit.index].v3; v3=mface[hit.index].v4;}
+                                               
+                                                       /* Get hit normal       */
+                                                       normal_tri_v3( hit.no, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+                                                       dot = ray_dir[0]*hit.no[0] + ray_dir[1]*hit.no[1] + ray_dir[2]*hit.no[2];
+
+                                                       /*
+                                                       *       If ray and hit normal are facing same direction
+                                                       *       hit point is inside a closed mesh.
+                                                       */
+                                                       if (dot>=0)
+                                                       {
+                                                               /* Add factor on supersample filter     */
+                                                               ssFactor += gaus_factor;
+                                                               depth += hit.dist;
+                                                               hit_found = 1;
+
+                                                               /*
+                                                               *       Mark hit info
+                                                               */
+                                                               if (hitFace == -1) {
+                                                                       VECADDFAC(hitCoord, ray_start, ray_dir, hit.dist);      /* Calculate final hit coordinates */
+                                                                       hitQuad = quad;
+                                                                       hitFace = hit.index;
+                                                               }
+                                                       }
+                                               }       // end of raycast
+                                       
+                                               /* Check proximity collision    */
+                                               if ((brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) && (!hit_found))
+                                               {
+                                                       float proxDist = -1.0f;
+                                                       float hitCo[3];
+                                                       short hQuad;
+                                                       int face;
+
+                                                       /*
+                                                       *       If pure distance proximity, find the nearest point on the mesh
+                                                       */
+                                                       if (!(brush->flags & MOD_DPAINT_PROX_FACEALIGNED)) {
+                                                               if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_faces_nearest_point_dp, &treeData) != -1) {
+                                                                       proxDist = sqrt(nearest.dist);  /* find_nearest returns a squared distance, so gotta change it back to real distance */
+                                                                       copy_v3_v3(hitCo, nearest.co);
+                                                                       hQuad = (nearest.no[0] == 1.0f);
+                                                                       face = nearest.index;
+                                                               }
+                                                       }
+                                                       else { /*  else cast a ray in surface normal direction  */
+                                                               negate_v3(ray_dir);
+                                                               hit.index = -1;
+                                                               hit.dist = brush->paint_distance;
+
+                                                               /* Do a face normal directional raycast, and use that distance  */
+                                                               if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1)
+                                                               {
+                                                                       proxDist = hit.dist;
+                                                                       VECADDFAC(hitCo, ray_start, ray_dir, hit.dist); /* Calculate final hit coordinates */
+                                                                       hQuad = (hit.no[0] == 1.0f);
+                                                                       face = hit.index;
+                                                               }
+                                                       }
+
+                                                       /* If a hit was found, calculate required values        */
+                                                       if (proxDist >= 0.0f) {
+                                                               float dist_rate = proxDist / brush->paint_distance;
+
+                                                                       /* Smooth range or color ramp   */
+                                                                       if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
+                                                                               brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) {
+
+                                                                               /* Limit distance to 0.0 - 1.0 */
+                                                                               if (dist_rate > 1.0f) dist_rate = 1.0f;
+                                                                               if (dist_rate < 0.0f) dist_rate = 0.0f;
+
+                                                                               /* if using smooth falloff, multiply gaussian factor */
+                                                                               if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH) {
+                                                                                       ssFactor += (1.0f - dist_rate) * gaus_factor;
+                                                                               }
+                                                                               else ssFactor += gaus_factor;
+
+                                                                               if (hitFace == -1) {
+                                                                                       distRate = dist_rate;
+                                                                               }
+                                                                       }
+                                                                       else ssFactor += gaus_factor;
+
+                                                                       hit_found = 1;
+
+                                                                       if (hitFace == -1) {
+                                                                               copy_v3_v3(hitCoord, hitCo);
+                                                                               hitQuad = hQuad;
+                                                                               hitFace = face;
+                                                                       }
+                                                       }       // proxDist
+                                               }       // end proximity check
+
+                                               /*
+                                               *       Process color and alpha
+                                               */
+                                               if (hit_found)
+                                               {
+                                                       float sampleColor[3];
+                                                       float sampleAlpha = 1.0f;
+                                                       float bandres[4];
+
+                                                       sampleColor[0] = brush->r;
+                                                       sampleColor[1] = brush->g;
+                                                       sampleColor[2] = brush->b;
+                                               
+                                                       /* Get material+textures color on hit point if required */
+                                                       if (brush->flags & MOD_DPAINT_USE_MATERIAL) dynamicPaint_getMaterialColor(sampleColor, &sampleAlpha, brushOb, bPoint[index].realCoord, hitCoord, hitFace, hitQuad, brush->dm, brush->mat);
+
+                                                       /* Sample colorband if required */
+                                                       if ((distRate >= 0.0f) && (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) && do_colorband(brush->paint_ramp, distRate, bandres)) {
+                                                               if (!(brush->flags & MOD_DPAINT_RAMP_ALPHA)) {
+                                                                       sampleColor[0] = bandres[0];
+                                                                       sampleColor[1] = bandres[1];
+                                                                       sampleColor[2] = bandres[2];
+                                                               }
+                                                               sampleAlpha *= bandres[3];
+                                                       }
+
+                                                       /* Add AA sample */
+                                                       paintColor[0] += sampleColor[0];
+                                                       paintColor[1] += sampleColor[1];
+                                                       paintColor[2] += sampleColor[2];
+
+                                                       paintAlpha += sampleAlpha;
+                                                       numOfHits++;
+                                               }
+                                       } // end supersampling
+
+
+                                       /* if any sample was inside paint range */
+                                       if (ssFactor > 0.01f) {
+
+                                               /* apply supersampling results  */
+                                               /*if (surface->pixelSamples > 1) {
+                                                       ssFactor /= gaussianTotal;
+                                               }*/
+
+                                               //cPoint->state = 2;
+
+                                               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+
+                                                       float paintWetness = brush->wetness * ssFactor;
+
+                                                       /* Get final pixel color and alpha      */
+                                                       paintColor[0] /= numOfHits;
+                                                       paintColor[1] /= numOfHits;
+                                                       paintColor[2] /= numOfHits;
+                                                       paintAlpha /= numOfHits;
+
+                                                       /* Multiply alpha value by the ui multiplier    */
+                                                       paintAlpha = paintAlpha * ssFactor * brush->alpha;
+                                                       if (paintAlpha > 1.0f) paintAlpha = 1.0f;
+
+                                                       /*
+                                                       *       Mix paint to the surface
+                                                       */
+                                                       dynamicPaint_mixPaintColors(surface, index, brush->flags, paintColor, &paintAlpha, &paintWetness, &timescale);
+                                               }
+                                               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+                                                       float *value = (float*)sData->type_data;
+
+                                                       if (brush->flags & MOD_DPAINT_ERASE) {
+                                                               value[index] *= (1.0f - ssFactor);
+                                                               if (value[index] < 0.0f) value[index] = 0.0f;
+                                                       }
+                                                       else {
+                                                               depth /= bPoint[index].normal_scale;
+                                                               /* do displace  */
+                                                               if (value[index] < depth) value[index] = depth;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               /* free bhv tree */
+               free_bvhtree_from_mesh(&treeData);
+               dm->release(dm);
+
+       }
+
+       return 1;
+}
+
+/*
+*      Paint a particle system to the surface
+*/
+static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakePoint *bPoint, ParticleSystem *psys, DynamicPaintBrushSettings *brush, Object *canvasOb, float timescale)
+{
+       int index;
+       ParticleSettings *part=psys->part;
+       ParticleData *pa = NULL;
+       PaintSurfaceData *sData = surface->data;
+
+       KDTree *tree;
+       int particlesAdded = 0;
+       int invalidParticles = 0;
+       int p = 0;
+
+       if (psys->totpart < 1) return 1;
+
+       /*
+       *       Build a kd-tree to optimize distance search
+       */
+       tree= BLI_kdtree_new(psys->totpart);
+
+       /* loop through particles and insert valid ones to the tree     */
+       for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)        {
+
+               /* Proceed only if particle is active   */
+               if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;                                                                 
+               else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;                                                                        
+               else if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
+
+               /*      for debug purposes check if any NAN particle proceeds
+               *       For some reason they get past activity check, this should rule most of them out */
+               if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {invalidParticles++;continue;}
+
+               BLI_kdtree_insert(tree, p, pa->state.co, NULL);
+               particlesAdded++;
+       }
+       if (invalidParticles)
+               printf("Warning: Invalid particle(s) found!\n");
+
+       /* If no suitable particles were found, exit    */
+       if (particlesAdded < 1) {
+               BLI_kdtree_free(tree);
+               return 1;
+       }
+       /* balance tree */
+       BLI_kdtree_balance(tree);
+
+       /*
+       *       Loop through every surface point
+       */
+       #pragma omp parallel for schedule(static)
+       for (index = 0; index < sData->total_points; index++)
+       {
+               float disp_intersect = 0;
+               float radius;
+               float solidradius = brush->particle_radius;
+               float smooth = brush->particle_smooth;
+               float strength = 0.0f;
+
+               /* If using per particle radius */
+               if (brush->flags & MOD_DPAINT_PART_RAD) {
+                       /*
+                       *       If we use per particle radius, we have to sample all particles
+                       *       within max radius range
+                       */
+                       KDTreeNearest *nearest = NULL;
+                       int n, particles = 0;
+                       float range = psys->part->size + smooth;
+
+                       particles = BLI_kdtree_range_search(tree, range, bPoint[index].realCoord, NULL, &nearest);
+                       for(n=0; n<particles; n++) {
+
+                               /*
+                               *       Find particle that produces highest influence
+                               */
+                               ParticleData *pa = psys->particles + nearest[n].index;
+                               float rad = pa->size + smooth;
+                               float str,smooth_range;
+
+                               if (nearest[n].dist > rad) continue; /* if outside range, continue to next one */
+
+                               if ((rad-nearest[n].dist) > disp_intersect) {
+                                       disp_intersect = rad-nearest[n].dist;
+                                       radius = rad;
+                               }
+
+                               /* Continue with paint check    */
+                               if (nearest[n].dist < pa->size) {
+                                       /*  If particle is inside the solid range, no need to continue further
+                                       *       since no other particle can have higher influence */
+                                       strength = 1.0f;
+                                       break;
+                               }
+                               smooth_range = (nearest[n].dist - pa->size);
+
+                               /* do smoothness if enabled     */
+                               if (smooth) smooth_range/=smooth;
+                               str = 1.0f - smooth_range;
+                               /* if influence is greater, use this one        */
+                               if (str > strength) strength = str;
+
+                       }
+                       if (nearest) MEM_freeN(nearest);
+
+               }
+               else {
+                       /*
+                       *       With predefined radius, there is no variation between particles.
+                       *       It's enough to just find the nearest one.
+                       */
+                       KDTreeNearest nearest;
+                       float smooth_range;
+                       radius = solidradius + smooth;
+
+                       /* Find nearest particle and get distance to it */
+                       BLI_kdtree_find_nearest(tree, bPoint[index].realCoord, NULL, &nearest);
+                       if (nearest.dist > radius) continue;
+
+                       /* distances inside solid radius have maximum influence -> dist = 0     */
+                       smooth_range = (nearest.dist - solidradius);
+                       if (smooth_range<0) smooth_range=0.0f;
+                       /* do smoothness if enabled     */
+                       if (smooth) smooth_range/=smooth;
+
+                       strength = 1.0f - smooth_range;
+                       disp_intersect = radius - nearest.dist;
+               }
+
+               if (strength <= 0.0f) continue;
+
+               //cPoint->state = 2;
+
+               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+
+                       float paintAlpha = brush->alpha * strength;
+                       float paintWetness = brush->wetness * strength;
+                       float paintColor[3];
+                       paintColor[0] = brush->r;
+                       paintColor[1] = brush->g;
+                       paintColor[2] = brush->b;
+
+                       if (paintAlpha > 1.0f) paintAlpha = 1.0f;
+
+                       dynamicPaint_mixPaintColors(surface, index, brush->flags, paintColor, &paintAlpha, &paintWetness, &timescale);
+
+               }
+               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+                       float sdepth;
+                       float *value = (float*)sData->type_data;
+
+                       /* change falloff type to inverse square to match real displace depth   */
+                       disp_intersect = (1.0f - sqrt(disp_intersect / radius)) * radius;
+                       /* get displace depth   */
+                       sdepth = (radius - disp_intersect) / bPoint[index].normal_scale;
+
+                       if (sdepth<0.0f) sdepth = 0.0f;
+                       if (value[index] < sdepth) value[index] = sdepth;
+               }
+       }
+       BLI_kdtree_free(tree);
+
+       return 1;
+}
+
+
+/***************************** Dynamic Paint Step / Baking ******************************/
+
+
+/* Prepare for surface step by creating PaintBakePoint data */
+static int dynamicPaint_prepareSurfaceStep(DynamicPaintSurface *surface, PaintBakePoint *bPoint, Object *ob, DerivedMesh *dm, float timescale) {
+       PaintSurfaceData *sData = surface->data;
+
+       MVert *mvert = dm->getVertArray(dm);
+       MFace *mface = dm->getFaceArray(dm);
+       //MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
+
+       int index;
+       FaceAdv *canvasInvNormals = NULL;
+       Vec3f *canvasVerts = NULL;
+
+       int canvasNumOfVerts = dm->getNumVerts(dm);
+       int canvasNumOfFaces = dm->getNumFaces(dm);
+
+       /*
+       *       Make a transformed copy of canvas derived mesh vertices to avoid recalculation.
+       */
+       canvasVerts =  (struct Vec3f *) MEM_mallocN(canvasNumOfVerts*sizeof(struct Vec3f), "Dynamic Paint transformed canvas verts");
+       if (canvasVerts == NULL) return 0;
+
+       #pragma omp parallel for schedule(static)
+       for (index=0; index<canvasNumOfVerts; index++) {
+               
+               /* Multiply coordinates by canvas transformation matrix */
+               VECCOPY(canvasVerts[index].v, mvert[index].co);
+               mul_m4_v3(ob->obmat, canvasVerts[index].v);
+       }
+
+       /*
+       *       Calculate temp per face normals using those transformed coordinates.
+       *       (To not have to calculate same normal for millions of pixels)
+       */
+       canvasInvNormals =  (struct FaceAdv *) MEM_callocN(canvasNumOfFaces*sizeof(struct FaceAdv), "Dynamic Paint canvas normals");
+       if (canvasInvNormals == NULL) return 0;
+
+       #pragma omp parallel for schedule(static)
+       for (index=0; index<canvasNumOfFaces; index++) {
+               if (mface[index].flag & ME_SMOOTH) continue;    /* Only calculate flat faces */
+               
+               /* Transformed normal */
+               normal_tri_v3( canvasInvNormals[index].no, canvasVerts[mface[index].v3].v, canvasVerts[mface[index].v2].v, canvasVerts[mface[index].v1].v);
+               if (mface[index].v4) normal_tri_v3(canvasInvNormals[index].no_q, canvasVerts[mface[index].v4].v, canvasVerts[mface[index].v3].v, canvasVerts[mface[index].v1].v);
+       }
+
+       /*
+       *       Prepare each surface point for a new step
+       */
+       #pragma omp parallel for schedule(static)
+       for (index=0; index<sData->total_points; index++)
+       {
+               /* Do drying dissolve effects */
+               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+                       PaintPoint *pPoint = &((PaintPoint*)sData->type_data)[index];
+                       /* drying */
+                       if (pPoint->wetness > 0.0f) {
+                               /* for every drying step blend wet paint to the background */
+                               float invAlpha = 1.0f - pPoint->e_alpha;
+                               pPoint->color[0] = pPoint->color[0]*invAlpha + pPoint->e_color[0]*pPoint->e_alpha;
+                               pPoint->color[1] = pPoint->color[1]*invAlpha + pPoint->e_color[1]*pPoint->e_alpha;
+                               pPoint->color[2] = pPoint->color[2]*invAlpha + pPoint->e_color[2]*pPoint->e_alpha;
+                               pPoint->state = 1;
+
+                               /* only increase alpha if wet paint has higher  */
+                               if (pPoint->e_alpha > pPoint->alpha) pPoint->alpha = pPoint->e_alpha;
+
+                               /* now dry it ;o        */
+                               if (surface->flags & MOD_DPAINT_DRY_LOG) pPoint->wetness *= 1.0f - (1.0 / (surface->dry_speed/timescale));
+                               else pPoint->wetness -= 1.0f/surface->dry_speed*timescale;
+                       }
+                       /*      If effect layer is completely dry, make sure it's marked empty */
+                       if (pPoint->wetness <= 0.0f) {
+                               pPoint->wetness = 0.0f;
+                               pPoint->e_alpha = 0.0f;
+                               pPoint->state = 0;
+                       }
+
+                       if (surface->flags & MOD_DPAINT_DISSOLVE) {
+
+                               pPoint->alpha -= 1.0f/surface->diss_speed*timescale;
+                               if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
+
+                               pPoint->e_alpha -= 1.0f/surface->diss_speed*timescale;
+                               if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
+                       }
+               }
+               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE &&
+                               surface->flags & MOD_DPAINT_DISSOLVE) {
+                       float *point = &((float*)sData->type_data)[index];
+
+                       *point *= 1.0f - (1.0 / (surface->diss_speed/timescale));
+               }
+
+               /*
+               *       Calculate current 3D-position of each surface pixel
+               */
+               if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
+                       float n1[3], n2[3], n3[3];
+                       PaintTexturePoint *tPoint = &((PaintTexturePoint*)sData->format_data)[index];
+
+                       interp_v3_v3v3v3(       bPoint[index].realCoord,
+                               canvasVerts[tPoint->v1].v,
+                               canvasVerts[tPoint->v2].v,
+                               canvasVerts[tPoint->v3].v, tPoint->barycentricWeights[0].v);
+
+                       /* Calculate current pixel surface normal       */
+                       if(mface[tPoint->face_index].flag & ME_SMOOTH) {
+                               normal_short_to_float_v3(n1, mvert[tPoint->v1].no);
+                               normal_short_to_float_v3(n2, mvert[tPoint->v2].no);
+                               normal_short_to_float_v3(n3, mvert[tPoint->v3].no);
+
+                               interp_v3_v3v3v3(       bPoint[index].invNorm,
+                                       n1, n2, n3, tPoint->barycentricWeights[0].v);
+                               mul_mat3_m4_v3(ob->obmat, bPoint[index].invNorm);
+                               normalize_v3(bPoint[index].invNorm);
+                               negate_v3(bPoint[index].invNorm);
+                       }
+                       else {
+                               if (tPoint->quad) {VECCOPY(bPoint[index].invNorm, canvasInvNormals[tPoint->face_index].no_q);}
+                               else {VECCOPY(bPoint[index].invNorm, canvasInvNormals[tPoint->face_index].no);}
+                       }
+               }
+               else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+                       /* In case of verted data */
+
+                       /* location */
+                       VECCOPY(bPoint[index].realCoord, canvasVerts[index].v);
+
+                       /* normal */
+                       normal_short_to_float_v3(bPoint[index].invNorm, mvert[index].no);
+                       mul_mat3_m4_v3(ob->obmat, bPoint[index].invNorm);
+                       normalize_v3(bPoint[index].invNorm);
+                       //mul_qt_v3(ob->quat, bPoint[index].invNorm);
+                       negate_v3(bPoint[index].invNorm);
+               }
+
+               /* Prepare special data for surface types */
+               if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+                       float temp_nor[3];
+                       if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX)
+                               {normal_short_to_float_v3(temp_nor, mvert[index].no);
+                               normalize_v3(temp_nor);}
+                       else {temp_nor[0]=0.0f;temp_nor[1]=0.0f;temp_nor[2]=1.0f;}
+
+                       mul_v3_v3 (temp_nor, ob->size);
+                       bPoint[index].normal_scale = len_v3(temp_nor);
+               }
+
+               /*
+               *       TODO: paint effect space preparation
+               */
+       }
+
+       MEM_freeN(canvasVerts);
+       MEM_freeN(canvasInvNormals);
+
+       return 1;
+}
+
+static void scene_updateObject(Scene *scene, Object *ob, float frame) {
+       int oflags;
+       /* backup object flags */
+       oflags = ob->recalc;
+
+
+       ob->recalc |= OB_RECALC_ALL;
+       ob->recalc |= OB_RECALC_DATA;
+       BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM);
+       object_handle_update(scene, ob);
+
+       /* restore flags */
+       ob->recalc = oflags;
+}
+
+static void scene_setSubframe(Scene *scene, float subframe) {
+       /* dynamic paint subframes must be done on previous frame */
+       scene->r.cfra -= 1;
+       scene->r.subframe = subframe;
+}
+
+/*
+*      Do Dynamic Paint Step. Paints scene brush objects of current state/frame to canvas.
+*/
+static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
+{
+       PaintSurfaceData *sData = surface->data;
+       DynamicPaintCanvasSettings *canvas = surface->canvas;
+       PaintBakePoint *bPoint;
+
+       if (!sData || sData->total_points < 1) return 0;
+
+       /* Init surface current frame position data */
+       bPoint = (struct PaintBakePoint *) MEM_mallocN(sData->total_points*sizeof(struct PaintBakePoint), "Dynamic Paint step data");
+       if (bPoint == NULL) return printError(canvas, "Not enough free memory.");
+
+       if (!dynamicPaint_prepareSurfaceStep(surface, bPoint, ob, canvas->dm, timescale))
+               return printError(canvas, "Not enough free memory.");
+
+       /*
+       *       Loop through surface's target paint objects and do painting
+       */
+       {
+               Base *base = NULL;
+               GroupObject *go = NULL; 
+
+               Object *brushObj = NULL;
+               ModifierData *md = NULL;
+
+               /* backup current scene frame */
+               int scene_frame = scene->r.cfra;
+               float scene_subframe = scene->r.subframe;
+
+               /* either from group or from all objects */
+               if(surface->brush_group)
+                       go = surface->brush_group->gobject.first;
+               else
+                       base = scene->base.first;
+
+               while (base || go)
+               {
+                       brushObj = NULL;
+
+                       /* select object */
+                       if(surface->brush_group) {                                              
+                               if(go->ob)      brushObj = go->ob;                                      
+                       }                                       
+                       else                                            
+                               brushObj = base->object;
+
+                       if(!brushObj)                                   
+                       {                       
+                               /* skip item */
+                               if(surface->brush_group) go = go->next;
+                               else base= base->next;                                  
+                               continue;                       
+                       }
+
+                       /* next item */
+                       if(surface->brush_group)
+                               go = go->next;
+                       else
+                               base= base->next;
+
+                       md = modifiers_findByType(brushObj, eModifierType_DynamicPaint);
+
+                       /* check if target has an active dp modifier    */
+                       if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))                                    
+                       {
+                               DynamicPaintModifierData *pmd2 = (DynamicPaintModifierData *)md;
+
+                               /* Make sure we're dealing with a painter       */
+                               if((pmd2->type & MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd2->brush)
+                               {
+                                       DynamicPaintBrushSettings *brush = pmd2->brush;
+
+                                       /* update object position on this subframe */
+                                       if (subframe) {
+                                               scene_setSubframe(scene, subframe);
+                                               scene_updateObject(scene, brushObj, BKE_curframe(scene));
+                                       }
+
+
+                                       /*      Check if painter has a particle system selected
+                                       *       -> if so, do particle painting */
+                                       if (brush->collision == MOD_DPAINT_COL_PSYS)
+                                       {
+                                               if (brush && brush->psys && brush->psys->part && brush->psys->part->type==PART_EMITTER)
+                                               if (psys_check_enabled(brushObj, brush->psys)) {
+                                                       /*
+                                                       *       Paint a particle system
+                                                       */
+                                                       dynamicPaint_paintParticles(surface, bPoint, brush->psys, brush, ob, timescale);
+                                               }
+                                       }                                                       
+                                       else {
+                                               /*
+                                               *       Paint a object mesh
+                                               */
+                                               dynamicPaint_paintMesh(surface, bPoint, brush, ob, brushObj, timescale);
+                                       }
+
+                                       /* return object to it's original state */
+                                       if (subframe) {
+                                               scene->r.cfra = scene_frame;
+                                               scene->r.subframe = scene_subframe;
+                                               scene_updateObject(scene, brushObj, BKE_curframe(scene));
+                                       }
+                               } /* end of collision check (Is valid paint modifier) */
+                       }
+               }
+       }
+
+       MEM_freeN(bPoint);
+
+       return 1;
+}
+
+/*
+*      Calculate a single frame for canvas point cache
+*/
+static int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Object *cObject, int frame)
+{
+       float timescale = 1.0f;
+       
+       /* dont do substeps for first frame */
+       if (surface->substeps && (frame != surface->start_frame)) {
+               int st;
+               timescale = 1.0f / (surface->substeps+1);
+
+               for (st = 1; st <= surface->substeps; st++)
+               {
+                       float subframe = ((float) st) / (surface->substeps+1);
+
+                       if (!dynamicPaint_doStep(scene, cObject, surface, timescale, subframe)) return 0;
+               }
+       }
+
+       if (!dynamicPaint_doStep(scene, cObject, surface, timescale, 0.0f)) return 0;
+       else  return 1;
+}
+
+/***************************** Image Sequence Baking ******************************/
+
+/*
+*      Do actual bake operation. Loops through to-be-baked frames.
+*      Returns 0 on failture.
+*/
+static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surface, Object *cObject)
+{
+       DynamicPaintCanvasSettings *canvas = surface->canvas;
+       Scene *scene= CTX_data_scene(C);
+       wmWindow *win = CTX_wm_window(C);
+       int frame = 1;
+       int frames;
+
+       frames = surface->end_frame - surface->start_frame + 1;
+       if (frames <= 0) {return printError(canvas, "No frames to bake.");}
+
+       /*
+       *       Set frame to start point (also inits modifier data)
+       */
+       frame = surface->start_frame;
+       scene->r.cfra = (int)frame;
+       ED_update_for_newframe(CTX_data_main(C), scene, win->screen, 1);
+
+       /* Init surface */
+       if (!dynamicPaint_createUVSurface(surface)) return 0;
+
+
+       /*
+       *       Loop through selected frames
+       */
+       for (frame=surface->start_frame; frame<=surface->end_frame; frame++)
+       {
+               float timescale = 1.0f / (surface->substeps+1);
+               int st;
+               float progress = (frame - surface->start_frame) / (float)frames * 100;
+               surface->current_frame = frame;
+
+               /* If user requested stop (esc), quit baking    */
+               if (blender_test_break()) return 0;
+
+               /* Update progress bar cursor */
+               WM_timecursor(win, (int)progress);
+
+               printf("DynamicPaint: Baking frame %i\n", frame);
+
+               /*
+               *       Do calculations for every substep
+               *       Note: these have to be from previous frame
+               */
+               if (frame != surface->start_frame) {
+                       /* change to next frame */
+                       scene->r.cfra = (int)frame;
+                       scene->r.subframe = 0.0f;
+                       ED_update_for_newframe(CTX_data_main(C), scene, win->screen, 1);
+
+                       for (st = 1; st <= surface->substeps; st++)
+                       {
+                               float subframe = ((float) st) / (surface->substeps+1);
+
+                               if (!dynamicPaint_doStep(scene, cObject, surface, timescale, subframe)) return 0;
+                       }
+               }
+
+               if (!dynamicPaint_doStep(scene, cObject, surface, timescale, 0.0f)) return 0;
+
+               /*
+               *       Save output images
+               */
+               {
+                       char filename[250];
+                       char pad[4];
+                       char dir_slash[2];
+                                               /* OpenEXR or PNG       */
+                       int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? DPOUTPUT_OPENEXR : DPOUTPUT_PNG;
+
+                       /* Add frame number padding     */
+                       if (frame<10) sprintf(pad,"000");
+                       else if (frame<100) sprintf(pad,"00");
+                       else if (frame<1000) sprintf(pad,"0");
+                       else pad[0] = '\0';
+
+                       /* make sure directory path is valid to append filename */
+                       if (surface->image_output_path[strlen(surface->image_output_path)-1] != 47 &&
+                               surface->image_output_path[strlen(surface->image_output_path)-1] != 92)
+                               strcpy(dir_slash,"/");
+                       else
+                               dir_slash[0] = '\0';
+
+
+                       /* color map    */
+                       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+                               sprintf(filename, "%s%s%s%s%i", surface->image_output_path, dir_slash, surface->output_name, pad, (int)frame);
+                               dynamicPaint_outputImage(surface, filename, format, DPOUTPUT_PAINT);
+
+                               sprintf(filename, "%s%s%s%s%i", surface->image_output_path, dir_slash, surface->output_name2, pad, (int)frame);
+                               dynamicPaint_outputImage(surface, filename, format, DPOUTPUT_WET);
+                       }
+
+                       /* displacement map     */
+                       if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+                               sprintf(filename, "%s%s%s%s%i", surface->image_output_path, dir_slash, surface->output_name, pad, (int)frame);
+                               dynamicPaint_outputImage(surface, filename, format, DPOUTPUT_DISPLACE);
+                       }
+               }
+       }
+       return 1;
+}
+
+
+/*
+*      An operator call to start baking dynamic paint image sequences for active object
+*/
+static int dynamicPaint_initBake(bContext *C, wmOperator *op)
+{
+       DynamicPaintModifierData *pmd = NULL;
+       Object *cObject = CTX_data_active_object(C);
+       int status = 0;
+       double timer = PIL_check_seconds_timer();
+       DynamicPaintSurface *surface;
+
+       /*
+       *       Get modifier data
+       */
+       pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
+       if (!pmd) {
+               BKE_report(op->reports, RPT_ERROR, "Bake Failed: No Dynamic Paint modifier found.");
+               return 0;
+       }
+
+       /* Make sure we're dealing with a canvas */
+       if (!pmd->canvas) {
+               BKE_report(op->reports, RPT_ERROR, "Bake Failed: Invalid Canvas.");
+               return 0;
+       }
+       surface = get_activeSurface(pmd->canvas);
+
+       /* Set state to baking and init surface */
+       pmd->canvas->error[0] = '\0';
+       pmd->canvas->flags |= MOD_DPAINT_BAKING;
+       G.afbreek= 0;   /* reset blender_test_break*/
+
+       /*  Bake Dynamic Paint  */
+       status = dynamicPaint_bakeImageSequence(C, surface, cObject);
+       /* Clean bake flag */
+       pmd->canvas->flags &= ~MOD_DPAINT_BAKING;
+       /* Restore cursor back to normal        */
+       WM_cursor_restore(CTX_wm_window(C));
+
+       /* Bake was successful:
+       *  Report for ended bake and how long it took */
+       if (status) {
+
+               /* Format time string   */
+               char timestr[30];
+               double time = PIL_check_seconds_timer() - timer;
+               int tmp_val;
+               timestr[0] = '\0';
+
+               /* days (just in case someone actually has a very slow pc)      */
+               tmp_val = (int)floor(time / 86400.0f);
+               if (tmp_val > 0) sprintf(timestr, "%i Day(s) - ", tmp_val);
+               /* hours        */
+               time -= 86400.0f * tmp_val;
+               tmp_val = (int)floor(time / 3600.0f);
+               if (tmp_val > 0) sprintf(timestr, "%s%i h ", timestr, tmp_val);
+               /* minutes      */
+               time -= 3600.0f * tmp_val;
+               tmp_val = (int)floor(time / 60.0f);
+               if (tmp_val > 0) sprintf(timestr, "%s%i min ", timestr, tmp_val);
+               /* seconds      */
+               time -= 60.0f * tmp_val;
+               tmp_val = (int)ceil(time);
+               sprintf(timestr, "%s%i s", timestr, tmp_val);
+
+               /* Show bake info */
+               sprintf(pmd->canvas->ui_info, "Bake Complete! (Time: %s)", timestr);
+               printf("%s\n", pmd->canvas->ui_info);
+       }
+       else {
+               if (strlen(pmd->canvas->error)) { /* If an error occured */
+                       sprintf(pmd->canvas->ui_info, "Bake Failed: %s", pmd->canvas->error);
+                       BKE_report(op->reports, RPT_ERROR, pmd->canvas->ui_info);
+               }
+               else {  /* User cancelled the bake */
+                       sprintf(pmd->canvas->ui_info, "Baking Cancelled!");
+                       BKE_report(op->reports, RPT_WARNING, pmd->canvas->ui_info);
+               }
+
+               /* Print failed bake to console */
+               printf("Baking Cancelled!\n");
+       }
+
+       return status;
+}
+
+
+/***************************** Operators ******************************/
+
+static int dynamicpaint_bake_exec(bContext *C, wmOperator *op)
+{
+
+       /* Bake dynamic paint */
+       if(!dynamicPaint_initBake(C, op)) {
+               return OPERATOR_CANCELLED;}
+
+       return OPERATOR_FINISHED;
+}
+
+void DPAINT_OT_bake(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Dynamic Paint Bake";
+       ot->description= "Bake dynamic paint";
+       ot->idname= "DPAINT_OT_bake";
+       
+       /* api callbacks */
+       ot->exec= dynamicpaint_bake_exec;
+       ot->poll= ED_operator_object_active_editable;
+}
+
+static int surface_slot_add_exec(bContext *C, wmOperator *op)
+{
+       DynamicPaintModifierData *pmd = NULL;
+       Object *cObject = CTX_data_active_object(C);
+       DynamicPaintSurface *surface;
+
+       /* Make sure we're dealing with a canvas */
+       pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
+       if (!pmd) return OPERATOR_CANCELLED;
+       if (!pmd->canvas) return OPERATOR_CANCELLED;
+
+       surface = dynamicPaint_createNewSurface(pmd->canvas);
+
+       if (!surface) return OPERATOR_CANCELLED;
+
+       /* set preview for this surface only and set active */
+       pmd->canvas->active_sur = 0;
+       for(surface=surface->prev; surface; surface=surface->prev) {
+                               surface->flags &= ~MOD_DPAINT_PREVIEW;
+                               pmd->canvas->active_sur++;
+       }
+
+       return OPERATOR_FINISHED;
+}
+
+/* add surface slot */
+void DPAINT_OT_surface_slot_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Surface Slot";
+       ot->idname= "DPAINT_OT_surface_slot_add";
+       ot->description="Add a new Dynamic Paint surface slot";
+       
+       /* api callbacks */
+       ot->exec= surface_slot_add_exec;
+       ot->poll= ED_operator_object_active_editable;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int surface_slot_remove_exec(bContext *C, wmOperator *op)
+{
+       DynamicPaintModifierData *pmd = NULL;
+       Object *cObject = CTX_data_active_object(C);
+       DynamicPaintSurface *surface;
+       int id=0;
+
+       /* Make sure we're dealing with a canvas */
+       pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
+       if (!pmd) return OPERATOR_CANCELLED;
+       if (!pmd->canvas) return OPERATOR_CANCELLED;
+
+       surface = pmd->canvas->surfaces.first;
+
+       /* find active surface and remove it */
+       for(; surface; surface=surface->next) {
+               if(id == pmd->canvas->active_sur) {
+                               pmd->canvas->active_sur -= 1;
+                               dynamicPaint_freeSurface(surface);
+                               break;
+                       }
+               id++;
+       }
+
+       dynamicPaint_resetPreview(pmd->canvas);
+       DAG_id_tag_update(&cObject->id, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject);
+
+       return OPERATOR_FINISHED;
+}
+
+/* remove surface slot */
+void DPAINT_OT_surface_slot_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Remove Surface Slot";
+       ot->idname= "DPAINT_OT_surface_slot_remove";
+       ot->description="Remove the selected surface slot";
+       
+       /* api callbacks */
+       ot->exec= surface_slot_remove_exec;
+       ot->poll= ED_operator_object_active_editable;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
index f71e2e9a6e9cab3ec97da7362333681bb46a6812..2dcefb980124914cdeebbce4766e4b7ff96b2891 100644 (file)
@@ -49,6 +49,7 @@
 #include "DNA_particle_types.h"
 #include "DNA_smoke_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_dynamicpaint_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
@@ -3455,6 +3456,14 @@ void object_remove_particle_system(Scene *scene, Object *ob)
                                smd->flow->psys = NULL;
        }
 
+       if((md = modifiers_findByType(ob, eModifierType_DynamicPaint)))
+       {
+               DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+               if((pmd->type == MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd->brush && pmd->brush->psys)
+                       if(pmd->brush->psys == psys)
+                               pmd->brush->psys = NULL;
+       }
+
        /* clear modifier */
        psmd= psys_get_modifier(ob, psys);
        BLI_remlink(&ob->modifiers, psmd);
index 64893bb0b5bbdc983bc1ad9ab38b3e4af8e51ecf..e92ba11826e838bac2090ea778a837d024707457 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "DNA_ID.h"
 #include "DNA_cloth_types.h"
+#include "DNA_dynamicpaint_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
@@ -60,6 +61,7 @@
 #include "BKE_blender.h"
 #include "BKE_cloth.h"
 #include "BKE_depsgraph.h"
+#include "BKE_dynamicpaint.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
@@ -602,7 +604,7 @@ static int  ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
 
        return ret;
 }
-static void ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
+static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
 {
        SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
        SmokeDomainSettings *sds = smd->domain;
@@ -651,6 +653,82 @@ static void ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
                        ptcache_file_compressed_read(pf, (unsigned char*)tcw, out_len);
                }
        }
+
+       return 1;
+}
+
+static int ptcache_dynamicpaint_totpoint(void *sd, int cfra)
+{
+       DynamicPaintSurface *surface = (DynamicPaintSurface*)sd;
+
+       if (!surface->data) return 0;
+       else return surface->data->total_points;
+}
+
+#define DP_CACHE_VERSION "1.01"
+
+static int  ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
+{      
+       DynamicPaintSurface *surface = (DynamicPaintSurface*)dp_v;
+       int cache_compress = 1;
+
+       /* version header */
+       ptcache_file_write(pf, DP_CACHE_VERSION, 1, sizeof(char)*4);
+
+       if(surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
+               unsigned int total_points=surface->data->total_points;
+               unsigned int in_len;
+               unsigned char *out;
+
+               /* cache type */
+               ptcache_file_write(pf, &surface->type, 1, sizeof(int));
+
+               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+                       in_len = sizeof(PaintPoint)*total_points;
+                       out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
+               }
+               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
+                       in_len = sizeof(float)*total_points;
+                       out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
+               }
+               else return 0;
+
+               ptcache_file_compressed_write(pf, (unsigned char *)surface->data->type_data, in_len, out, cache_compress);
+               MEM_freeN(out);
+
+       }
+       return 1;
+}
+static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
+{
+       DynamicPaintSurface *surface = (DynamicPaintSurface*)dp_v;
+       char version[4];
+       
+       /* version header */
+       ptcache_file_read(pf, version, 1, sizeof(char)*4);
+       if (strncmp(version, DP_CACHE_VERSION,4)) {printf("Dynamic Paint: Invalid cache version: %s!\n",version); return 0;}
+
+       if(surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
+               unsigned int data_len;
+               int surface_type;
+
+               /* cache type */
+               ptcache_file_read(pf, &surface_type, 1, sizeof(int));
+
+               if (surface_type != surface->type)
+                       return 0;
+
+               /* read surface data */
+               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
+                       data_len = sizeof(PaintPoint);
+               else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE)
+                       data_len = sizeof(float);
+               else return 0;
+
+               ptcache_file_compressed_read(pf, (unsigned char*)surface->data->type_data, data_len*surface->data->total_points);
+
+       }
+       return 1;
 }
 
 /* Creating ID's */
@@ -805,6 +883,40 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
        if(sds->wt)
                pid->data_types |= (1<<BPHYS_DATA_SMOKE_HIGH);
 }
+
+void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, Object *ob, DynamicPaintSurface *surface)
+{
+
+       memset(pid, 0, sizeof(PTCacheID));
+
+       pid->ob= ob;
+       pid->calldata= surface;
+       pid->type= PTCACHE_TYPE_DYNAMICPAINT;
+       pid->cache= surface->pointcache;
+       pid->cache_ptr= &surface->pointcache;
+       pid->ptcaches= &surface->ptcaches;
+       pid->totpoint= pid->totwrite= ptcache_dynamicpaint_totpoint;
+
+       pid->write_point                        = NULL;
+       pid->read_point                         = NULL;
+       pid->interpolate_point          = NULL;
+
+       pid->write_stream                       = ptcache_dynamicpaint_write;
+       pid->read_stream                        = ptcache_dynamicpaint_read;
+
+       pid->write_extra_data           = NULL;
+       pid->read_extra_data            = NULL;
+       pid->interpolate_extra_data     = NULL;
+
+       pid->write_header                       = ptcache_basic_header_write;
+       pid->read_header                        = ptcache_basic_header_read;
+
+       pid->data_types= BPHYS_DATA_DYNAMICPAINT;
+       pid->info_types= 0;
+
+       pid->stack_index = pid->cache->index;
+}
+
 void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
 {
        PTCacheID *pid;
@@ -845,7 +957,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
                        BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
                        BLI_addtail(lb, pid);
                }
-               if(md->type == eModifierType_Smoke) {
+               else if(md->type == eModifierType_Smoke) {
                        SmokeModifierData *smd = (SmokeModifierData *)md;
                        if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
                        {
@@ -854,6 +966,19 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
                                BLI_addtail(lb, pid);
                        }
                }
+               else if(md->type == eModifierType_DynamicPaint) {
+                       DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+                       if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+                       {
+                               DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+
+                               for (; surface; surface=surface->next) {
+                                       pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+                                       BKE_ptcache_id_from_dynamicpaint(pid, ob, surface);
+                                       BLI_addtail(lb, pid);
+                               }
+                       }
+               }
        }
 
        if(scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) {
@@ -1586,7 +1711,8 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
                ptcache_file_pointers_init(pf);
 
                // we have stream reading here
-               pid->read_stream(pf, pid->calldata);
+               if (!pid->read_stream(pf, pid->calldata))
+                       error = 1;
        }
 
        ptcache_file_close(pf);
@@ -1722,15 +1848,21 @@ int BKE_ptcache_read(PTCacheID *pid, float cfra)
                return 0;
 
        if(cfra1) {
-               if(pid->read_stream)
-                       ptcache_read_stream(pid, cfra1);
+               
+               if(pid->read_stream) {
+                       if (!ptcache_read_stream(pid, cfra1))
+                               return 0;
+               }
                else if(pid->read_point)
                        ptcache_read(pid, cfra1);
        }
 
        if(cfra2) {
-               if(pid->read_stream)
-                       ptcache_read_stream(pid, cfra2);
+               
+               if(pid->read_stream) {
+                       if (!ptcache_read_stream(pid, cfra2))
+                               return 0;
+               }
                else if(pid->read_point) {
                        if(cfra1 && cfra2 && pid->interpolate_point)
                                ptcache_interpolate(pid, cfra, cfra1, cfra2);
@@ -2278,6 +2410,8 @@ int  BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
                        smokeModifier_reset(pid->calldata);
                else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES)
                        smokeModifier_reset_turbulence(pid->calldata);
+               else if(pid->type == PTCACHE_TYPE_DYNAMICPAINT)
+                       dynamicPaint_resetSurface((DynamicPaintSurface*)pid->calldata);
        }
        if(clear)
                BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
@@ -2334,6 +2468,18 @@ int  BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
                                reset |= BKE_ptcache_id_reset(scene, &pid, mode);
                        }
                }
+               if(md->type == eModifierType_DynamicPaint) {
+                       DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+                       if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+                       {
+                               DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+
+                               for (; surface; surface=surface->next) {
+                                       BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
+                                       reset |= BKE_ptcache_id_reset(scene, &pid, mode);
+                               }
+                       }
+               }
        }
 
        if (ob->type == OB_ARMATURE)
index b34b9c4b70f27d99ba887e21ecb689a206da421e..d83a2ac6ad57b6e57ccd1e013ee4385af5f665da 100644 (file)
@@ -60,6 +60,7 @@ float area_poly_v3(int nr, float verts[][3], const float normal[3]);
 
 float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
 float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
+void closest_to_line_segment_v2(float *closest, float p[2], float l1[2], float l2[2]);
 
 float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
 float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
index 96ed788a49fa8ab363df59403ae774061ae20291..9a543a3f4a3d19288509b2ddaad47b781c604ebd 100644 (file)
@@ -211,6 +211,21 @@ float dist_to_line_segment_v2(const float v1[2], const float v2[2], const float
        return sqrtf(rc[0]*rc[0]+ rc[1]*rc[1]);
 }
 
+/* point closest to v1 on line v2-v3 in 2D */
+void closest_to_line_segment_v2(float *closest, float p[2], float l1[2], float l2[2])
+{
+       float lambda, cp[2];
+
+       lambda= closest_to_line_v2(cp,p, l1, l2);
+
+       if(lambda <= 0.0f)
+               copy_v2_v2(closest, l1);
+       else if(lambda >= 1.0f)
+               copy_v2_v2(closest, l2);
+       else
+               copy_v2_v2(closest, cp);
+}
+
 /* point closest to v1 on line v2-v3 in 3D */
 void closest_to_line_segment_v3(float closest[3], const float v1[3], const float v2[3], const float v3[3])
 {
index 222c4bcf6fc0a3f29d03d163db8b0f5abe93fa5b..0b3e2dc2577c02ea46df528a43c9a08ca361a17e 100644 (file)
@@ -58,6 +58,7 @@
 #include "DNA_cloth_types.h"
 #include "DNA_controller_types.h"
 #include "DNA_constraint_types.h"
+#include "DNA_dynamicpaint_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_fileglobal_types.h"
 #include "DNA_genfile.h"
@@ -4020,6 +4021,44 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 
                        }
                }
+               else if (md->type==eModifierType_DynamicPaint) {
+                       DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
+
+                       if(pmd->type==MOD_DYNAMICPAINT_TYPE_CANVAS)
+                       {
+                               pmd->brush = NULL;
+
+                               pmd->canvas = newdataadr(fd, pmd->canvas);
+                               pmd->canvas->pmd = pmd;
+                               pmd->canvas->dm = NULL;
+                               pmd->canvas->ui_info[0] = '\0';
+                               pmd->canvas->flags &= ~MOD_DPAINT_BAKING; /* just in case */
+
+                               if (pmd->canvas->surfaces.first) {
+                                       DynamicPaintSurface *surface;
+                                       link_list(fd, &pmd->canvas->surfaces);
+
+                                       for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next) {
+                                               surface->canvas = pmd->canvas;
+                                               surface->data = NULL;
+                                               direct_link_pointcache_list(fd, &(surface->ptcaches), &(surface->pointcache), 1);
+                                       }
+                               }
+                       }
+                       else if(pmd->type==MOD_DYNAMICPAINT_TYPE_BRUSH)
+                       {
+                               pmd->canvas = NULL;
+
+                               pmd->brush = newdataadr(fd, pmd->brush);
+                               if (pmd->brush) {
+                                       pmd->brush->pmd = pmd;
+                                       pmd->brush->mat = newdataadr(fd, pmd->brush->mat);
+                                       pmd->brush->psys = newdataadr(fd, pmd->brush->psys);
+                                       pmd->brush->paint_ramp = newdataadr(fd, pmd->brush->paint_ramp);
+                                       pmd->brush->dm = NULL;
+                               }
+                       }
+               }
                else if (md->type==eModifierType_Collision) {
                        
                        CollisionModifierData *collmd = (CollisionModifierData*) md;
@@ -11162,7 +11201,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                /* enable all cache display */
                                                stime->cache_display |= TIME_CACHE_DISPLAY;
                                                stime->cache_display |= (TIME_CACHE_SOFTBODY|TIME_CACHE_PARTICLES);
-                                               stime->cache_display |= (TIME_CACHE_CLOTH|TIME_CACHE_SMOKE);
+                                               stime->cache_display |= (TIME_CACHE_CLOTH|TIME_CACHE_SMOKE|TIME_CACHE_DYNAMICPAINT);
                                        }
                                }
                        }
index 240e8d00ab8d1b825652c9c850fba57248f9b4e9..0a22a66fe61920d0b33f9c2a561c5a5f36176b33 100644 (file)
@@ -99,6 +99,7 @@ Any case: direct data is ALWAYS after the lib block
 #include "DNA_cloth_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_controller_types.h"
+#include "DNA_dynamicpaint_types.h"
 #include "DNA_genfile.h"
 #include "DNA_group_types.h"
 #include "DNA_gpencil_types.h"
@@ -1250,6 +1251,28 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                        FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
                        
                        writestruct(wd, DATA, "FluidsimSettings", 1, fluidmd->fss);
+               }
+               else if(md->type==eModifierType_DynamicPaint) {
+                       DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
+                       
+                       if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
+                       {
+                               DynamicPaintSurface *surface;
+                               writestruct(wd, DATA, "DynamicPaintCanvasSettings", 1, pmd->canvas);
+                               
+                               /* write surfaces */
+                               for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next)
+                                       writestruct(wd, DATA, "DynamicPaintSurface", 1, surface);
+                               /* write caches */
+                               for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next)
+                                       write_pointcaches(wd, &(surface->ptcaches));
+                       }
+                       else if(pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH && pmd->brush)
+                       {
+                               writestruct(wd, DATA, "DynamicPaintBrushSettings", 1, pmd->brush);
+                               writestruct(wd, DATA, "Material", 1, pmd->brush->mat);
+                               writestruct(wd, DATA, "ColorBand", 1, pmd->brush->paint_ramp);
+                       }
                } 
                else if (md->type==eModifierType_Collision) {
                        
index 7525015bca9e926c3c22caf7c649e104ab2b943a..d89594bc2a3965da5067550be87d02300cd048e8 100644 (file)
-/** \file blender/editors/datafiles/blenderbuttons.c
- *  \ingroup eddatafiles
- */
 /* DataToC output of file <blenderbuttons> */
 
-int datatoc_blenderbuttons_size= 210335;
+int datatoc_blenderbuttons_size= 195798;
 char datatoc_blenderbuttons[]= {
-137, 80, 78, 71, 13, 10, 26, 10,  0,  0,  0, 13, 73, 72, 68, 82,  0,  0,  2, 90,  0,  0,  2,128,  8,  6,  0,  0,  0, 68,254,
-214,163,  0,  0, 10, 79,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,105,108,101,  0,
-  0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, 75,136,128,148, 75,111, 82, 21,  8, 32, 82, 66,139,128, 20,145, 38,
- 42, 33,  9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69,  4, 27,200,160,136,  3,142,142,128,140, 21, 81, 44, 12,138, 10,216,
-  7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,179,207,  7,192,
-  8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112,  0, 16,  8,179,100, 33,
-115,253, 35,  1,  0,248,126, 60, 60, 43, 34,192,  7,190,  0,  1,120,211, 11,  8,  0,192, 77,155,192, 48, 28,135,255, 15,234, 66,
-153, 92,  1,128,132,  1,192,116,145, 56, 75,  8,128, 20,  0, 64,122,142, 66,166,  0, 64, 70,  1,128,157,152, 38, 83,  0,160,  4,
-  0, 96,203, 99, 98,227,  0, 80, 45,  0, 96, 39,127,230,211,  0,128,157,248,153,123,  1,  0, 91,148, 33, 21,  1,160,145,  0, 32,
- 19,101,136, 68,  0,104, 59,  0,172,207, 86,138, 69,  0, 88, 48,  0, 20,102, 75,196, 57,  0,216, 45,  0, 48, 73, 87,102, 72,  0,
-176,183,  0,192,206, 16, 11,178,  0,  8, 12,  0, 48, 81,136,133, 41,  0,  4,123,  0, 96,200, 35, 35,120,  0,132,153,  0, 20, 70,
-242, 87, 60,241, 43,174, 16,231, 42,  0,  0,120,153,178, 60,185, 36, 57, 69,129, 91,  8, 45,113,  7, 87, 87, 46, 30, 40,206, 73,
- 23, 43, 20, 54, 97,  2, 97,154, 64, 46,194,121,153, 25, 50,129, 52, 15,224,243,204,  0,  0,160,145, 21, 17,224,131,243,253,120,
-206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191,  6,255, 34, 98, 98,227,254,229,207,171,112, 64,  0,  0,225,116,126,209,254,
- 44, 47,179, 26,128, 59,  6,128,109,254,162, 37,238,  4,104, 94, 11,160,117,247,139,102,178, 15, 64,181,  0,160,233,218, 87,243,
-112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, 87,253,108,249,
-126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71,  4,248,224,194,204,244, 76,165, 28,207,146,  9,132, 98,220,230,143, 71,
-252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, 66,146, 41,197,
- 37,210,255,100,226,223, 44,251,  3, 62,223, 53,  0,176,106, 62,  1,123,145, 45,168, 93, 99,  3,246, 75, 39, 16, 88,116,192,226,
-247,  0,  0,242,187,111,193,212, 40,  8,  3,128,104,131,225,207,119,255,239, 63,253, 71,160, 37,  0,128,102, 73,146,113,  0,  0,
- 94, 68, 36, 46, 84,202,179, 63,199,  8,  0,  0, 68,160,129, 42,176, 65, 27,244,193, 24, 44,192,  6, 28,193,  5,220,193, 11,252,
- 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,212, 64, 29, 52,
-192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15,250, 97,  8,158,193, 40,188,129,  9,  4, 65,200,  8, 19, 97, 33,218,
-136,  1, 98,138, 88, 35,142,  8, 23,153,133,248, 33,193, 72,  4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, 72, 49, 82,138,
- 84, 32, 85, 72, 29,242, 61,114,  2, 57,135, 92, 70,186,145, 59,200,  0, 50,130,252,134,188, 71, 49,148,129,178, 81, 61,212, 12,
-181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,208,171,104, 15,
-218,143, 62, 67,199, 48,192,232, 24,  7, 51,196,108, 48, 46,198,195, 66,177, 56, 44,  9,147, 99,203,177, 34,172, 12,171,198, 26,
-176, 86,172,  3,187,137,245, 99,207,177,119,  4, 18,129, 69,192,  9, 54,  4,119, 66, 32, 97, 30, 65, 72, 88, 76, 88, 78,216, 72,
-168, 32, 28, 36, 52, 17,218,  9, 55,  9,  3,132, 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, 49,135, 88, 72,
- 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18,137, 67, 50, 39,185,144,  2, 73,177,164, 84,210, 18,210, 70,210,110,
- 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107,178,  7, 57,148, 44, 32, 43,200,133,228,157,228,195,228, 51,228, 27,
-228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82,202,106, 74, 25,229, 16,229, 52,229,  6,101,152, 50, 65, 85,163,154,
- 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,165,173,162,149,
-211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232,  3,244,119, 12, 13,134,
- 21,131,199,136,103, 40, 25,155, 24,  7, 24,103, 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,235,152,231,153,
- 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, 11, 85,243, 85,
-203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169,  9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, 59,168,135,170,
-103,168,111, 84, 63,164,126, 89,253,137,  6, 89,195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, 25,179,120, 44,
- 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, 51, 74, 51, 87,
-179, 82,243,148,102, 63,  7,227,152,113,248,156,116, 78,  9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, 27,166, 52, 76,
-185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,251,129, 14, 65,
-199, 74, 39, 92, 39, 71,103,143,206,  5,157,231, 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,165, 27,161,187,
- 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,167,245, 71, 12,
- 88,  6,179, 12, 36,  6,219, 12,206, 24, 60,197, 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, 97,149, 97,151,
-225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, 92,227, 36,227,109,198,109,198,163, 38,  6, 38, 33, 38, 75, 77,234,
- 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,155,231,155,215,
-155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, 88, 85, 90, 93,
-179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,183, 25,176,229,
-216,  6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61,  7, 13,135,217, 14,
-171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,207,216, 51,227,
-182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,155, 27,198,221,
-200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,159,204, 52,159,
- 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,231, 35, 47, 99,
- 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, 95,204, 55,192,
-183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255,100,255,122,255,209,  0,167,128, 37,  1,103,  3,137,129, 65,129, 91,
-  2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,193,173, 33,104,
-200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80,126,232,214,208,  7, 97,230, 97,139,195,126, 12, 39,133,135,133, 87,
-134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,175, 45, 74, 53,
- 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,174, 54,110,108,
-190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46, 18, 44, 58,150,
- 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, 54,209,136,216,
- 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, 76, 13, 76,221,
-155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,102,118,203,172,
-101,133,178,254,197,110,139,183, 47, 30,149,  7,201,107,179,144,172,  5, 89, 45, 10,182, 66,166,232, 84, 90, 40,215, 42,  7,178,
-103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194, 18,225,146,182,
-165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113,121,219, 10,227, 21,  5, 43,134, 86,  6,172, 60,184,138,182, 42,109,
-213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94,193,202,130,193,181,  1,107,235, 11, 85, 10,229,133,125,235,220,215,
-237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,229, 27,135,111,
-202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,110, 13,217,218,
-180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,206,205, 59, 63,
- 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,247,253, 62,201,
-190,219, 85,  1, 85, 77,213,102,213,101,251, 73,251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,113,237,199,  3,
-210,  3,253,  7, 35, 14,182,215,185,212,213, 29,210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,119, 45, 13, 54,
- 13, 85,141,156,198,226, 35,112, 68,121,228,233,247,  9,223,247, 30, 13, 58,218,118,140,123,172,225,  7,211, 31,118, 29,103, 29,
- 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,156, 52, 60, 89,
-121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,231, 99,206,223,
-106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, 87,154,175, 58,
- 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233, 27,158, 55,206,
-221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,206,203,187,217,
-119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,160,243,209,220,
- 71,247,  6,133,131,207,254,145,245,143, 15, 67,  5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,114,253,233,252,
-167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,151,147,191,109,
-124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,239,163,223, 15,
- 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251,147, 25,147,147,255,  4,  3,152,243,252, 99, 51, 45,219,  0,  0,  0,
-  6, 98, 75, 71, 68,  0,255,  0,255,  0,255,160,189,167,147,  0,  0,  0,  9,112, 72, 89,115,  0,  0, 13,215,  0,  0, 13,215,  1,
- 66, 40,155,120,  0,  0,  0,  7,116, 73, 77, 69,  7,219,  2, 27, 16, 38, 47, 61,220,216,191,  0,  0, 32,  0, 73, 68, 65, 84,120,
-218,236, 93,119,120, 20,213,226, 61, 51, 59,179,187,217,146, 77, 35, 61,144, 66,  9, 96,  0, 67, 81,130, 84, 65, 80,140,138, 10,
- 86,132,167,207,103,197,134,  5, 84, 68, 68, 32, 54, 64,240, 39,242,208,167,128,160,128,  5,  4,164, 68, 74,232, 29,233,  9,144,
-  4, 18, 66, 58,201, 38,219,203,220,223, 31,217, 89, 55,203,182, 64, 98,129,123,190,111,190,221,157,157, 57,115,239,157,123,239,
-156, 57,183,  1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,215, 52, 86,175, 94, 77,154,112,248,144,
- 64, 57, 29,219,128,191, 59,103, 11,198,157, 52, 35,231,  0,  7,231,187,255,144,112, 14,248,187,114,138,241,109,  2,239,144,166,
-228,163,230, 74, 79,151,112,146,230, 14,103, 75,113, 54, 87, 57,242, 16, 78,210,  2,247,253,221,127, 72, 56,  7,252,221, 56,221,
-243, 79,128,188, 77,226, 12, 48, 79, 53, 53,156,164,185,195,217, 82,156, 87, 91,142,124,132,147, 92,109, 94,242,114,239,223,197,
-117,  4,174,  5, 69, 86,192,200,204,204,100, 92,248,153,191, 43,167,107, 58,136,252,205, 25,214,102,196,150,230,230,116, 75,207,
-230,194,187,153,153,153,204,234,213,171,183,  2, 24,208,156,113,111,142,251,238, 22,215,102,225,189,  2,145,213, 36,206,230,202,
-247, 45,205,217, 92,101,201,157,179, 57,242,189,167,251,222,130,247,168,185,194,217, 44,101,169, 37,242,188,135,252,115,213,188,
-238,156,205, 81,150,220, 57,155, 35,223,255, 25,156,205, 81,150, 60,113, 54, 71,190,247,118,239,175, 55,131,138,253,139,  5,129,
-123,  1, 31,248,119, 22, 68, 45, 37, 54,155,224,192,252,229,156,205,124,143,222,117,112, 54,231,219,205,192,230,186, 71, 45,145,
-223, 93, 57,155,139,223,157,167, 57,238,147, 39,206,171, 13,175,151,112, 54,123,220,175, 54,223,255, 89,156,205,124,143,154,165,
- 44,185,113, 14,108,230,151,129,129, 46,191,223,109, 78,206,230, 42, 75, 30,194,121,213,247,201, 19,231,213,134,215, 75, 56,155,
- 61,238,205,241, 12,105, 41,222,107, 26, 45,213,124,214,220,156, 77,228,190,166, 56,155,216, 60, 51,164,  5,238,253, 95, 26,206,
-230,228,116, 15, 99,115, 54,247,180,100, 56,155,147,179,  9, 97,189,230, 56,255,105,247,253,239,152,158,222,248,174,166, 89,202,
-155, 59,218, 18,225,108, 78,206,  0,185,175,  9,206,171,184,247,215, 28,184,191, 75, 64,196,132,111,230, 55, 19, 52,179,  3,211,
-146,194,181, 57,195, 57,176, 37, 28,194, 22, 64,179,135,211,241,166, 60,185,  5,226,254, 79, 73, 83, 90,150,104, 89,250,219,149,
- 37,183, 60, 57,176, 25,157,162,102,117,158,221, 57,155,227, 26,174, 28,205,149, 71, 91, 58,238,205, 89,150, 90,226,222, 83, 92,
-133, 11, 65, 57, 41, 39,229,164,156,148,147,114, 82,206,235,150,243,154,  4, 75,147,128,130,130,130,130,130,130,130,130,130,130,
-130,130,130,130,130,130,226, 31,  5,175,237,187,113,113,113,171,149, 74,101, 59,111,255,235,116,186,139, 23, 47, 94, 28, 68,147,
-240,175,  3,189, 71, 20,255, 32,176,248,195, 65, 23,  0, 16,199, 70, 65, 65, 65,113, 77,195,107,103,120,185, 92,158,114,242,228,
-201, 14,130, 32,192,110,183,195,102,179, 57, 63,205,102, 51,250,247,239,223,228,142,244,209,209,209, 57, 18,137, 36,169, 41,231,
-216,237,246,243,101,101,101,125,125, 28,178, 19, 64, 10,195,252,161, 25,197,239,222, 62,  1,148, 88,173,214,238,190, 56, 25,134,
- 73,113,231,243,194, 37,126,247,201, 25, 18, 18,178,159,227,184,  4, 79, 92,222,190, 11,130,144, 95, 81, 81,209,231,207,188, 71,
-215, 51,162,163,163,115, 56,142,107,114,254, 44, 45, 45,245,154, 63, 99, 99, 99, 15,177, 44, 27,215,  4, 74,137, 32,  8,185, 23,
- 47, 94,236,235, 67,136,236,  4,144,226,243, 13,202, 45, 63, 49, 12, 83,108,183,219,123,250, 43, 71,190,184, 60,228, 81,127,156,
- 78,145,197,113, 92, 86, 84, 84,212, 51,122,189,222,  8,128, 72, 36, 18,226, 18, 54,  0,128,205,102,171,168,169,169,233, 66,115,
- 34,  5,  5,197,117, 33,180,  4, 65, 96, 77, 38, 19,242,242,242, 64,136,199,250,222,126,  5,215,235,112,224,183,141, 81,193, 81,
-209,176, 89, 44, 80,181,138,116,114,151,157, 56,  6,155,213,  2,155,217,140, 54,189,122,139, 97, 64,231,206,157, 37,126, 56, 19,
- 62,248,224,131,168,224,224, 96, 24,141, 70, 24,141, 70,152, 76, 38, 24,141, 70,152,205,102,152,205,102, 88, 44, 22, 88, 44, 22,
-216,108, 54,152, 76, 38,100,103,103,219,173, 86,171, 79,206,105,211,166, 69,105, 52, 26, 39,159,184,137,156, 34,175,213,106,133,
-209,104,196,166, 77,155,124,114,114, 28,151, 80, 82, 82, 18, 37,149, 74, 65,  8,129, 32,  8, 32,132, 52,218,220,209,182,109, 91,
-139,175, 64,182,208, 61,186,158,209, 97,218,210, 53, 81, 33, 10, 57,108,130,128,204,110,109,157,127,228,127,185, 28,196,102,135,
- 96,179,161,253,243,163,157,251, 59,117,234,228, 51,127, 18, 66, 18,167, 45, 93, 19, 26, 40,103, 85, 85,149,161, 99,199,142, 37,
-104,112,155,189,  9,173,  4,131,193, 16,229,224,191, 76, 16,177, 44,219,104, 91,191,126, 61, 50, 51, 51,253,197, 61,225,229,151,
- 95,142,178, 90,173, 48,155,205, 48,153, 76,176, 90,173,176,217,108,206,205,110,183, 59, 55,179,217,140, 61,123,246,  4,234,100,
-125,112,219,109,183, 61,190,102,205, 26,213,207, 63,255,172, 74, 74, 74,130, 84, 42,133, 68, 34,129, 68, 34,  1,203,178,224, 56,
- 14, 55,223,124, 51, 67,179, 32,  5,  5,197,117, 35,180, 76, 38, 83, 65,122,122, 58,113,124,143,151,203,229, 82,183,183,220,184,
-246,237,219,231,186,159,231,175,185, 42, 56, 42, 26, 19, 91,135,  3,  0,222, 57, 87,229,124, 64,124,216,231, 70,231, 49,239, 93,
-168,  5,  0, 40, 20, 10, 48,174,175,209, 94,160, 82,169,112,219,109,183, 65, 38,147,161,103,207,158,224,121,222,227, 38,149, 74,
-193,243,188,223, 68, 97, 24,  6,106,181, 26, 83,166, 76, 17, 69, 18, 84, 65,114,140,235,211, 19, 65, 32,248,239,177,211, 48, 11,
-  4, 28,199, 57,183, 64, 56,165, 82, 41,142, 30, 61, 10,142,227, 32,145, 72,156,159,226,247, 85,171, 86, 97,228,200,145,224, 56,
- 14, 10,133,  2,240, 51,115,176,235, 61, 50,155,205,177, 50,153,204,  2, 64, 20,103, 82,134, 97, 98,174,228, 30, 93,207,  8, 81,
-200, 49,102,222, 79,  0,128,162, 89,207, 59,239,221,158,103,223,113, 30,147,248,159,  7,192, 48, 12,120,158,  7,203,178,205,198,
- 89, 93, 93,109,120,232,161,135,182,  7,  7,  7,175,215,106,181,240, 35,224, 80, 84, 84,  4,142,227,188,230,119,150,101, 49,115,
-230, 76,156, 57,115, 38,160,184, 27,141, 70, 44, 88,176,  0,118,187,189, 17,175,248,221,125, 95,128, 34,235,253,161, 67,135,142,
- 94,179,102, 77, 24,195, 48,248,236,179,207, 32,149, 74, 49,124,248,112, 68, 68, 68, 96,195,134, 13,144, 74,165,120,253,245,215,
-105,230,163,160,160,240, 85,231,241,  0,110,  4, 16,233, 48, 17,234,  0,132,186, 28, 82,225,248,140, 20,127, 51, 12,179,207,  3,
- 79, 47,199, 49, 21, 12,195,236,115,249,109,  6, 32,243,176,191, 10,128,194,177,153,208,224,254,167,185, 92, 71, 60, 15,222,174,
-203,  1, 13,235, 15,  1,216,  2, 96, 96,102,102,230, 86,  0, 40, 45, 45,189,163,180,180, 20,  0,144,146,146,114, 50, 55, 55,183,
-163,168,121, 28,205, 83, 82,155,205,214, 65,108,170, 18,221,162, 33, 67,134,248,124,195,183, 89, 44,151,  9, 16, 79, 90,202, 83,
-115,133, 55,  1, 99,177, 88,240,192,  3, 15,  0,128,215,135,142,235, 22,128,118,131,217,108,  6,199,113, 72,109, 29,137, 73,195,
-210,113, 19,177, 66, 87,207,192, 86,171,195, 61,106, 43, 78,118,238,142,249,231, 43,112, 78, 91, 15,142,227,  2,226, 20,  4,193,
-171,200,146, 72, 36,152, 55,111, 30, 30,122,232, 33, 72, 36,146,128,248, 92,239, 81,114,114,242,154,220,220,220,  8,134, 97, 76,
-142,123, 36,183,217,108, 26,155,205, 22, 97,183,219, 35,154,114,143,174,103,216,  4,193, 99, 62,244,150,103,  3,185, 79,129,112,
- 86, 87, 87, 27, 50, 51, 51,119,203,229,242,133,209,209,209, 37,197,197,197,126,133,150,187,248,113,127,169,248,228,147, 79, 48,
-103,206, 28, 12, 26, 52, 40,160,112,154, 76, 38, 48, 12,131,249,243,231, 95,246,223,212,169, 83, 47,187,158, 31, 78,  6,  0, 27,
- 23, 23,247,236,186,117,235, 52,226,177,173, 90,181,  2,207,243,232,210,165, 11,130,131,131,177,125,251,118,216,237,246,128,203,
- 37,  5,  5,197,181, 11, 79, 90,196,  5,253, 39, 78,156,216, 51, 43, 43,107,122, 70, 70,198,119, 59,119,238, 92,202, 48,204,106,
-151, 58, 49,211, 81,191,174, 22,127, 19, 66,122,185,138, 30,135, 88,139,100, 24,102,181,120,188,235,111,241,147, 16, 50,  4,128,
- 76,252, 61,113,226,196,180,172,172,172,233, 19, 38, 76,120,115,198,140, 25,210,137, 19, 39,118,205,202,202,154, 46, 94,199, 83,
- 56, 60, 57, 90, 62,215,158, 18,155,168, 78,157, 58,229,173,137,202,245,  1,224,179,182, 84,181,138,116, 58, 89,239, 37, 70, 56,
-247, 79, 41,174,113, 62,192,230,246,104,  7,149, 74,133, 97,239,125, 20,144, 83,100, 54,155, 81, 94, 94,238,116, 25,252,109,129,
-114, 42, 21, 65,200,126,185, 11,138,170,100,120,119, 87, 53,214, 28, 62,  3,158,231,113,123,231, 46,184, 67, 26,140,183, 19,101,
-120,249,116, 33,172, 36,176, 62,189,132, 16,143,  2, 75,252, 46, 54,161,  4, 42,180,220,238, 81,145,209,104,172,202,203,203, 51,
-  8, 13, 15,118,  5, 33, 36,140, 97,152, 58,135,203, 21, 27,232, 61,186,158,145,217,173,173,211,117,218, 19, 60,216,185,127,164,
-238,168,243,158,140,159,247, 33,  0, 96, 80,247,155,253,150,135, 64, 56,171,170,170, 12,125,  7, 15,220,106, 55,152,191, 25, 61,
-122,116,193,230,205,155, 21,129,132,213,147,208, 18, 93, 91, 81,100,113, 28,  7,179,217, 28, 80,220,205,102,179,215,242, 33,149,
- 74,175,196,209,130, 78,167, 51,175, 92,185, 18,115,231,206, 69, 68, 68,  4,134, 14, 29,138,216,216, 88, 44, 95,190, 28,132, 16,
- 60,255,252,243, 80, 40, 20,162,123, 77, 51, 32,  5,197,245, 13, 95, 90, 68,158,149,149, 53,221, 93,200,184,254,118, 21, 80,110,
- 98,202, 85,172,165,249,121,254,175,118, 23, 79,226,117, 25,134, 89, 61, 99,198,140, 76, 63,225,168,240, 38,180,124, 78,137,111,
- 50,153, 10,186,117,235, 22,144,154,208,235,245,165,254,196,134,167,183,122, 87,151, 64,173, 86, 67,165, 81,131, 13,176,222,181,
- 90,173, 78,161,178,113,227, 70, 40, 20, 10, 12, 31, 62,252,170, 28, 45,139,197,  2,153,148,  7,219, 42, 26, 99,102,109, 70, 85,
-157,193,249,128,217,146, 95,128,131,101,229,120, 57, 99, 48, 84,138,114,212,155,205,  1, 57,111,130, 32, 92, 38,178, 56,142,195,
-  3, 15, 60,224,116, 19, 92,251,173,192, 71,211, 97, 68, 68,196,126,142,227, 18, 92,238, 81, 80, 74, 74, 10,240, 71,191, 30, 70,
- 16,132,250,208,208,208, 31,  1,196, 17, 66, 18,  0,  4,  7,114,143, 40, 60,231, 79,247,253,130,155, 83,117, 37,156, 85, 85, 85,
-134,204,204,204,221,118,131,249,155, 11, 23, 46,236,  6, 16,116,211, 77, 55, 53, 89,104,137,  2,139,231,121,204,156, 57, 19,115,
-230,204,113,254, 31,168,208,178,217,108,141,  4,212,233,211,167, 27, 93,203, 93,216,249,105, 54, 37,104, 24, 93, 40,164,164,164,
- 56,207,137,137,137, 65,104,104, 40,  4, 65,128, 32,  8,  8, 10, 10,130, 66,161,128, 84, 42,165,153,142,130,130,194,151, 22, 49,
- 76,152, 48,225, 77,134, 97, 86, 59,156,165, 99, 62,  4,149, 39,237,209,203, 77,172, 85,120, 57, 46,211,147,216,114,253, 46, 98,
-226,196,137,105,238,225,240,212, 92,233,172, 85,221,166,221,111,  4,215, 38,170,230,122,136,249,122,144,169, 67, 53, 80,168, 84,
-144, 72, 88, 48, 12, 67,252,113, 89, 44, 22,103,197,255,204, 51,207,248,236,183, 18,104,127, 42,139,197,  2,150,147,224, 98, 76,
- 50,236,236, 54,231,185,226,198,114, 60,206,197,116,132,228,212, 33,240,  1, 62,112,221, 29,173,231,159,127, 30, 11, 22, 44,  0,
-203,178,206, 52,225, 56, 14,237,219,183, 71, 65, 65,129, 79, 46,142,227, 18,206,157, 59, 23,229,154,142,162,136, 37,132,192,110,
-183,163,109,219,182,198,188,188,188, 23,105,209,189, 58,145,229,109,191,221, 46,  4,236,194,120, 58,174,170,170,202, 48,106,212,
-168,173,181,181,181,223,220,112,195, 13,167,209,120, 10,  4,191,124, 28,199, 53, 18, 88,162,200,250,244,211, 79, 27,137, 34,171,
-213, 26,208,139,128,213,106,189, 76,240,124,252,241,199,141, 62,  1,160, 79,159, 62,  1, 57,195,  0,  8,203,178, 68, 42,149,226,
-182,219,110, 67,215,174, 93,241,243,207, 63, 67, 16,  4, 60,247,220,115, 80, 40, 20,152, 61,123, 54,108, 54, 27, 62,248,224,  3,
-234,104, 81, 80, 80,248,210, 34,166, 25, 51,102, 28,155, 49, 99,134,211, 89,114,119,180,188, 60,119,239,116,136,170, 72, 81,164,
-  1, 48,121, 18, 68,158, 92, 50,119,  1,230,186, 47, 43, 43,107,186,123, 56,220,155, 43, 27,  9,173, 63, 11,165,199,143,226,163,
- 91,210,  1, 52,110, 46,156,119,115, 71,168,212, 42,168,130,213, 24,181,106, 27,  0, 56, 42,253,  9,  1, 57, 90,162,208,170,170,
-170,242, 41,178,154,226,104,177, 50, 14, 43, 18, 46,129,200,120,112,102,107, 35,161, 37,225,120, 20, 69, 36,131,229,165,224,236,
-182,128, 56,  9, 33,151, 53, 21,142, 29, 59, 22, 12,195, 56, 71,136,117,235,214,205,149,139,241,247,112,124, 45,188,161, 15,158,
-123,115,236,  7,149, 70, 90, 98,175, 36,127,238,255, 18, 39,127,120, 22,  0,208, 87,167,115,222,139,105,221,254, 24, 59, 48,235,
-232, 86,167,251,248, 30, 94,189, 34,206,170,170, 42,195, 77,157,210,118, 75,195, 67,190, 57,127,254,252,110,  0,236,131, 15, 62,
- 24,218,173, 91,183,128,202,164, 56,184,194, 93,100,185, 58, 89,226,167,159, 17,182, 46,194,209, 30,144,128, 18,155, 17,  3,200,
-243, 68,204,219, 26,141,  6,106,181,218, 57,226, 54, 40, 40,  8, 74,165,210,217,191, 51, 64,225, 70, 65, 65,113,253, 34, 76, 20,
- 58, 14,177,212,200,105,114,244,173,202,116,253,237,201,241,114, 56, 80, 57,126,234,215, 53, 14,129,230, 17,162,179,230,118,206,
-106,111, 34,141, 19, 21,164,235,103, 76, 76,204,175,106,181, 58, 57,208,216, 55,101, 20,155,221,106,185,204,217, 98, 24,  6,234,
- 96, 53, 20,106, 21, 20,193,106,175,174,151, 47,161, 37, 58, 69,226, 67,103,225,194,133, 80,171,213,248,215,191,254,213,228, 62,
- 90, 78,161, 37,101,177, 65,190,  9, 18, 25,215, 72,100,113, 28,  7,  9,207,163, 84, 29, 11,150,231,193,217,  2,115,201,106,107,
-107,193,113, 28, 38, 77,154,228,124,131,119, 21, 89, 77,137,179, 47,176, 12, 35,186, 91,242,118,237,218,189,202, 48, 76, 34,128,
- 36,157, 78, 39,191,120,241,226,173,180,188,250, 80,  6,118,235,101, 46,148, 55,247,245, 74, 57, 69, 39, 75, 26, 30,242, 77,199,
-142, 29,157, 78,150, 82,169, 20, 71,155,250,191,199, 44,235, 81,100,185,143, 16,228, 56,174, 33, 47,251, 25, 29,233,234,104,205,
-152, 49,195,201,235,234,100,137,104, 74, 57, 18,195,186,117,235, 86, 28, 60,120, 16,207, 60,243, 12, 20, 10,  5,230,204,153,  3,
-155,205,134,169, 83,167, 66,161, 80, 64, 38,147,209,204, 71, 65, 65,221,172, 70, 90,196, 13, 21,110,253,160, 24, 55, 81, 83,225,
- 73, 96,185, 54, 19,138,223, 25,134,177,122,224, 53,187, 53, 41,186,239, 23, 63,171,102,204,152,177, 89,116,178, 92,246, 55, 10,
-135, 95, 71, 75, 46,151, 39,231,229,229, 57, 39,194,244,245,105, 54,155, 49,104,208,160,128,157, 49,113,212, 33,199, 73, 26,  9,
- 11,101,176, 26, 74, 77, 48, 20,106,181,187,224, 96,252, 85,226,226, 27,177,171,208,154, 60,121, 50, 56,142,195,130,  5, 11,  0,
-  0,175,190,250,106,192,125,180, 68, 78,216, 25, 20,147,179, 72,159, 53, 18,230,111,173, 40,219,241, 59, 56,142, 67, 84,239, 59,
- 32,220, 52, 18,122,133, 26,156,221, 22,240,168,195,234,234,106, 20, 20, 20, 64, 34,145,224,149, 87, 94,105, 52,215,145,251, 72,
-182,141, 27, 55,250,141,187, 39, 39,107,242,249,106, 39,143, 66,161, 96,127,255,253,247,100, 65, 16, 82, 12,  6, 67,187, 62,125,
-250,  8,180, 40,251, 17, 69,130, 45, 32, 81, 21,104,254,116,231, 20,251,100,213,214,214,126,115,254,252,249, 61,  0,216,209,163,
- 71,135, 42,149, 74,124,245,213, 87,122,  0,178,229,203,151, 43,252,137, 34, 49,223,248, 19, 89, 60,207, 55,228,229, 64,226, 78,
- 26, 79, 89,226,175, 99,124, 32,121, 94, 12, 43,195, 48,176,219,237, 80, 40, 20,141,156,172,160,160, 32,200,229,114,154,241, 40,
- 40, 40,252,213, 37,251,  2,174,199,  9,233,229, 34,170,246, 93,  9,111, 83,174,231, 15,156, 55,161, 97, 50,153,112,226,196,137,
- 64,121,  2,158, 24,179,117,207,155,241,222,133, 90, 48, 12,131,255,246,185,  1, 42,141, 26, 74,149, 10,247,255,188,213, 89,113,
- 31,157,254, 42,228, 42, 53,226,250, 13, 13,168, 34, 23,155, 14, 93,133, 86, 77, 77, 13,120,158,199,251,239,191, 15,150,101,241,
-193,  7, 31, 32, 62, 62, 30, 23, 47, 94,196,242,229,203,  3,114,180, 36,118,  9, 98, 31,235,  4,229,216, 16,104, 30,235,143,176,
-219, 38,227,130,153,195, 78,163, 18,253,141,199, 33,219,240, 41,204,130, 61,224, 17, 88, 54,155, 13, 91,183,110,117,239,240,238,
-236, 83,101,179,217, 96,181, 90, 97,177, 88,240,193,  7, 31,  4, 50,194,243,178,251, 38,166,161, 99, 18, 84, 73,110,110,110, 36,
- 33, 36, 28, 64,  8,128, 74, 90, 92,125, 35,182,247,243,136,236,249, 52,  0, 96,213,140, 39,156,251, 39, 29,253, 35,127,206,252,
-182, 97,  1,128,142, 73, 67,155,196, 89, 85, 85,101,184,125, 80,159, 28,163,192,127,221,165, 75,151, 70, 78, 86, 80, 80, 16,227,
-248, 29,144, 93,198,178, 44, 36, 18,201,101,205,133,222,196, 86, 32,125,180,108, 54,155,115, 34, 81, 95,253, 25,175,196,209,122,
-226,137, 39, 16, 27, 27,235,116,178,222,123,239, 61, 40, 20, 10, 76,156, 56, 17, 86,171, 21,159,126,250, 41,205,124, 20, 20, 20,
-127,186, 40,251, 51,224,177, 38, 53, 26,141,133, 93,187,118,133,151,255,226,131,130,130,120,183, 72,197,181,111,223, 62,215, 67,
- 19,226, 16,  0,217,158, 42,117,134, 97, 16,172,  9, 70,144, 90,  5,165,155,139, 21, 20,172,129, 92,173,  6, 43,245, 88,153, 95,
-198, 41,246, 45,113, 21, 90,226, 86, 91, 91, 11,158,231, 49,119,238, 92,104, 52, 26,152, 76, 38,191,156,226, 67, 71, 34,145, 64,
- 95, 84,135,147,211,179, 33, 11,218,137,118, 67, 31, 66, 44,175,128,116,251,143, 48,216,173,254, 38, 44,189,140,179, 67,135, 14,
-120,231,157,119, 46,155,214,193, 27,226,227,227,253,198,221,221,201,154,121, 67, 27, 72,101, 82,140, 63, 94,  4,147,201,196, 60,
-244,208, 67,  2,  0,  3,128, 10,131,193,112, 62,144,244,108,  6,252,227, 57,125,141,138, 21, 33, 16,187, 39,  1,227,145, 83,116,
-178,140,  2,255,117, 65, 65,129,232,100,133, 40,149, 74,124,241,197, 23,122,  0,236,212,169, 83,149,137,137,137,146, 64,242,146,
- 68, 34,193,172, 89,179, 60,246,201,242, 36,186,154, 82,142, 92,207, 29, 48, 96,128,199,  9, 75,189,136,183,203, 56,197,176, 70,
- 68, 68, 56,157, 44,187,221,238, 28,109, 40,206, 62,239,227,165,130,230, 79,202, 73, 57,175, 31,206,107, 18, 30,107,224,139, 23,
- 47,222,238,237,132,182,109,219,230,229,229,229,181, 23,151,226,112, 84,156, 82,163,209,216,161, 79,159, 62,126,173, 29, 65, 16,
- 32,151,203, 65,  8,193,173,239,100,129, 97,  1, 22,141, 31, 98, 81,183, 12,134, 68,194, 65,104, 88,234,195,239,168, 67,131,193,
-208,232,225,224,105,171,175,175,135,201,100, 10,120, 54,111,163,209,216,104, 10,  6,134,  8, 56,247,219,178,203, 70, 31,138, 91,
-160,253,118,130,130,130, 26, 53,253,248,113,172,152, 64, 28, 45,215,166, 71,169, 76, 10, 78,202,139,142, 86,221,233,211,167, 71,
-209,108, 30, 56,196,  1, 11,  0,144,218,103, 56,  4,193, 14, 98,183, 55, 90, 38,169, 83,242,237, 16,136, 29, 22,171, 30, 38,147,
-201,223,180, 39, 76,101,101,165, 97,212,168, 81, 91,  1,252,239,158,123,238,201, 69,195,236,194, 68,173, 86,203,121,158, 23,  0,
- 84,  3, 32,151, 46, 93, 10,185,112,225,130, 96, 52, 26,219,248, 11,231,154, 53,107,112,226,196,  9,244,235,215,175,209,114, 80,
-162, 43,234, 58,187,123, 32,249, 83,108, 46,247, 52, 35,188, 55, 33, 23, 40, 36, 18,  9, 66, 66, 66, 32,149, 74,241,254,251,239,
- 67, 42,149, 66,169, 84,  2,  0, 62,253,244, 83,231,228,171, 20, 20, 20, 20,215,141,208,242, 87,111,250,104, 86,244,217,132,104,
-179,217,138, 19, 19, 19,155,116, 49,187,221, 94,230, 71,184, 21, 47, 95,190, 92,234,234, 66,248,251, 36,132,148,249,121,216, 22,
-175, 90,181, 74,234,201,221,240,182,192,180, 63, 78,187,221, 94,156,148,148,228,213, 49,241,  4,171,213,122,193,159,104,205,170,
- 48, 52, 18,  9,227,143, 23,121, 93, 59,145,194,111, 94,243,145, 63,223,186,210,252,121, 58, 53, 53,245, 66,104,104,232,218,232,
-232,232,170, 29, 59,118, 68,244,234,213, 43,194,245,152, 94,189,122,197,186,157,102,134,247,117, 14,193, 48, 76,241, 61,247,220,
-227, 49,207,139,162,201, 67,254, 44,246,151,231,247,238,221, 43,117, 61,223, 27,191, 75, 57, 42, 14, 64,184,158, 75, 79, 79,103,
- 93,121,188,229,125,171,213, 90, 65,115, 33,  5,  5,197,117, 47,180, 12,  6, 67, 81,215,174, 93,109, 94,254, 59,239,235,220,170,
-170,170,158,205, 29,  1,171,213,218,231,159,192, 89, 89, 89,217,172,113,183,217,108,197,142,  9, 74,125, 30, 67,179,248, 95,119,
-143,  0,160,188,188,252, 38,  0,208,233,116,240,183,172, 78, 19,  4, 97,179,231, 79,155,205,214,167, 37,210,180,186,186, 58,131,
-230, 44, 10, 10, 10, 42,180,154,  0,186, 24,241,223,  3, 45, 33, 90, 41, 40, 40, 40, 40, 40, 40,154, 23, 44, 77,  2, 10, 10, 10,
- 10, 10, 10, 10,138,150,  1,131,134,145,  3,158,208,148,209,  4, 67,174,224,218,217,148,147,114, 82, 78,202, 73, 57, 41, 39,229,
-188,238, 56,253,113,211,209,140, 45, 44,192, 40, 39,229,164,156,148,147,114, 82, 78,202,121,253,113, 94,147,160, 77,135, 20, 20,
- 20, 20, 20, 20, 20, 20, 45,  4,142, 38,193, 95,  6,  9,154, 48,163,190, 63, 16, 66,194,  0,120, 91, 48,206,204, 48,204,165, 43,
-224,100,  0, 72, 29,155, 56,209,145, 21,128,  5,128,133, 97, 24,226,159,227, 93,182,164, 36, 44,141,216,249, 94,132, 97,120, 65,
-192,225, 54,109, 90, 31, 98,152, 59,204,  0,160,138,238,212, 89,173, 82, 12, 49, 89,204,201,114, 94,118,162, 70, 87,191,209, 84,
-158, 87, 72,179,  7,  5,197, 95,130,187,  0, 76, 65, 67,183,146, 25,  0,150,209, 36,161,160,104, 33,161,165, 86,171,247,179, 44,
-155,224,111,126, 30, 17,142,181,204,138, 47, 93,186,212,179,  9,215, 30,165, 86,171,  7,241, 60,127, 11,  0, 88,173,214, 29,245,
-245,245,155,  1, 44,  7, 96,187,194, 56,105,  0, 60,  0,224, 17,199,239, 37,142,202, 66,123,133,124, 93, 67, 66, 66,126,224,121,
-158, 84, 86, 86,246,  6,128,136,136,136,221, 86,171,149,209,106,181,247,  3, 56,210, 68, 62,150,231,249,153,189,123,247,238,191,
-109,219,182,255,  1,152,219, 76,247, 82,206,178,172, 71,129, 34,  8, 66,210, 21,136, 44, 41,128,144,185,115,231, 70, 44, 94,188,
- 56,189,184,184,184, 11,  0, 36, 36, 36, 28, 29, 61,122,244,161,113,227,198, 85, 17, 66,106, 25,134,177,248,226, 41, 41,  9, 75,
- 43, 47,205,127,166,172,252,196,  3,  0, 16, 19,219,101,153, 68,194, 74,  9, 57,176, 75,217,234,145, 86,237,219, 37, 61,253,221,
- 87,115,165, 73,201,173,177,105,231,193, 27,199,189,248,102,218,  5,224, 19, 42,182,254, 60,  4,  7,  7,239,103, 89, 54,193, 87,
- 25,247, 84,230,237,118,123,113,117,117,117, 79,111,156, 28,199, 37,248,170, 47, 60,237, 19,  4, 33,191,178,178,210,227, 84, 19,
- 26,141,102, 23,199,113,201,129,114,137,159, 54,155,173,216,219, 40, 93,141, 70,179, 95, 34,145, 36,248,138,167,167,255,  4, 65,
-200,175,168,168,240, 22,206,203,226,222, 28,225,188, 18, 78, 95,225, 20,235, 35,  0,159, 70, 68, 68,220, 92, 85, 85,245, 40,128,
- 55,181, 90,109, 55,137, 68,130,240,240,240, 55,205,102,243,153,144,144,144, 47,107,107,107,119,  2,120, 17,  0, 93, 47,149,130,
-162,185,160,209,104,202,234,235,235,137,  8, 65, 16,136,213,106, 37, 38,147,137, 24, 12,  6,162,211,233, 72,125,125, 61,209,106,
-181,164,182,182,150, 84, 85, 85,145,200,200, 72,247,201, 27,189,181,225,118,209,104, 52,121, 89, 89, 89,166,130,130,  2, 98,177,
- 88,136,197, 98, 33,133,133,133,228,163,143, 62, 50,105, 52,154, 60,  0, 93,188,156, 59,196, 75,101,113, 27,128,165,233,233,233,
-230, 53,107,214, 16,163,209, 72,116, 58, 29, 89,182,108, 25,185,225,134, 27,204,  0,150, 58,142, 97,  3,228,  4,128,190, 49, 49,
- 49,197,103,207,158,181,111,220,184,209, 18, 18, 18,146, 29, 18, 18,146, 93, 88, 88,104, 63,123,246,172,208,170, 85,171, 98,  0,
-125,155, 16, 78,  0, 24, 57,126,252,248,178,194,194, 66, 50, 96,192,128,195, 46,251, 25,248, 95,231,110,136, 39, 39,139, 16, 18,
- 67,  8,137, 69,195, 36,151,151,109,132,144, 88,199, 49, 97,  1,114,170,242,243,243, 91, 71, 71, 71,103, 49, 12, 99,118,231, 99,
- 24,198, 28, 29, 29,157,149,159,159,223,154, 16,162,242,197, 89,124,126,222,147,107,215, 12,174,209, 93, 58, 69,116,151, 78,145,
-255,125, 61, 80,251,212,184, 71,151,198,182,237,190, 32, 52, 33,109,238,137, 83,167,231, 19, 66,230,111,222,151, 55,127,242,231,
-191,206,191,119,220,236, 47, 34, 18,211,159,106, 66,122, 94, 13, 40, 39,128,208,208,208, 82,157, 78, 71,  8, 33,196,110,183, 19,
-139,197, 66, 76, 38, 19,209,235,245,164,190,190,158,212,213,213, 57,203,121,109,109,173,243,123, 84, 84,148,215,242, 30, 22, 22,
- 86,102, 48, 24, 26,213, 29,102,179,217, 89,127,232,245,122,162,215,235,137, 78,167,115,110,245,245,245, 36, 46, 46,174,200, 71,
- 56, 47,138,225, 20,  4,129,216,108, 54, 98,177, 88,156,188, 70,163,177,209,102, 50,153,136,201,100, 34,137,137,137,  1,135, 51,
- 16, 78,163,209, 72, 18, 18, 18, 74,188,113,134,135,135,151, 25,141,198, 70,156,174,241,119,231, 21,127,199,196,196,148, 54,133,
- 51,144,112,250, 74, 79,  7,230,230,230,230, 18,131,193, 64,226,227,227,171,238,191,255,126,171,221,110, 39,107,214,172, 33,233,
-233,233,194,192,129,  3, 45,149,149,149,228, 95,255,250, 23,241,241, 82, 72,203, 17,229,164,184, 18, 71,139, 97, 24,168, 84, 42,
-124,255,253,247, 94,151,227,112,253,222,166, 77,155, 64,175,217, 51, 57, 57,121,235,246,237,219, 21,177,177,127, 76,136,109, 54,
-155, 17, 22, 22,134,231,158,123, 78,118,215, 93,119,181, 31, 58,116,232,238,115,231,206, 13,  0,176,223, 15,223,125,145,145,145,
-159, 77,154, 52, 41,250,193,  7, 31, 68, 68, 68,163, 73,183, 49,106,212, 40,220,127,255,253,210,220,220,220,135, 22, 46, 92,248,
-208,188,121,243, 74,235,235,235,199,  1,248,209, 23,169, 66,161,184, 39, 46, 46,238,139,237,219,183, 71, 69, 69, 69, 33, 37, 37,
-133,125,253,245,215,219,119,232,208, 65,145,144,144,192, 94,188,120, 17, 63,255,252,115,252,195, 15, 63,188,162,172,172,236,105,
-139,197,178, 50,128,184,203, 34, 34, 34,222,124,250,233,167, 91,105,181, 90,219,129,  3,  7,242,196,253, 50,153,108,106, 70, 70,
- 70,175, 45, 91,182,124, 11,224,203, 43,113,178,  8, 33, 90,252,209,196, 39,194, 42,254, 31,136,179, 69,  8,145, 29, 62,124, 56,
- 60, 35, 35,227, 71,147,201,212,253,153,103,158, 57, 63,125,250,116,133, 70,163,209,  0, 96,180, 90,237,165, 41, 83,166,152,103,
-207,158,253, 70,231,206,157,  7,239,218,181,235, 62, 66,136,213, 33,200, 46,231, 99, 24,103,120,138, 46, 84, 96,235, 78, 65,246,
-206,196, 87, 19, 62,156,150,124,110,223,241, 34,129, 83,104,240, 75,206, 49,148, 85,213,227,215, 93,199, 17, 19, 17,204, 72,229,
-124, 90, 72,252, 13,  3,106, 47, 28,207,129,143, 25,210, 41,154,  7, 12,195, 64,169, 84,226,151, 95,126,185,108,233, 42, 79,203,
- 90,113, 28,135,208,208, 80,191,171, 27,  4,  5,  5, 97,227,198,141, 30,215, 94,244,180,164, 79, 72, 72,  8,124,189,108, 48, 12,
-131,160,160, 32,236,216,177,  3, 44,203,122, 92, 26,200,125,159, 74,165,  2,235, 99,173, 43,145, 51, 39, 39,199, 47,151,248,169,
- 86,171,129,134,166,127,239,133, 82, 46,199,246,237,219,189,198,217,253,187,218,177,222,171, 63,206, 29, 59,118, 52, 90,250,203,
-125, 73, 48,215,223, 42,149, 10,140, 31,210,176,176,176,222,  9,  9,  9,216,187,119, 47,150, 47, 95, 30,158,150,150,134,211,167,
- 79,131, 97, 24, 76,159, 62,157,185,225,134, 27,248,210,210, 82,244,235,215, 15, 63,253,244, 83, 31,173, 86, 75, 11, 12,197, 95,
-  2, 66,  8, 15,224, 70,  0,145,104,232,118, 83,  7, 32, 20, 13, 43,105,200,  0, 84,  1, 80, 56, 54, 19,128,122,  0,173, 28,167,
- 87, 58,234, 22, 87,129, 80,225,186,248, 52, 33,164,151,131, 91, 92,161, 34,210,229, 88,241, 26,238,191,221, 63, 61,114,115,  0,
-176,122,245,106,241, 97, 54, 48, 51, 51,115,171,107,228,  2, 17, 89,226, 58,101, 30,202,180,251, 16, 77,185, 74,165,250, 97,247,
-238,221,138,200,200, 63,226, 96, 50,153, 80, 87, 87,135,250,250,122,212,213,213, 33, 56, 56, 24,203,151, 47, 87, 12, 30, 60,248,
-135,186,186,186, 14,142, 68,243,198, 57,235,226,197,139,209, 54,155, 13, 50,153,231, 46, 74, 44,203,162, 83,167, 78,120,243,205,
- 55, 49,108,216,176,152, 65,131,  6,205,114, 19, 90,151, 13, 37, 85, 42,149, 95, 28, 56,112, 32, 74,169, 84, 34, 47, 47, 15,197,
-197,197, 24, 63,126,124,107, 65, 16, 80, 84, 84,132,211,167, 79,227,194,133, 11, 88,184,112, 97,212,136, 17, 35,190,240, 32,180,
- 60, 13, 79,125,230,229,151, 95,238, 24, 22, 22,198,126,244,209, 71, 53, 58,157,238,255, 28,251,223,153, 51,103,206, 99,253,251,
-247,143,250,247,191,255, 77,118,236,216,177,216,113,227,188,166,167,107,159, 44, 71, 51, 31, 28,153,239,164,219, 57,157, 92,254,
-  7, 33, 36,  6,128,137, 97,152, 26, 15,156, 12,128,144,161, 67,135,190, 98, 50,153,186,111,223,190,253,204, 45,183,220,146,  8,
-224,162,152,249, 66, 66, 66, 84,179,102,205,138,206,204,204,204,189,245,214, 91,187, 15, 29, 58,244,149,138,138,138,233,132,144,
- 10,151, 62, 91, 78, 78, 65,192,225,152,216, 46,203,114,118,141,123, 96,203, 14,179,244,213, 23, 39,159,111,211, 58,169,246,112,
- 94,181,253,120,126,  5,234, 12, 54,220,123,107,195,  2,230,189,187,180,193,103,223,111,199,115, 47,189,197,255,184,108,209,253,
-103,  8, 84,245, 37,199,215,248, 72,207,171,  5,229,132,179,137,  9, 60,207,227,142, 59,238,  0,195, 48,151,173,229,201,243, 60,
-118,237,218,133, 91,111,189, 21, 60,207,227,137, 39,158,  8,136,147,227, 56, 12, 29, 58,212,185,142,162, 43,159,187,104,240,162,
-  9,178,221, 42, 91,112, 28,  7,150,101,189, 46,164,237,206,233,175, 94, 18,195,233,139,203,245, 63,127,225,116, 44,121, 20,176,
-200, 10,148, 83, 12, 39,199,113,232,211,167, 15, 14, 29, 58,228, 83,116,121,209,151,141,226,126,233,210,165, 49, 29, 58,116,200,
-153, 59,119,110, 56,  0, 84, 85, 85, 57, 23,188,151, 72, 36, 56,117,234, 20,204,102, 51,222,125,247, 93,139, 86,171,253, 55, 45,
- 71,148,179, 37, 57,125,105, 17,  0,253, 39, 78,156,216, 51, 43, 43,107,122, 70, 70,198,119, 59,119,238, 92,202, 48,204,106, 66,
- 72,166,248, 57,113,226,196,180,172,172,172,233, 19, 38, 76,120,115,198,140, 25,199, 24,134, 89, 13,  0,238,191, 29,117, 73,166,
-155,136,139, 20,121, 28,101,174,209,177,158,126,187,127,122,226,110,228,104,101,102,102, 50,142, 72, 50,174,149, 90,160, 66, 43,
-144,181,251, 56,142,123,126,250,244,233,209,190, 68, 86,125,125, 61, 74, 74, 74,144,152,152,136, 39,158,120, 34,122,238,220,185,
-207,219,108,182,143,125,208, 74, 37, 18,  9,246,238,221,139,242,242,114,116,237,218, 21,201,201,201,141, 14, 56,123,246, 44,214,
-174, 93,139,154,154, 26,244,232,209,  3,104,232,220,237, 17,221,186,117,123,183, 83,167, 78, 67, 89,150,181, 41, 20, 10, 28, 62,
-124, 24,221,187,119,199,247,223,127,143, 54,109,218, 64,169, 84, 34, 55, 55, 23, 93,187,118,197,214,173, 91, 17, 25, 25,137,244,
-244,116,155, 86,171,221, 86, 93, 93,189,249,220,185,115,239,122, 11,103,124,124,252,228,167,158,122, 74, 86, 82, 82, 34,124,243,
-205, 55,219,  1,108,  7,240,252, 91,111,189,245,248,176, 97,195,162, 14, 30, 60, 88,187,111,223,190, 61, 94, 68, 86, 32, 78,150,
-205,253,161,100,183,219, 77,  6,131,193,108, 50,153,172, 44,203, 22, 50, 12, 99,182,219,237, 29,188,153, 16, 99,199,142,109, 91,
- 89, 89,249,220, 75, 47,189, 84,224, 16, 89,167,208,208,  1, 30,  0, 96,179,217, 76,245,245,245,218,140,140,140,196,135, 31,126,
-248,204,210,165, 75,159, 27, 59,118,236,242,111,190,249,166, 30,128,193,157,176, 77,155,214,135, 36, 18, 86,170,171, 11,207, 95,
-177,252,203,151,215,174,122,190,117, 81,209,133,246, 17,173, 34,117, 82,117,100,201,242, 37, 95,239,  7, 96, 46,169,208,226,200,
-217, 82,240,188,  4, 39,138,106,209,255,246, 81,252,153,188,105,125,  1,172,161,239,114, 45,255,178, 40, 46, 66,189,101,203, 22,
-159,142,214,174, 93,187,192,243, 60, 20, 10,  5,102,207,158,237,147, 84, 20,  6,162, 91,228, 79,204,136,139,163,251,114,159,  4,
- 65,112, 46,244,238,190,253,223,255,253, 31, 94,122,233,165, 70,215,112,136, 13,198, 31,167,183,240, 37, 38, 37,161,188,172,172,
-209,190, 64, 22,165,183,219,237,224,121, 30, 11, 22, 44, 64,102,102, 38, 86,175, 94,237,243,243,142, 59,238,  0,203,178, 36,144,
-244,236,211,167, 15, 44, 22,139, 51,204,167, 78,157,242,200, 59,111,222, 60,127,193,188, 11,192,148,238,221,187,107,  6, 13, 26,
-132,156,156, 28,220,127,255,253, 38,139,197,146,  7,  0,119,222,121,103,234,220,185,115,101,  7, 14, 28, 64, 68, 68,  4,127,254,
-252,249,255,129,118,144,167,104, 97,120,210, 34,226, 51, 47, 43, 43,107,186,187,136,113,133,248, 63,195, 48,171,103,204,152,145,
-233, 42,138, 92,127,139,174,147,155,136, 75,115,117,164, 92, 69,148, 55,  1,229,246,188,117, 61,190,194,163,208,114, 68,108,160,
-171, 11, 36, 86,190,254, 68,150,143, 55,199, 70,  8,  9,  9, 25,126,239,189,247, 58, 69,142,209,104,116, 10, 44, 81,100,137,191,
-115,115,115,209,179,103, 79,105, 72, 72,200,240,170,170,170,143,  3, 16,113,136,139,139, 67,101,101, 37,142, 30, 61,138,196,196,
- 68, 88,173, 86,172, 95,191, 30,181,181,181,224,121, 30, 82,169, 20, 22,139,207,190,219,232,212,169,211, 29,139, 23, 47,238,185,
-104,209,162, 75,226, 27,221,146, 37, 75, 64,  8, 65,100,100, 36,244,122, 61,202,202,202,176,121,243,102,216,108, 54,168,213,106,
-164,164,164,200,238,185,231,158,190, 83,166, 76,225,125,  8,173, 62,247,223,127,127,136, 70,163,193,139, 47,190, 72, 44, 22,203,
- 12,199,190,201,227,198,141,139, 40, 44, 44, 52, 63,249,228,147,123, 45, 22,203, 71,162,153,232, 42,112,188,220, 88,175, 78,150,
-213,106, 21,211,180,160,190,190, 30,173, 90,181, 74,116,117,182,188,137,193, 29, 59,118,244,  1, 32,153, 58,117,106, 16,128, 50,
-215, 48,152,205,102,212,215,215, 67,167,211, 89,107,107,107,203, 95,123,237, 53,219,210,165, 75, 37,142,115, 78,120, 18, 90, 12,
-115,135, 89,163, 81,202,  8,145,188, 53,127,254,124,245,176, 97,195, 88,181, 90,141,186,186, 58,205,175,235,214,169,  7, 15,234,
-155, 50, 61,235,195, 13,154,132,174,101, 59, 14,231,227, 66,105, 45,204, 86, 43, 82, 98, 67, 26,252, 48,138, 22,135, 99, 32,139,
-211,209,114, 21, 21, 57, 57, 57,184,253,246,219,157,101, 93, 42,149, 54,114,190,252,113,114, 28,135,219,111,191,253, 50,135,103,
-203,150, 45, 30,221, 39,127,112, 21, 69,238,226,200,147,  0, 99, 89,214,239,  2,235,162,155,231, 73,108,185,186,250,110,226,205,
- 95, 51,  7, 56,142,195,184,113,227,192,243, 60, 94,127,253,117,112, 28,135,244,244,116,112, 28,135,140,140, 12,240, 60,143, 91,
-111,189,181,201,113,223,189,123, 55,186,119,239,238, 12, 83,122,122, 58,122,245,234,  5,142,227,208,175, 95, 63,240, 60,143,161,
- 67,135,  6,194,249,102, 93, 93, 93, 55,181, 90,141,220,220, 92, 72, 36, 18, 48, 12,115, 26, 64, 55,  0,136,141,141, 61,163,  6,
-111,130,189,  0,  0, 32,  0, 73, 68, 65, 84,215,235,219, 26,141, 70, 60,245,212, 83,140,217,108,238,250,250,235,175,191,101, 52,
- 26,169,208,162,104, 49,184,107, 17, 23, 24, 38, 76,152,240, 38,195, 48,171, 69,135,202,221,121,242,244,219, 67,221, 36, 58, 80,
-251, 28,101,181,151,155,136,171, 96, 24,102, 31, 33,228, 78,111,231,  2, 48,187,  9,171, 70, 77,135,174,205,134,126, 29, 45,177,
-242, 13, 84,104,249,131,209,104,188, 49, 42, 42,202,171,200,114,253, 52,155,205, 72, 78, 78,134,209,104,188,177,169, 15,141,216,
-216, 88, 88, 44, 22,124,249,229,151,144, 74,165,144, 74,255,208, 23,102,179,111,179,232,248,241,227,  5,187,119,239,238,222,163,
- 71,143,176,159,126,250,169, 98,192,128,  1,145,195,134, 13,131, 66,161,128,193, 96,128,213,106, 69,239,222,189,209,169, 83, 39,
- 20, 23, 23,227,215, 95,127,173,236,208,161, 67,171, 61,123,246,  8,165,165,165,231,124, 80,223, 54,120,240, 96, 48, 12,131,117,
-235,214, 85,  2,216, 39,151,203,215, 78,155, 54, 45,204,108, 54, 11,163, 71,143, 62, 95, 93, 93,253, 18,  0,139, 76, 38,155, 51,
- 96,192,128,140,236,236,236,111,  5, 65,152,221,212,140,234,158,182, 58,157, 14, 65, 65, 65,129, 76, 37,193, 87, 87, 87,119,  1,
-  0,149, 74, 21, 14,224,140, 51,135, 27, 12,141,196,176,217,108, 54,134,135,135,171,  0,192,113, 14,239,133, 51,210,102,195,138,
-115,231,242,131, 93,251,207,133,134,134,226,145,135, 31,102,111,233,211, 71,214,237,198, 27,135,190,253,201,162,239,227, 34, 52,
-230,148,184,  8, 88,237, 86,100,111, 88, 47, 16,193,186,129, 86, 59,127,142,208, 18,197,134,187,163,197,243, 60,182,110,221,122,
-217, 62,169, 84,138,255,254,247,191,  1,  9,  3, 81, 84,121,107, 58,115,107,234, 98,252,  9, 24,158,231, 33,145, 72,176, 96,193,
-  2,  8,130,128,151, 95,126,185, 81,115,162, 43,127, 64,118,158,139,  8,236, 52, 89,  0, 96, 70,241, 76,185,243,124,247,240, 58,
-206,  9,200, 37,155, 59,119,110, 64,142,214,157,119,222,233, 87,184,186,182, 48,184,134,235,208,161, 67, 30,121,231,207,159,239,
- 55, 61,237,118, 59,214,172, 89,227, 20,169, 34,222,126,251,237,167,100, 50, 89,244,182,109,219, 80, 90, 90, 10,157, 78,135,250,
-250,122,244,238,221, 59,133,101,217,195,165,165,165,133, 39, 78,156,184,151,150, 30,138, 63,209,209, 50,205,152, 49,227,216,140,
- 25, 51, 60, 58, 86,238,206,146, 47,231, 73, 20, 88, 14, 65, 20, 41,138, 55, 52,116,171,217,231,239, 92,  0, 50,247,166, 67,159,
- 70,144,155,138,156,226,169,242, 13,164,249, 48, 64, 59,157, 99, 24,  6, 70,163,209,163,192,114, 21,  7, 22,139,  5,213,213,213,
-176,219,237, 87, 60,215,151,167, 55, 89,127, 66,235,232,209,163,255,122,252,241,199, 75, 66, 66, 66,186, 85, 84, 84,148, 11,130,
-112,235,174, 93,187, 34, 57,142,131, 70,163,129, 70,163,193,218,181,107,161, 84, 42, 49,110,220,184,114,187,221,158, 19, 28, 28,
- 28, 97, 48, 24,126, 47, 45, 45,125,219,171,130,225,249,161,253,250,245,195,129,  3,  7,112,233,210,165,141,  0,210, 31,125,244,
-209,219, 91,183,110,205, 76,155, 54,205,120,246,236,217,217,  0,202, 85, 42,213,226,197,139, 23, 15,234,209,163, 71,240,232,209,
-163,177,117,235,214,249,  0,140,129,198, 89,167,211, 53, 18, 88, 90,173, 22,117,117,117, 80,169, 84,182,  0,211,140,199, 31, 35,
- 12, 65,  8,113,222, 27,135,155, 37,222, 31,194,113,156, 56,170,209,155,200,130, 74,165,154,186,104,209, 34,133,251, 32,  5,187,
-221,142,178,178, 50,104, 52, 26, 76,122,251,109,233,123,227,255,221, 93,162,142,222,197,178, 12,204, 22, 82, 67,  4,243,122, 93,
-217,131,219,128,119,105,205,243, 39, 64, 20,  6,119,223,125,247,101,205,133, 82,169, 20, 27, 55,110,196,136, 17, 35,156, 47, 46,
- 61,122,244,240,251,114, 37, 10,131,187,238,186,203,233, 12,173, 95,191,222, 99,179,159,232, 72,  5, 34,  8,197, 99, 95,120,225,
-  5,112, 28,135,207, 62,251, 12,175,188,242, 10, 88,150,197,204,153, 51,193,178, 44,222,121,231,157,128, 69,166,171,128, 41,252,
-176,225, 51,225, 21, 45,170,230, 69,  3,  0,130, 53, 26, 49, 66, 77,170,123, 56,142,115, 58, 89, 55,222,120, 35,120,158, 71, 70,
- 70,  6, 56,142,115, 58, 89,195,135, 15,119, 77, 71, 18,  8, 39,199,113,200,203,203,115,134, 57, 35, 35,163,145,147,197,113, 28,
-238,188,243,206, 64,130, 57, 61, 52, 52,116, 74,167, 78,157, 58,207,154, 53,139,151, 72, 36, 24, 60,120,112,106, 76, 76,204, 57,
-155,205, 22, 49,117,234, 84,165,135,115, 20,  0,186,117,238,220, 89, 69, 75, 13, 69, 11, 58, 90, 83, 60,252, 21,230,218,231,170,
-  9, 47,146,171, 93,143, 23, 57,220,197,145,195, 33,203,241,199,229,233, 92,127,224, 68,  5,233,203, 82, 15, 68,104, 57,108,103,
-159, 23, 83, 42,149, 71,202,203,203, 51, 20, 10, 69, 35,145,229, 73,112, 73, 36, 18,148,150,150, 66,169, 84, 30, 49,153, 76,205,
-118, 19,253, 53, 29,  2, 48,158, 62,125,122,188,203,239, 33,195,135, 15,255,102,227,198,141,177,217,217,217,216,179,103, 15, 34,
- 35, 35, 49,119,238,220,139,101,101,101,255,  2,176,177,178,178,210,239,117,219,182,109,219, 69,173, 86, 99,199,142, 29,  0,176,
- 21,192,191,159,123,238, 57,198,106,181, 98,222,188,121, 58,  0,235, 66, 67, 67,215, 44, 95,190,188,123,183,110,221,100,217,217,
-217,218, 61,123,246,252, 22,160,200,178, 11,130,112,153,192,114, 77,211,224,224,224, 64, 28, 45,107, 72, 72,200, 81,173, 86, 59,
-202, 96, 48,104,229,114,121,176, 86,171, 53,185, 10, 44,145,159,227, 56, 62, 47, 47,175,  4, 64, 74, 72, 72,200, 81,120,105,230,
-228, 56,110,240,224,193,131, 57,247,123, 80, 86, 86,134,210,210, 82, 88, 44, 22,244,232,209,131,145, 48, 86,201,165,162, 35,110,
-211, 58, 80,145,245, 39, 57, 90, 68, 44,235,226, 40, 65, 79, 35, 13,215,175, 95,239,252,205,178, 44,190,254,250,235,128, 68,209,
-198,141, 27,125,118, 88,119,107, 58,244,107,141,139,199,127,254,249,231, 32,132, 56,157, 44,150,101, 49, 97,194,  4,200,229,114,
- 76,155, 54, 13, 19, 38, 76,  0,199,113,126,155, 14, 93,  5, 76,210,235,122,215,151,163,134, 66,225,232, 15,197, 48,140,171,216,
- 98,  2, 21,111,190,220,188, 64, 90,  2, 92, 57,197,243,130,130,130,188,118,132,119,227,244,117,129, 95,  0,228,199,198,198,238,
-200,200,200,  8,217,191,127, 63,102,206,156, 41, 53,153, 76,109,178,179,179,157,215,245,148, 94, 58,157, 78, 65, 75, 14, 69, 75,
-184, 89, 62,254,174,112,235, 95,197,184, 54,227,249,248,116, 63, 30, 46,251, 92,121, 43, 24,134,177,122,184, 94,133,  7,113,229,
-126, 13,215, 99, 42,188, 58, 90,254, 42, 11,127,130, 43, 16, 71, 75,175,215,255,182,110,221,186, 94, 15, 63,252, 48,231,171,217,
- 80,167,211, 33, 58, 58, 26,199,142, 29,179,233,245,250,223,  2,112,202,154, 83,104,185, 35,187,188,188, 92, 98,181, 90,209,190,
-125,123,196,199,199,195,104, 52,162,166,166, 70,  2, 96, 99,128, 28, 82,149, 74, 37,  1,128,154,154, 26,160, 97,168,105,106,135,
- 14, 29,112,224,192,  1, 84, 87, 87,255,  8, 96,216,148, 41, 83,122,244,238,221, 91,250,253,247,223,235,159,121,230,153, 31,173,
- 86,107, 64, 74, 67, 16,  4,179,205,102, 75,102, 89,214, 82, 83, 83,115,193, 53, 61,163,163,163,195, 85, 42, 21, 83, 86, 86,102,
- 13, 68,104,117,235,214,109,239,249,243,231, 49,117,234,212,138,233,211,167,119,168,171,171,187, 84, 91, 91,107,115, 21, 91, 70,
-163,145,109,213,170,149,124,222,188,121, 10,  0,232,214,173,219, 94,111, 66, 75,167,211,181, 86, 42,255,120, 49, 54,153, 76, 40,
- 45, 45, 69,105,105, 41,202,202,202, 80, 87, 87,135,148,148, 20,232,245,250, 68, 90,205,252,101, 66,171, 81,243,153,107,249,118,
-125,144, 55,165,172,187, 10,152,187,239,190,219,217,183, 75,116,200,196,109,197,138, 21,238, 29,204,  3, 18, 90,159,127,254, 57,
- 94,120,225,  5,  4,  5,  5, 97,214,172, 89,141,154, 14,221,197,129, 32,  8, 76, 32,113, 79,126,195,128,210, 57,225,224,121, 30,
- 17,207,148, 53,106,162,243, 32, 56,  2, 10,231,244,233,211,155,165,233,208,149, 51, 49,177,161,168, 44, 88,176,  0,163, 70,141,
-194,182,109,219,174,184,233, 48, 45, 45,109,201,234,213,171, 67,142, 31, 63, 14,173, 86,139,138,138, 10,152, 76, 38, 20, 23, 23,
-123,109, 21,112,212,229, 65,180,228, 80,252,201,245,212,190, 63,147,183, 57,175,199,249,121,128,  7, 44,180,  2,113,180, 76, 38,
-211,172, 23, 95,124,241,185, 33, 67,134,132,  7,  7,  7,163,164,164,228, 50,145, 85, 95, 95, 15,181, 90, 13,131,193,128, 85,171,
- 86,105, 77, 38,211, 44,127,226,192,106,181, 34, 42, 42, 10,149,149,149, 16,188,244,159,102, 89, 22, 10,133,  2,245,245,245,128,
-159, 78,230,158, 30, 24, 22,139,  5, 86,171, 21, 86,171, 21, 22,139,197,239, 91,178,187,153,167, 82,169, 68,225,  1,  0,186,184,
-184,184,246, 65, 65, 65, 40, 40, 40,  0, 26, 70,246, 13,185,253,246,219,249,170,170, 42,242,228,147, 79,110, 39,132, 60,  5,223,
-179,227,155,115,114,114,146,  1, 64,161, 80,228,  2, 64,113,113,177,181,166,166,166,145, 83,168, 84, 42,201,136, 17, 35, 98,  9,
- 33,200,201,201, 73,150, 74,165,  4,222, 71, 53, 26, 87,174, 92,121, 60, 36, 36,100,105, 86, 86,214,195,153,153,153,199,186,116,
-233,146,172,211,233,202, 13,  6,131,193,104, 52, 18,137, 68, 34, 13, 11, 11, 11,218,176, 97,195,153, 93,187,118, 13,209,104, 52,
- 75, 87,174, 92,121,220,155,243,166, 82,169,138,245,122,125,146,120, 79, 93, 69, 86,105,105, 41,  8, 33,200,207,207,135, 82,169,
- 60,239,175, 89,151,162,229, 32,190, 84,185, 59, 47,238,251,  2, 21, 89,174,194, 96,195,134, 13, 62,231,208, 10,148,211, 85, 20,
-189,242,202, 43,152, 51,103,206,101,142,214,180,105,211,  0,  0,111,191,253,118,192,125,180, 68,247,170,116, 78, 56, 98, 94,168,
-110, 20,118,  0, 96,196,240, 53,173,204,131,227, 56, 76,157, 58,245,178, 78,234,174, 77,123,  1, 54,241, 53, 10,103,121,121, 57,
- 56,142, 67,120,120, 56, 30,121,228, 17, 12, 29, 58,212,217,  4,217, 84,222,147, 39, 79,238,120,227,141, 55,186,166,165,165,225,
-253,247,223,175, 14, 13, 13, 13,254,207,127,254,195,213,212,212, 48,190, 28, 45, 42,180, 40, 40,154, 65,104,137,  5, 44,208, 81,
-135, 94, 42,203, 33,104, 60,215, 70,173, 94,175,127,228,182,219,110,251,105,217,178,101,138,182,109,219,226,228,201,147,168,174,
-174,134,217,108,134, 84, 42, 69,108,108, 44,106,106,106,240,245,215, 95, 27,244,122,253, 35,  0,106,253,112,190,213,179,103,207,
- 47, 62,254,248,227,160,244,244,116, 84, 87, 87,163,190,190,222, 41,132, 24,134,129, 70,163,129, 66,161,192,222,189,123,177,126,
-253,122,  3,128,183,252,112,122, 82,115,176, 88, 44, 78,193, 21,128,208,114,229, 84,137,174,142, 94,175,  7,  0,107,235,214,173,
- 99,  0, 32, 63, 63, 31,  0, 10, 83, 82, 82,166,180,109,219,150, 89,188,120, 49, 33,132,172,247, 34,178,156,156, 12,195, 84, 19,
- 66, 46,  1,136, 49,155,205, 82,  0,168,173,173,181,180,106,213, 42, 74, 46,151, 11, 10,133, 66,  8, 10, 10, 18, 74, 74, 74,108,
- 54,155, 77, 10,  0,253,250,245, 51,  3, 40,117, 91,163,208,149, 83, 32,132,104,231,207,159, 63,101,244,232,209, 25,125,250,244,
- 73,123,246,217,103,143, 62,249,228,147,108,124,124,124, 88, 93, 93,157,241,244,233,211,151, 62,249,228,147,186,221,187,119, 15,
-225,121,254,220,252,249,243,167,  0,208, 50, 12, 35,120,226,180,217,108,191,101,103,103,255, 43, 51, 51,147,187,112,225,  2,202,
-202,202,156, 34,171,172,172, 12,157, 58,117,194,174, 93,187,236, 22,139, 37,187,  9,233,217, 92,160,156, 13, 47, 33, 68, 44,235,
-222,  4,150,248, 50, 21, 40,167,171, 40, 26, 53,106, 84, 35, 23, 75, 42,149,226,135, 31,126,240, 88,111,120, 40, 87,141,226,238,
- 58,199,215, 27,111,188,209, 72,180, 77,154, 52,201,107,117,230, 47, 61, 69,158,218,  5,241,141, 71, 29,122, 41,231,190,194, 41,
-214,157, 60,207, 99,210,164, 73,  1, 59, 90,184,188,143,214,101,156, 98,220,  7, 12, 24,  0,189, 94,239, 20,178,222, 28, 45,127,
-233,105,183,219, 95,152, 51,103, 14,209,104, 52, 55,107,181,218, 71,207,159, 63,191, 80,175,215,223, 84, 91, 91,235,211,209, 50,
-153, 76,114, 90,142, 40, 39, 90,102,126,174,235, 71,104, 57, 30,146,104,221,186,117,163,181,179, 88,150,109,180, 53,165,159,129,
-  3, 27,242,242,242,238,187,229,150, 91,190,125,225,133, 23,130,211,211,211,249,164,164, 36,232,116, 58, 20, 20, 20,224,216,177,
- 99,182,149, 43, 87,106,245,122,253,163,  0,  2, 25,117,182,232,248,241,227,235,135, 13, 27,246, 78,239,222,189,159,158, 60,121,
-178, 36, 53, 53, 21,181,181,181,  8, 11, 11, 67, 84, 84, 20, 78,157, 58,133, 85,171, 86,217, 43, 43, 43,191,  0,240, 30, 60,180,
-161,250,123,225,183, 88, 44,120,232,161,135, 32,  8,  2,102,207,158,141, 64, 22, 84,118,129,197, 98,177, 16,  0,140,163, 63,151,
-222, 49,187, 52, 78,159, 62, 13,  0,231,146,147,147,131,  1, 32, 59, 59,155, 65,195,252, 90,129,188,225, 19, 66,136,211,217,234,
-212,169, 83,129,123,229, 40, 58, 89,162, 11,230, 47,220, 12,195, 24,  9, 33,229,122,189,126,216, 43,175,188,242,206,231,159,127,
-254,240,231,159,127,126,217,113, 26,141,102,233,204,153, 51,223,123,224,129,  7,202, 25,134,241,218,143, 76,167,211,189, 61,102,
-204,152,  7,142, 28, 57, 18, 28, 20, 20,  4,157, 78,135,170,170, 42, 88, 44, 22,164,164,164,160,188,188, 28,139, 22, 45,170, 51,
- 24, 12,239,210,226,248,215,192, 85, 24,120,115,181,  2, 16, 89, 94, 93,157, 95,126,249,197,227, 28, 85, 77,229,116, 23, 27,129,
-206,109,229,235,165, 72,156,150,198,211,148, 17, 77,172,215, 46,227,229, 56, 14, 31,125,244,145,115,210, 86, 79, 78, 86, 83, 28,
- 45,145, 51, 60, 60,188,193, 38, 87, 42, 33,  8,  2,238,188,243,206,171,225, 21,  0,140,115,153,241,125,250,107,175,189, 54,165,
- 83,167, 78,169,  0,228,174,105,208, 68, 23,159,130,130,194,159,208,178,219,237,197, 29, 59,118,108, 84,193,249, 91,204,212,106,
-181, 22,  7,120,221,245, 58,157, 46,101,230,204,153, 47,170, 84,170, 33,122,189,190,171,163,226, 56,162,211,233,178, 77, 38,211,
-167,104,218, 34,208, 21,  0,158,223,189,123,247,236, 97,195,134, 77,187,245,214, 91, 71,142, 31, 63,158, 33,132, 96,222,188,121,
-228,236,217,179, 43, 28, 46,214,217, 43, 73,164,240,240,240,227, 95,127,253,117,244, 79, 63,253,  4,171,213,138, 79, 63,253, 20,
-193,193,193,199,171,171,171,  3,165, 40,223,180,105,211, 55,125,250,244,121,108,215,174, 93,139,  0,252,190,117,235,214,133,125,
-251,246, 29,179,107,215,174, 37,  0,142,109,222,188,121, 97,239,222,189,199,236,219,183,111, 57,128, 67, 77,168,124,157,206,150,
-205,230,185,165,209,139,147,229,139, 83, 75,  8,177, 60,254,248,227,227, 31,120,224,129, 47,247,237,219,119, 83, 77, 77, 77, 87,
-  0,  8, 13, 13, 61,210,171, 87,175,189,203,150, 45, 59,229,112,178,252,117,214,175,208,233,116, 35,186,118,237,250,227,251,239,
-191,175, 74, 75, 75,227,218,183,111,143,194,194, 66, 28, 61,122,212,246,191,255,253,175,222, 96, 48,220, 13,224, 18, 45,142,127,
-157,208, 34,132, 32, 52, 52,180,209, 75,148, 56,228,191,169,205,133,174, 15,102,113,169, 30,119, 94,111,156,190,166, 77, 16,161,
- 86,171,157,147,155,  6,210,101, 65, 16,124,207,199, 70,  8,113,114,138, 91,  0, 34,203,239,  8, 65,199, 18, 56,  1,115,  6, 50,
-189,131, 74,165,130,213,106,117,242,  6, 48,242,179,169,106,241, 23,  0,191, 88,173,214,211,  0,218, 81,113, 69, 65,209,130, 66,
-235,210,165, 75, 61, 91,248,218, 90,147,201,244,158,201,100,122, 79,220, 97, 52, 26,175,150,243, 44,128,  7, 54,109,218,244,241,
-166, 77,155,196,118,132,169,240,191, 94,162, 79,156, 60,121, 50,147,231,249,255, 46, 93,186,180, 55, 33,  4, 33, 33, 33,187, 11,
- 11, 11,255,211, 20, 14,187,221,254,248,174, 93,187,158,131,163, 47,147,197, 98,121,124,199,142, 29, 47,162, 97, 61, 38,216,237,
-246,199,247,236,217,227,252,221,196,  7, 37, 33,132,152,  8, 33,113, 94, 14, 49, 53,209,129, 19,157, 45,243,178,101,203,234,  1,
- 28,198, 31,243,100, 89, 29,155,209,173,185,208, 23, 54,235,116,186,246,147, 38, 77,154, 46,145, 72,  6,235,116,186,120,149, 74,
- 85,100,179,217,126,211,235,245,111,161, 97,141, 42,138,191,  8,102,179,249, 66,199,142, 29, 57, 79, 47, 80,190, 30,228,190, 94,
-172,236,118,123,113,135, 14, 29,252,190,156,121,224,188,224, 67, 52,156, 75, 73, 73, 97,  3,229, 18, 97,177, 88,202,125,133, 51,
- 37, 37,  5, 77,229,244, 23,247,228,228,100,143,113,247, 35,  8,189,198,221,102,179, 93, 17,167,175,244,244,  5,131,193,112, 41,
- 50, 50,178,222,104, 52,242, 38,147,137,183,217,108,141,236, 71,133, 66, 81, 97, 48, 24,104,225,161,160,184, 26,161,245, 15,199,
-126, 52, 44, 47,209, 92, 48, 29, 57,114,228, 49,167, 61, 85, 94,126,165, 60,238, 74,178,222,207,239,166,  8,163,102,119,132, 28,
- 66, 74,223, 76,116,149,245,245,245, 79,138, 63,196, 62, 32, 20,127, 61,170,170,170,110,110,110,206,234,234,234,102,127, 81,171,
-172,172,204,104,129,184,247,188, 94, 57,125,161,164,164,228,102, 63, 66,140, 22, 28, 10,138,  0,193,210, 36,160,160,160,160,160,
-160,160,160,104, 25, 48,104, 24, 57,224,  9, 77, 25, 77, 48,228, 10,174,157, 77, 57, 41, 39,229,164,156,148,147,114, 82,206,235,
-142,211, 31, 55, 29,205,216,194,  2,140,114, 82, 78,202, 73, 57, 41, 39,229,164,156,215, 31,231, 53,  9,218,116, 72, 65, 65, 65,
- 65, 65, 65, 65, 65,133, 22,  5,  5,  5,  5,  5,  5,  5,  5, 21, 90, 20, 20, 20, 20,174, 72,109,221,186,245,137,212,212,212, 11,
-  0,198,182,240,181, 30,233,221,187,119,149, 92, 46,223,  0, 32,149, 38, 61,  5,  5,  5, 21, 90, 20, 20, 20,215,180,200,234,218,
-181,235,246,147, 39, 79,118,202,206,206,142,139,143,143,255,176, 37, 47,214,179,103,207, 15,182,109,219, 22,190,110,221,186,219,
- 98, 98, 98,114,174, 80,108,165,182,105,211,230, 68,106,106,106, 49,128, 71,154, 57,136, 99, 51, 50, 50,170,101, 50,217,122, 42,
-  4, 41,174,  3,116,  1,208,149, 10, 45, 10, 10, 10,138, 22, 20, 89, 59,119,238,140, 48, 26,141, 56,121,242, 36, 42, 42, 42, 14,
-181,228,  5,115,115,115, 47,237,220,185, 19,  9,  9,  9, 88,178,100, 73,100,114,114,242,182, 38, 10,154,212,174, 93,187,110, 63,
-113,226, 68,167,236,236,236,248,168,168,168, 79,154, 51,124, 55,221,116,211,180,109,219,182,133,109,216,176, 97,104,100,100,228,
-149, 10, 65, 10,138,191, 51,228,  0, 30, 99, 24,102,111,151, 46, 93,142,164,165,165,253,206, 48,204, 46,  0,163,112,237,206,221,
- 25, 24, 86,175, 94,189,117,245,234,213, 91,105, 30,161,160,160,104,  6,164,165,165,165,233,116, 58, 29,169,168,168, 32,159,125,
-246, 25,  9, 15, 15,183,  0,248, 13,192, 74, 15,219,155,  0, 52,  1,114,107, 28,199,123,226,249, 45, 60, 60,220,242,217,103,159,
-145,252,252,124,114,252,248,113,146,154,154,106,  8, 80,208,164,118,237,218,181, 82, 12,243,218,181,107,  9,199,113,235,155, 51,
- 81, 52, 26,205,177,156,156, 28,114,246,236, 89,178, 97,195,  6, 18, 29, 29, 93, 78,197, 22,197, 53,130, 36,  0, 31,168,213,234,
-234,187,238,186,139,124,245,213, 87,100,213,170, 85,228,199, 31,127, 36,179,102,205, 34,131,  6, 13, 34, 50,153,236,  2,128,215,
-  1,132, 94, 79, 90,132,113, 68,140,  0, 24,  8,  0,153,153,153, 84,108, 81, 80, 80, 92, 45,118,234,245,250, 12,189, 94,143,186,
-186, 58,180,110,221, 26, 60,207,123, 60,176,188,188, 28, 59,118,236,192,184,113,227,142,151,150,150,246,135,239,117, 47,195,186,
-119,239,190,115,243,230,205,169,193,193,193,206,157,130, 32,192, 98,177,192,106,181,194, 98,177,192,100, 50,193,100, 50, 65, 38,
-147, 65,161, 80, 32, 60, 60,252, 40,124, 55, 97, 56,221, 55,131,193,128,131,  7, 15, 98,244,232,209, 21, 85, 85, 85,253,  1,228,
- 54, 99,186,164, 70, 69, 69,229, 44, 90,180, 40, 50, 37, 37,  5,231,207,159,199, 19, 79, 60, 81,121,238,220,185,126,205,124, 29,
- 10,138, 63, 19, 19,238,187,239,190,105,209,209,209,108,151, 46, 93, 16, 27, 27, 11,147,201,  4,131,193,  0, 66,  8, 56,142,  3,
- 33,  4,181,181,181,200,201,201,193,230,205,155, 77,151, 46, 93,250, 26,192,167,  0,242, 92, 68,214, 53,169, 69,156, 66, 43, 51,
- 51,147,161,121,133,130,130,162,153,112,164,182,182,182,139,201,100,130, 78,167, 11,232,132,252,252,124,140, 29, 59,246,120,105,
-105,233, 45,240,188,168,188,166,123,247,238,123,114,114,114, 82,141, 70, 35,180, 90,255,235,206,203,100, 50,  4,  5,  5, 33, 34,
- 34, 98, 23,128, 62,222,222,196,187,116,233,178,127,215,174, 93,225,  6,131,  1,135, 14, 29,194, 35,143, 60, 98,169,174,174,222,
- 14,192, 91,224,171,209,176,142,234, 57, 15,255, 37,  2,120,209,241,134,239,  9,170,200,200,200,190,139, 23, 47,150,182,109,219,
- 22,122,189, 30,163, 70,141,170,206,205,205,237,  5,160,128,102, 29,138,127, 32,114, 79,158, 60,217,193,110,183,163,178,178, 18,
- 38,147,  9,122,189,222, 41,180, 36, 18,  9,  8, 33,176,217,108,206, 23,163,  3,  7, 14, 32, 59, 59,155,228,231,231, 79,118,148,
-165,107, 86,139, 80,161, 69, 65, 65,209, 18, 72,237,208,161,195,161, 95,127,253, 53, 72, 42,149, 98,213,170, 85,152, 60,121,178,
-181,186,186,122,155,187,120,137,142,142, 78, 91,184,112, 97,114, 74, 74, 10,126,255,253,119,220,127,255,253,111,  1,152,238,129,
-243, 77,173, 86, 59,205, 98,177,224,208,161, 67, 24, 51,102, 76, 65, 89, 89,217, 49,119, 17,147,156,156,220,239,147, 79, 62,225,
-123,244,232,  1,173, 86,139,145, 35, 71,234, 79,157, 58,213, 27,192, 49, 47, 97,253,164,186,186,250, 21,187,221,142,186,186, 58,
- 36, 36, 36, 64, 42,149,250,140,156,193, 96, 64, 82, 82,210,174,138,138,138,203,196, 91, 68, 68,196,166,243,231,207, 15, 82, 40,
- 20, 62, 57, 44, 22, 11,138,139,139, 33,147,201, 96, 50,153,208,174, 93,187,175,  1, 60, 78,179, 14,197, 63, 81,104, 29, 62,124,
-184,195,119,223,125,135,238,221,187,163,115,231,206,168,175,175,119,138, 46,179,217, 12,171,213,122,217, 73, 90,173, 22, 47,191,
-252,114, 30, 28,205,231,215,170, 22, 17, 59,166, 77, 17,219, 68, 51, 51, 51,  7,208, 60, 67, 65, 65,113,181, 21,111, 94, 94, 94,
-250,144, 33, 67,182,173, 88,177,162,213,240,225,195,209,174, 93, 59,254,222,123,239,141,212,235,245,131, 93, 15, 44, 43, 43, 11,
- 27, 51,102,204,254,162,162,162,100,199,174, 94, 94, 56,123,  5,  7,  7, 35, 63, 63, 95, 20, 89, 61,225,214,204, 40,147,201,214,
- 31, 62,124,152,151,201,100,216,183,111, 31,198,142, 29, 91, 89, 80, 80,224,175, 89, 46,212,108, 54, 67, 34,145,  0,  0,138,139,
-139,253, 70,238,252,249,243, 16,  4,193,228,233, 63,150,101,229,  7, 14, 28, 64, 92, 92,156, 79, 14,150,101,221,  5, 93, 13,205,
- 54, 20,255, 80, 88,205,102, 51,122,246,236,137,130,130,  2, 28, 56,112,192, 41,184, 42, 43, 43, 81, 82, 82,210,232,224,189,123,
-247,226,224,193,131,232,223,191,191, 59,207, 53,169, 69,156,202,113,245,234,213,  3, 28,145,219, 74,243, 12,  5,  5, 69, 51, 33,
- 53, 46, 46, 46,103,209,162, 69,145,177,177,177, 24, 52,104, 80, 81,105,105,105, 27, 15,199,173, 36,132,220,157,159,159,143,182,
-109,219,174,  2,112,207,149, 28,147,152,152, 88,177,111,223,190, 86,199,143, 31,199, 35,143, 60, 82,225,232,243,229,175,239, 83,
-114,167, 78,157,246,109,216,176, 33,156,101, 89, 28, 59,118, 44,144,166,195, 66, 52,244, 47, 57,231,225,191, 68,  0,147,  0,132,
-123, 57, 87,213,161, 67,135,190,251,247,239,151, 50, 12,131,194,194, 66,177,233,176,167,131,151,130,226,159,134, 17,113,113,113,
-255,123,238,185,231, 66,122,247,238,141,226,226, 98, 92,184,112,  1,151, 46, 93, 66,122,122, 58,210,210,210,112,246,236, 89,172,
- 95,191, 30,  7, 15, 30,132, 92, 46, 71, 66, 66,  2,212, 75,191,195,127, 25, 28,  7,144, 70,181,  8,  5,  5,  5,197, 85,136, 45,
-169, 84,186, 62, 62, 62,190, 28,158,231,165, 10, 27, 57,114,100,137,221,110, 39,103,207,158, 37,104, 24, 61,  8, 47, 66,139,156,
- 61,123,150, 68, 71, 71,231,  3,  8,243,112,204,216,152,152,152, 34,165, 82,121, 20, 77,156,214,161,125,251,246, 21,167, 78,157,
- 34, 69, 69, 69,100,221,186,117, 36, 34, 34,162, 37, 70,  4,166,118,236,216,177,178,174,174,142, 24,141, 70,146,147,147, 67, 18,
- 19, 19, 43, 64, 71, 30, 82,252,243, 17, 12, 96,106, 74, 74,138,241,227,143, 63, 38,235,215,175, 39, 11, 22, 44, 32,211,166, 77,
- 35,227,199,143, 39, 25, 25, 25, 36, 35, 35,131,140, 26, 53,138,188,242,202, 43,228,246,219,111, 39,106,181,186, 22,192,189, 52,
-233, 40, 40, 40, 40,154, 23,137,  0,102, 57,  4,213,202,145, 35, 71,150,152, 76, 38,114,225,194,  5,242,195, 15, 63, 16, 52, 76,
-221,224,  9,111,150,150,150,146,210,210, 82,113,106,132,124,252, 49,173,195, 87, 14,222,171, 18, 65, 73, 73, 73, 21,251,247,239,
- 39,133,133,133,100,237,218,181,196, 33,216,154, 13, 10,133, 98,131, 86,171, 37, 70,163,145,108,218,180,137, 78,239, 64,113, 45,
- 34, 10,192,220, 27,110,184,193, 58,123,246,108,178,114,229, 74,242,217,103,159,145, 17, 35, 70,144,215, 95,127,157, 60,248,224,
-131, 36, 50, 50,210,  4, 32, 11, 64,  8, 77,174,171,  7, 93,217,156,114, 82, 78,202,233,142,245,199,143, 31, 39, 34,236,118, 59,
-185,112,225,  2,217,176, 97,  3,137,137,137, 57,134,198,243,105,185,114,106, 58,119,238,124,242,212,169, 83,228,252,249,243,196,
- 98,177, 56, 57, 78,158, 60, 73,  0,108,109,134,112,166,198,199,199,151,111,217,178,133,156, 58,117,138,196,196,196, 20, 53,103,
-220,147,146,146,202, 43, 42, 42,200,166, 77,155, 72,100,100,164, 63,145, 69,243, 18,229,252, 39,115, 38,  1, 88,220,163, 71, 15,
-251,156, 57,115,200,211, 79, 63, 77, 18, 19, 19,237,142,151,162,248,235, 73,  8, 93,223,179,180, 82, 80, 80,252, 21,144,239,222,
-189, 27,114,185,220,185,227,247,223,127,119,157, 71,203,219,188, 13,218, 19, 39, 78,220, 50,124,248,240,109,115,230,204,233,236,
- 58,138,105,203,150, 45,  0, 96,106,134,176,229, 94,184,112,161,255,176, 97,195, 62,141,136,136,184,177,180,180,244,157,230,140,
-120, 97, 97,225, 43, 93,187,118,157, 94, 87, 87,167,213,235,245,163, 64,231,206,162,184,118, 81,  8, 96,244,129,  3,  7, 62, 60,
-112,224,192, 91,  0,  8,128,247,  1,156,184,222, 18,130, 10, 45, 10, 10,138, 63, 27, 99,159,124,242, 73,247,206,226,251,  0,252,
-159, 15,145, 37,226, 82, 65, 65, 65,159, 59,239,188,243, 57, 52, 30,157, 40,118, 78,111, 14,228,154,205,230,161,238, 35,165,154,
-  9, 75, 74, 75, 75,151,208, 44, 64,113, 29,225, 24,128,  7,175,231,  4,160, 66,139,130,130,226,207,198, 57,  0, 79, 92,197,249,
- 90,120,158,103,139,130,130,130,226,111,  7,186,168, 52,  5,  5,  5,  5,  5,  5,  5,  5, 21, 90, 20, 20, 20, 20, 20, 20, 20, 20,
-255, 44, 48,240, 62,114, 32,187,  9, 60, 87, 50,162, 33,155,114, 82, 78,202, 73, 57, 41, 39,229,164,156,215, 29,167, 63,238,108,
- 80,180,168,  0,163,156,148,147,114, 82, 78,202,249,207,230,100, 28, 27,235,216,196,223,127,231,184, 51,127,227,184, 95, 47,156,
-215, 36,254,170,206,240,226,141, 16,208, 48,228,147,226,239,  7,215,  2, 66,232,125,162,160,160,104, 98,221, 33,113,121,216,218,
- 29, 27,254,134,117,137,171, 40, 16,174,242,185,212, 18,113,191,158, 57,175,121,161,117,163, 74,165,154, 44,147,201, 82, 24,134,
-177,235,116,186, 35, 38,147,105, 62,128, 93, 87,121,205,175,162,163,163,199, 86, 85, 85,  9, 44,203,130,101, 89, 48, 12,  3,150,
-101,193,243,188,161,182,182, 86,115, 37,164,145, 93, 70,188,202, 49,204, 11,118, 98,159, 95,126,116,213, 52,127,251, 41,124, 23,
- 24,169, 84,122, 95,120,120,120,104, 69, 69,  5, 97,217,134,174,124, 18,137, 68, 92,  8,215, 86, 91, 91,251, 77,160,100, 97, 97,
- 97,123,195,195,195, 67,197,243, 25,134, 65, 85, 85, 85, 77,121,121,249, 77,  0, 16, 20, 20,180, 67,165, 82, 69,112, 28,  7,137,
- 68,  2,137, 68,  2,189, 94, 95, 85, 85, 85,117, 11,189, 21,255, 76, 44, 95,190, 92, 50, 44,254,137,118, 28, 49,116, 99, 89, 18,
- 34,  8, 76,173,141, 81,252,190,254,194, 87,103,  2, 57,127,212,168, 81,118,154,138,127, 30,100, 50,217,236,232,232,232,127,215,
-215,215,235, 25,134, 33, 12,195,128, 97, 26,222,179,220, 63,237,118,123,113, 85, 85, 85, 79, 63, 15, 91, 94, 38,147,205,140,137,
-137, 25,163,215,235,245, 14, 62,143,188,  0, 96,181, 90,139, 43, 43, 43,123,  6, 84,215, 71, 70,206, 87, 40, 20,143,234,245,122,
- 29,195, 48,130,235,127,132, 16,215,135,249,217,202,202,202,126,254,132,129, 76, 38,251, 52, 58, 58,250, 95,142,184, 59,195,121,
-181,113,143,142,142, 30,163,211,233,  2,226,244, 17,247,203, 56, 91, 34,156,127, 83,206,107, 95,104,165,167,167,127,183,103,207,
-158, 14, 60,207,  3,  0,140, 70, 99,215,185,115,231, 62,246,198, 27,111,100,  1,152,120,133,215, 91,216,175, 95,191,135,114,114,
-114,216,149, 43, 87,178,189,122,245,  2,195, 48,176,219,237,176,219,237,232,210,165,139,226, 74, 35, 18,162, 82, 78, 56,184,241,
-191, 65, 55, 14,121,242,133,114, 96,154,191,253,190,  4, 38,128,183,  1,164, 52, 49,  8, 21,142,116, 57,232, 69,108,236,100, 89,
-182, 73,156,130, 32,228, 95,186,116,169,143, 15,  1,211,236,156, 14,145,117,127,191,126,253, 66,178,179,179,153,162,162, 34, 70,
-161, 80, 64, 16,  4,216,237,118, 88,173, 86,220,112,195, 13, 77,114, 66, 67, 67, 67, 53, 19, 38, 76,104,119,199, 29,119,224,135,
- 31,126,192, 99,143, 61,134,190,125,251,230,149,151,151,  3,  0, 84, 42, 85,196,241,227,199, 59,132,135,135, 67,175,215,163,182,
-182, 22,183,221,118, 27,170,170,170,254,209,133,235,230,244,132,247, 25,150,113,206, 21, 69,108,246,234, 61,191,151,188,125,181,
-188,225,225,225,  7,229,114,121,180, 95,181,236,242, 32, 51, 26,141,101,213,213,213,221,253,156,146,  4,224, 46,137, 68,210,158,
-227,184,142,  0,146,108, 54, 91, 52,  0, 72,165,210, 50,137, 68, 82,104,181, 90, 79,153,205,230,211,  0,126,129,143,  5,144,135,
-197, 63,209,142,177,233, 71,214,153,132,225,202,182, 89,169,250,179, 19,114,149,114,253,218, 97,241, 79,172,  8, 84,108,253,133,
- 72,  5,176, 12, 13, 11, 74, 63,141,134,121,128,174,  6,241,  0,238, 70,195,154,143,201, 22,139,165, 18,192,  1, 52,244, 67,201,
-  3,144, 24, 25, 25,185, 68, 16,  4, 83, 85, 85,213, 19,240,176, 80,117,239, 30,173,247,179, 44,155, 32,122,  2,  2,177, 23,239,
- 62, 80,220, 44, 15, 40,150,101, 63,205,204,204,252,215,138, 21, 43,148,  7, 14, 28, 80,118,238,220,217,249, 66, 36,  8,  2, 26,
-107, 23, 32, 57, 57,217,159,171,193,177, 44, 59,123,228,200,145, 15, 47, 94,188, 88,121,238,220, 57,101, 92, 92,156,147,211, 85,
-108,137,136,139,139, 11, 52,239,127, 53,116,232,208,209,139, 22, 45,226, 87,173, 90,165,104,213,170, 21, 34, 34, 34, 32,149, 74,
- 47, 59,246,150, 91,110, 17,252, 71,157,253,244,158,123,238, 25,253,253,247,223, 43,247,236,217,163,236,210,165, 11, 36, 18,201,
- 85,199,125,196,136, 17, 15,127,247,221,119,202, 35, 71,142, 40,219,183,111, 15,209, 84,112,231, 99, 89, 22,173, 91,183, 14,136,
-243,238,187,239,126,120,217,178,101,202,131,  7, 15, 42, 59,118,236,232, 76, 79, 66,200, 21,135,243,111,206,121, 93, 56, 90, 50,
-139,197,130,173, 91,183,130,101, 89,132,135,135, 99,236,216,177,216,184,113,227,132, 77,155, 54,173,190,  2,103,235, 43,135,200,
-226,  1,224,199, 71, 71, 32,159,  7,198,149,155, 33,149, 74,113,246,236, 89, 72, 36,146, 38, 91,139,114,185,124, 12, 33,100,146,
-254,194, 62,185,193, 96,133,177,100,191, 82,161, 80, 56, 31,  0,250, 18,199,254,139,251,149, 10,133,226,172, 68, 34,153, 90, 95,
- 95,191,208, 27, 95,251,246,237,191, 61,118,236, 88, 39, 79,  5,215, 23,244,122, 61,218,180,105,147, 88, 93, 93,221,222,211,255,
- 60,207, 39,156, 59,119, 46, 74, 38,147,129, 16,226, 44,196,238,159,226,119,139,197,130, 27,110,184,193,226,235,154,190, 56,109,
- 54, 27,130,130,130, 32,186, 81,102,179, 25,245,245,245,254, 56, 25,169, 84,122,159, 40,178,  0, 96,233,210,165,136,137,137, 65,
- 84, 84, 20, 84, 42, 21, 20, 10,133,147, 51, 80, 72, 36, 18, 12, 27, 54, 12,239,190,251, 46,178,178,178,240,218,107,175, 53,170,
-104,121,158, 71,120,120, 56,214,173, 91,  7,141, 70,131,196,196, 68,136,  2,255, 31,109, 11,178, 76,248,174,253,231,157, 14,237,
-237,183,118,226,110,238,206,125,238,120, 84,130,101,  1, 65,104,120,116, 50, 12,136,205, 42, 92,218,127,164,228,157,  0,210, 51,
-174,176,176, 48, 42,208, 52,178,217,108,136,139,139,147,248, 57,108,120, 90, 90,218,143,207, 62,251,172,180,125,251,246,140, 84,
- 42,  5,199,113,224, 56, 78, 20,232,137,132,144, 68, 65, 16,  6,150,149,149,145,185,115,231,126,184,101,203,150,123,  1,172,245,
- 88,177, 16, 67,183, 58,147, 48,124,219, 33,220, 52,114,200, 27, 88,183,124,194, 77,253,210,  5,  4, 43, 13,103,  0,252,157,133,
- 86,106, 90, 90,218,161, 61,123,246,  4, 89, 44, 22,244,238,221,123,119,110,110,110, 15, 92,217, 12,238, 97,  0, 62,153, 56,113,
-226,232,103,159,125, 86, 18, 26, 26, 10,153, 76,134,186,186, 58,156, 57,115,102,204, 55,223,124, 67,190,248,226,139,255,  3, 16,
- 92, 88, 88,152,177,119,239, 94, 12, 26, 52,232, 69,  0, 47, 95,174,  8, 36,  9, 59,246, 22, 68,137,191,239, 30,214, 85,154,209,
-147, 45,107,112,113,220,143, 38, 16,236, 66,241,222,195, 23,  2, 17, 98, 31,142, 24, 49,226,145, 21, 43, 86,168,  1, 96,222,188,
-121,184,239,190,251, 16, 30, 30, 14,165, 82,  9,169, 84, 10,158,231, 27,125,250,121,216, 74,  0,124,248,224,131, 15,142, 92,188,
-120,113, 48,  0, 44, 94,188, 24, 35, 70,140, 64, 68, 68,  4,130,131,131, 33,147,201, 32,145, 72,154,156,152,225,225,225, 95,245,
-189,233,166,199, 23, 45, 90,  4,  0,120,235,165,151,112,199,205, 55, 67,173, 84, 64,169,144, 65, 76, 11,153,132,199,237,227, 94,
-240,171, 47,  1,124,124,223,125,247, 61,240,253,247,223,  7,  3,192,129,  3,  7, 80, 94, 94,142,232,232,104, 40, 20, 10,200,100,
- 50,103,156, 25,134,129, 66,161,  8, 40,238,247,221,119,223,200,239,190,251, 46, 24,  0, 22, 46, 92,136, 97,195,134, 57,227, 46,
-151,203, 33,149, 74, 27,109,238,162,211, 19,231,189,247,222, 59,114,217,178,101,193,  0,240,205, 55,223, 96,200,144, 33,  8, 11,
- 11,115,166,167,200,213,148,123,244, 55,231,188, 62,132,214,161, 67,135,238, 87,169, 84, 51,  0, 68,202,100,178,208,135, 31,126,
-184,245,227,143, 63,142,  7, 31,124, 16,155, 54,109,122,170,137, 66,139,137,142,142, 30,155,147,147,227,124, 66,155,201,101,130,
-169,201, 15,112,  7, 38,237,127,234,169,152,172, 51,245,216,189,247, 20,130,192, 50,123, 63,254, 56,210,120,250, 52,236,102, 51,
-222, 59, 91,215,176,223, 70,152,173,175,140,139,185,113,246,255, 77,  2,176,208,135, 11, 32, 55,153, 76,200,203,203,107, 82, 32,
-138,138,138, 32,  8,130,201,151,187, 32,149, 74,113,244,232,209,203, 84,189, 39, 36, 38, 38,250, 42,128,126, 57,215,175, 95,143,
-241,227,199,227,212,169, 83, 16,151, 42,  9,128,147,  9, 15, 15, 15, 21, 69,150, 40,130, 20, 10,  5,120,158,103, 56,142, 99,196,
-166, 61, 71,225, 10, 72, 24,179, 44,139,111,191,253, 22, 31,124,240,  1, 94,127,253,117,204,159, 63, 31,221,186,117,251, 35, 19,
-114, 28,180, 90, 45,194,194,194, 16, 22, 22,214, 72, 32,254,147,225,126,155,103,206,154,163,132, 64, 26, 58,129, 16,  1, 16,  0,
-  2,  2,129,  8, 40,187,112,  6,147,223,253, 40,224,167, 15,207,243, 56,125,250,180, 51, 31,136,206,176, 40,140, 92, 93,131,164,
-164, 36,191,121, 73, 42,149, 78,249,249,231,159,101,223,126,251, 45,190,255,254,123, 48, 12,  3,185, 92, 14,149, 74,133,208,208,
- 80, 68, 68, 68, 56,183,132,132,  4,230,127, 61,184,254,121,  0,  0, 32,  0, 73, 68, 65, 84,255,251,159,180, 91,183,110, 83,180,
- 90,237, 90,207,247,156,132, 40,219,102,165,142, 28,242,  6,  0, 96,228, 27,  4,151,242,166,221,200,214,188,243,119, 94, 68, 54,
-181,107,215,174,219,119,238,220, 25,164,215,235, 33,  8,  2,214,174, 93,171, 28, 50,100,200,182,130,130,130,126, 77, 21, 91, 73,
- 73, 73,171,118,238,220,121, 75,100,100, 36,106,107,107,161,213,106, 97,181, 90, 33,145, 72,144,152,152,136, 15, 63,252,144,185,
-231,158,123,158, 31, 51,102,140, 81,161, 80,136,206, 70,146,231,188,212, 56, 51,205,253,236,243, 80, 66, 26,242, 15, 17, 72,163,
-207,234,242, 66,188,244,202,228,128,194,216,186,117,235,167,127,248,225,  7,181,171,179,228, 42,  2, 92, 69,150,184,249, 17,  6,
-108,155, 54,109, 30, 95,178,100,137,147,179, 85,171, 86,224, 56, 14, 60,207,131,227, 56,176, 44,139,109,219,182, 97,198,148,137,
-  8,139,140,195,156,207,230,249, 13,103,100,100,228,252, 97,195,134, 61,186,112,225, 31, 85,119,215,182,109,113,231, 45, 55, 35,
-170,149,  6,173,194,130, 27,210, 73, 96,240,251,169,  2,191,207, 35,  0,108,235,214,173,159, 88,190,124,185,218,245,133, 80,140,
-171,248,242, 44,186,248,102,179, 25, 61,123,246, 12, 40,238,174,156,162,219, 38,138, 54, 49, 61,197,235,136,229,213, 79, 56, 31,
- 23,133,176, 67,112, 54,226,224,121, 30,203,215, 45,242,234,102, 95, 41,103, 83,239,187, 59,103, 97, 97, 33,166, 79,159, 14,241,
-165,205,181,171, 80,124,124, 60,230,204,153,227,183, 94,114, 43,  3,189,  0, 68,186,236, 50,  3,144,185,124, 86, 48, 12,179,207,
-195,113,226,126,222,209, 98, 21,137,134,126, 99,117,  0, 66, 61,240,121,227,169,116, 60,243, 34,221,142,111,116, 29,175, 66,107,
-245,234,213, 98, 41, 30,152,153,153,185,213,241,189, 70, 46,151, 23, 41,149,202, 24,  0,117,107,215,174,197,127,254,243, 31, 56,
-172,213,187, 67, 66, 66,142,121,112,117, 14,153, 76,166, 55,  0,148, 57,118,137, 67, 52,217,234,234,106, 97,227,198,141,236,226,
-123,135,194, 76,128,244, 73, 51, 48, 44, 51, 19,235,227,101,144,  0,184,233,100, 37,148, 74, 37,167,213,106,173,174,253,182, 60,
-244,221,202,118,203, 80,146, 32,142, 67,239,237,107, 48,126,251, 26,220,164,146,161,106,197, 50,212,237,200,  1,203, 50,232,175,
-106,133,215, 30,217,136, 62, 26, 57,100, 38, 29, 88,150,245,148,179,157,156,121,121,121,163, 52, 26,205, 12,183,  4, 14,  4,249,
-104, 88,199,  9, 94,194,  9, 66,  8,186,117,235,  6,134, 97,156,110,129,184,137,133, 78,220, 14, 30,244,216,  2,233,149,211,209,
-  4,  7,149, 74,133,223,126,251,205,121,204,224,193,131, 97, 52, 26, 17, 30, 30, 30, 16,103, 69, 69,  5, 41, 41, 41, 97, 22, 47,
- 94, 12,158,231, 17, 17, 17,  1,165, 82,201, 44, 90,180,104,162, 84, 42, 77, 48, 26,141,130,217,108,134, 76, 38,155, 35,222, 31,
-142,227,116, 90,173, 54,194, 27,167, 68, 34,193,179,207, 62,139, 87, 95,125, 21,243,231,207,199, 83, 79, 61,117,153,227,101, 52,
- 26,209,170, 85, 43,167,216,242, 80,  0, 91, 98,184,111,203,114, 10,  4,199, 14,174,199,241, 35,217, 16,236,  2,236,  2,  1, 33,
-118,  8, 54,224,192,198,221, 29, 46,230,151,196, 19,144,134,174,183,  0,228,181,245,182,  1, 17,178,142,  0, 86,110,173, 50,207,
-246, 23, 78,142,227, 96, 52, 26,241,243,207, 63,227,228,201,147, 88,187,118, 45, 12,  6,  3, 90,181,106,133,208,208, 80,220,124,
-243,205, 24, 51,102, 12,146,146,146,252,198,157, 16,178,176,168,168, 40,189,111,223,190, 76, 77, 77, 13,106,106,106, 96, 48, 24,
- 96,183,219, 97,179,217,192,113, 28,130,130,130,160, 80, 40, 16, 29, 29, 13,163,209, 72, 76, 38,211, 66,111,156,130,192,212,234,
-207, 78,200, 93,183,124,194, 77, 35,223, 32, 88,241,  1,131,118,109,228,250,223,246,  7, 63,190,114,251,107,183,  1, 32,  2,113,
- 90, 11,196,106, 23, 42, 95,157,248,201,243,127,250, 61,186, 92,100, 69, 24, 12,  6,212,213,213, 53,216,250, 50, 25, 86,172, 88,
-209,234,174,187,238,202, 41, 41, 41,233,239, 67,108, 93,198, 25, 28, 28,156, 40,145, 72,112,244,232, 81,124,241,197, 23,248,237,
-183,223, 80, 86, 86,118, 41, 46, 46, 46,100,224,192,129,236, 75, 47,189,132,244,244,116,124,253,245,215, 65,254, 56,  9, 33, 40,
-204,219,134,194,211,219, 33,  8, 13,174,117,195,230,249, 59,  9, 48,238, 58,157,206,120,232,208, 33,245,151, 95,126,137,168,168,
- 40, 36, 39, 39, 67,169, 84, 34, 40, 40,168,209, 67,214,245,193,235,175,108, 26, 12,  6, 99, 97, 97,161,250,187,239,190, 67, 68,
- 68,  4,146,146,146,160, 84, 42, 33,147,201,192,113, 28, 24,134,193,226,197,139,177,244,221, 71, 80,120,234,  8, 70,220,121,155,
-223,112, 42,149,202, 71, 23, 46, 92,216,200,  2,137, 14, 11,  3,199,179,144,240, 12,194,  6,223, 11,  0,184,180,233, 39, 95,179,
- 67,186,114, 50,117,117,117,198, 61,123,246,168,247,239,223, 15, 65, 16,144,148,148,  4,189, 94, 15,141, 70,227,140,255,198,141,
- 27,113,207, 61,247,224,219,111,191, 69, 70, 70,134,223,184,215,215,215, 27,143, 28, 57,162, 94,178,100,  9,194,195,195,209,186,
-117,107,103,220,197,141,231,121, 72, 36, 18,164,164,164,160,182,182, 22,106,181,218,239, 61, 58,112,224,128,122,201,146, 37,  8,
- 11, 11, 67, 66, 66,130,211,113, 19,197,209,  7,159,191,219,136, 32,136,137,189,106,206,166,222,119,119,206, 17, 35, 70,160, 93,
-187,118,208,104, 52, 80,169, 84, 78,110, 95,156, 94,180,136, 83,111, 51, 12,179,218,165, 76,100, 50, 12,179,218,245,211,219,113,
-142,175,253, 39, 78,156,216, 51, 43, 43,107,122, 70, 70,198,119, 59,119,238, 92,234,141,207, 27,207,196,137, 19,211,178,178,178,
-166,187, 30,239,225, 58,222, 29,173,204,204, 76,198, 17, 73,  6, 64,114,143, 30, 61,246,109,218,180, 41, 60, 56, 56,216,121,240,
-249,243,231, 81, 83, 83,131,224,224, 96,205,204,153, 51, 53,  3,  7, 14, 68,116,116,180,243, 13, 32, 47, 47,239,134,212,212, 84,
- 45,  0,119,223, 86, 96, 89, 22,125,250,244,193, 49, 71,107,199,176,204, 76, 36, 36, 36, 56, 59,121,  4,  5,  5,225,249,231,159,
-103,198,143, 31,207,137,110,  6, 33,  4,  6,131,  1,177,177,177, 10, 95,174, 14,  0,164, 25, 42,241,211,192,254, 96, 25, 64,127,
-112, 47,164, 50,  6,172,132, 65,119, 82,133, 95,  7,245,  7,  3,192,124,120, 23,  2,112, 97, 14,  2,184,173,101, 28, 14,130, 51,
-103,206,  4,228,104, 57,226,197, 92, 41,167,232,104,236,220,185, 19,118,187, 61, 80, 78,194,178, 44, 84, 42, 21, 98, 98, 98,160,
- 80, 40,160, 84, 42,153,239,190,251,238,237,228,228,228,216,241,227,199,179, 90,173,150,237,211,167, 15,238,187,239, 62, 78,108,
-226, 76, 75, 75,243, 27,151,173, 91,183,226,139, 47,190,192, 83, 79, 61,229,209,209, 98, 24,  6,145,145,145,208,104, 52,184, 86,
- 32,  0,176,216,172,208,215, 27,156, 77,186,118,187, 29, 71,182, 28,238,144,127, 56, 47,109,245,119,223,242,  0, 96,220,242,147,
-235,105,177,247,125,190, 44,117, 64, 24,191,103,235, 37,235, 30, 95,121,158,227, 56,140, 29, 59, 22, 89, 89, 89,120,244,209, 71,
-177,118,237, 90,188,243,206, 59,248,247,191,255,125,153,171,229,239,205,209,106,181,254,247,177,199, 30,123,106,197,138, 21, 29,
-223,120,227, 13, 86,116,180,148, 74, 37, 24,134,129,209,104,132,201,100,130,193, 96,192,169, 83,167,132, 39,159,124, 50,215,108,
- 54,255,215,107,115, 37,163,248, 93, 41,215,175,109,155,192,182,211, 21,124, 20,220,247,230, 36,  3,163,232, 81,123,111,234, 16,
- 50,124,108, 82, 24,  8,  1, 17,  0,129,  0, 38,147, 14,207, 63,255,162,228, 47,188, 85, 78,145,101, 52, 26,113,232,208, 33, 12,
- 26, 52,  8, 69, 69, 69, 56,113,226,  4, 58,116,232,128, 69,139, 22, 69, 62,252,240,195, 57,229,229,229,253,  3,117,182,142, 28,
- 57, 50,241,198, 27,111,252,180,190,190,190,186,190,190,254, 83,  0, 75,  1,212,156, 57,115,166,243,153, 51,103,230,174, 95,191,
-190,223,228,201,147, 37,110,125,116, 36,222,236, 81,171,213,  6,131,193,228, 83, 96,137,191,  9, 17,  2,138, 56,195, 48,164, 99,
-199,142,184,235,174,187,192,243, 60,148, 74, 37,212,106,117,163,102, 51,119,193,229,171,254,  0, 32, 48, 12,131,184,184, 56, 12,
- 31, 62, 28, 82,169,180, 17,167,152, 15,135, 15, 31,142, 23,222,155,132,255,190,112, 43,190,120,172,  3,134,188, 95,230, 51,156,
-122,189,190,126,243,230,205,138, 87,159,122, 10, 55,182,111,143, 86, 26, 13,218, 68, 71, 66, 33,151, 65,234, 26, 38, 38, 32,147,
-157,  0, 16, 36, 18,  9,186,116,233,130,178,178, 50, 20, 20, 20,160,160,160,  0, 44,203,162,111,223,190, 78, 23,230,244,233,211,
-120,239,189,247, 96, 50,153,  2,142,123,251,246,237,113,235,173,183, 66, 38,147, 65,169, 84, 54,106, 50, 20,211,180,174,174, 14,
-237,218,181,195,202,149, 43,145,154,154,234,151,179, 83,167, 78, 24, 48, 96, 64,163,244, 84, 40, 20, 78, 81,  4,  0, 69,123,234,
-157,215,136,143,143,111, 18,231,134,189,231,241,229,198,205, 48,153,  5,104,245,214, 70, 39,196,182,210, 96,251,146, 55,  2,138,
-187,200,185, 96,193,  2,212,212,212, 56,141,  3,241,165, 92, 52, 81, 90,183,110,141,121,243, 60, 59,153,110, 90,196,211, 51, 47,
- 51,192,231,173,120,156,152,185,228, 89, 89, 89,211,221,207,247,199,231,250,191,219,249,102, 55,113, 86,214,164,166, 67,185, 92,
-254,230,230,205,155,195,107,107,107,113,250,244,105,176, 44,235,108, 83,231, 56, 14, 22,139,  5,103,207,158, 69,120,120, 56,202,
-203,203, 33,151,203, 33,145, 72, 96, 54,155,  1,160,187,183,  7, 56, 33,  4, 47, 84, 52,116, 17, 90, 23, 39, 69, 33,128, 59, 43,
- 26, 10,134,216, 33,254,135, 31,126,128, 90,173, 70,112,112,176,243,211, 95, 51,210,145,130, 51, 40,227, 25,176,187,182,129, 97,
-  1,150,  1, 24,  9,192,178,  4, 44,195,128,221,149,  3,134,  1, 84, 17, 97, 77,173,128,253,117,140,247,217,  1,222,155,251,228,
-201,197,114,255,190,101,203, 22,  4,202,217,174, 93, 59,168,213,106,231,182,126,253,250, 70,142,150,221,110, 71, 68, 68, 68, 32,
-156,164,193,141, 16, 16, 21, 21,  5,158,231,153, 69,139, 22, 77, 76,249,127,246,174, 59, 60,138,106,125,191, 51,219,119,147,108,
- 54, 61, 33, 33,148,  0, 82, 34, 77,225,194,165,151,  0, 66,104, 34, 69, 46,  4, 17, 81,138,168, 40, 17,129, 31, 42, 32,161, 73,
-147, 42,200, 37, 32, 72,151, 46, 69,164,131,  5, 20, 36,129, 64,  8,  9,164,111,234,246, 50,237,247, 71,118,227,102,179, 73, 54,
- 33,194,  5,231,125,158,121,118,167,189,115,206,156, 51,103,222,243,157,239,124,211,176, 97,200,244,233,211, 73,129, 64,128,235,
-215,175, 35, 33, 33,  1,245,235,215,119,219,103,171,168,168, 40,235,147, 79, 62, 97, 62,249,164,100, 14, 69,100,100, 36,138,138,
-138,114,237,251, 53, 26, 77,126,159, 62,125,202,248,109,228,229,229, 61,219,158,240,182,251, 72, 91,105, 24, 76, 38,232,180,134,
- 82,235, 80,110,102,142,234,227, 15, 63, 16, 45,155,250,  6,  0,224,195,149,107,160,221,248, 87, 67,118,224,195, 81,129, 67,191,
-220, 53, 19,192,224,202,248,117, 58, 29, 76, 38, 19, 34, 34, 34,112,249,242,101,104,181, 90,244,235,215, 15,  4, 65,148,206, 16,
-173,  6, 44, 25, 25, 25,157,162,163,163,127, 93,177, 98, 69, 68,243,230,205,  9,189, 94, 15,131,193,  0,199,223,155, 55,111,114,
- 59,119,238, 76, 49, 24, 12,255,182,153,206, 93,226, 68,198, 55,201,125, 67,223,220,251,227,117, 65,116, 96,163, 36,101, 70, 97,
-  4,157,159, 33,213,107,140,119, 76, 12,151,  0,142,  1, 24,176,224,104, 22,140,109,216,235,105, 65, 46,151,127,117,241,226, 69,
- 63,147,201,132,107,215,174, 97,204,152, 49,150,188,188, 60,  9,  0,252,231, 63,255,177,108,223,190, 93,210,168, 81, 35,108,219,
-182, 45,224,213, 87, 95,221,163,215,235, 95,116,147,250,219,172,172,172,111,157, 55,250,249,249,173,126,248,240, 97,119, 71,159,
- 31,154,166, 75,147,227,242,193,100,  1,138,162, 96, 52,154, 81, 92,172,133,197, 74,217,218, 76, 22, 12, 67,219,126, 89,208,182,
-118, 84, 34, 22,122,181,125, 49, 88,199,113, 28, 72,130, 40,186,246,103,118,221,202, 68,187,171, 33, 46, 55,173, 89,206, 96,236,
-179,204,252,252,252, 32, 18,137,240,237,183,223,226,198,165, 19,144,  8, 56, 48, 52,  5,154,178,130,161, 44, 16,  9,  4,248,241,
-250,  3, 68, 53,243,114, 75, 16,250,251,251, 99, 64,199,142,136,238,216,177,100,122,155, 80,  8, 79,169, 20, 10,177,172,196,146,
-  5,128, 99, 72,119,131,  8,176,246,116,  6,  5,  5,225,183,223,126,195,180,105,211,176,120,241, 98,200,229,242,210,217,207,183,
-111,223,198,238,221,187, 17, 21, 21, 85,237,188,219, 45,120, 51,103,206, 68,102,102, 38, 86,174, 92,137,151, 94,122,  9, 34,145,
-  8, 69, 69, 69,248,247,191,255,141,156,156, 28,183, 56, 29,135,247, 36, 18, 73, 25,235,147, 93,  0, 86,183,140, 28, 57,223, 24,
- 18,130, 67,151,118,130,  0,129,171, 59, 62, 40, 35, 10,215,239,186, 80,109,206,185,115,231,150, 73,167, 59,214, 44,119,225,100,
-117,170,242, 56,130, 32,174,217,141,173, 51,103,206,156, 69, 16,196,145,153, 51,103,206,138,139,139,187,229, 14,159,171,253,  4,
- 65, 28,181,137,176,  1, 14,219,174, 85, 75,104, 41, 20,138,246,158,158,158,184,119,239, 30,250,245,235,103,201,207,207, 79, 18,
-137, 68, 77,242,242,242,164,185,185,185, 48, 24, 12,186,249,243,231, 63,  0, 32,239,208,161, 67,163, 31,127,252, 17,143, 30, 61,
-194,246,237,219,  1,224,128,107,159, 13, 18, 44,203,150, 86, 10,231,110,155, 64, 32,192,149, 43, 87,112,229, 74, 89,215,175,205,
-155, 55, 87,249,194,120,245,251,195,184,126,253, 58, 28,195,  3,216,255, 59,110,147,201,100, 64,229, 51, 60,202,160, 42,199,248,
-170, 28,224, 93,193, 93,223, 47, 87, 51,115, 42, 66, 70, 70, 70,133,231, 95,185,114,165,140, 69,171, 42, 78,129, 64,  0,134, 97,
- 32,151,203,  9,177, 88, 76,136,197,226, 48,187,200, 18,  8,  4,165, 15,140, 84, 42,133, 84, 42, 45,211, 75,173,  8,153,153,153,
- 61, 50, 51, 51, 43,220,175, 86,171, 59,169,213,106, 60,143,176, 82, 20,140,  6, 11,180, 58, 35, 62,143,251,111,201,198,207,241,
- 51,128,159, 59,189, 51, 13,147,251, 70,245,172,238, 48,181,253,126,  7,  6,  6,226,220,185,115, 32,  8,  2,123,246,236,129,183,
-183, 55,250,246,237, 11,165, 82,137,153, 51,103, 98,248,240,225,213,109,204,138,243,243,243, 59,189,255,254,251,191, 46, 93,186,
- 52,188,110,221,186,176, 88, 44,176, 90,173,176, 88, 44, 72, 78, 78,198,206,157, 59, 31, 25, 12,134, 78,  0,138,171, 34, 59,145,
-241, 77,242,254,243, 31,102,246, 30,249,170,241,118,206, 15,200,206,206,  7, 77,103,128,101,104, 88,105,166,196,194, 71,211,160,
-105,  6, 98,177, 64,185,244,139, 15, 78,177,224, 64,146,132,  5,192, 43, 79,170,140, 84, 42, 85,164, 90,173,198,221,187,119, 17,
- 19, 19,147,157,159,159,159,  8,160, 23,  0,228,231,231, 95, 28, 51,102, 76,243,248,248,248,224,  6, 13, 26,192,211,211, 83,169,
-215,235,171,162,244,  4, 48, 25, 64, 31,148,248,129,216, 81,  0, 96, 62, 73,146,210,107,215,174,149,155,105,119,254,252,121,  0,
-248,217,117, 15,200,102,209, 50,153,160,206, 47,196,132,119,230,252,213, 51,  2, 87, 70, 92,112,224, 48,233, 93,200,  0, 32, 47,
- 39, 25,111, 76,152, 38,173,170, 67,224,234, 69, 88, 13, 31,157, 50, 29, 53,123, 29,245,244,244, 44, 25,126, 59,184, 19, 71,191,
-124,  7, 96,172,224, 40, 35, 96, 53,  0, 86, 29, 88,139,  1,132, 88, 14, 80, 70,183,132,150,167,167, 39, 60,229,114,  4,170, 84,
-224, 56, 14, 66,129,  0, 34,145, 16, 44,  5, 16, 12, 81, 42, 72, 89,247,  2,131,148,118, 42,229,114, 57, 82, 83, 83, 49,121,242,
-100, 88,173, 86, 12, 25, 50,  4, 22,139,  5, 38,147,  9, 70,163, 17, 13, 27, 54,132,193, 96,112,139,207, 62, 91,209,211,211, 19,
- 98,177, 24, 31,124,240,  1, 94,126,249,101,204,155, 55, 15,177,177,177,104,216,176, 33, 38, 77,154,132,157, 59,119, 34, 50, 50,
-178, 42, 94,206,177,140,236,247,211, 46,182, 28,135,248,  0, 84,187,140,156, 57,  9,130, 44, 35,216,236,203,123, 99,123, 85,155,
-115,209,162, 69, 80,171,213,229, 44, 89,246,255,161,161,161, 88,183,110, 93, 77, 71,134,236,214,163, 32, 23,251,  6, 56, 91,162,
- 56,142,107,103,243,157, 50,199,197,197,221,138,139,139,139, 38,  8,226, 72, 92, 92, 92,116, 69, 22, 45, 87, 60, 46,246,187,253,
-210, 18, 58,141,141,118,119,220,105,191,209,190,190,190,130,240,240,112, 82,169, 84,162,168,168,  8,  1,  1,  1,156, 90,173, 30,
-169, 80, 40, 62,251,238,187,239, 26,233,116, 58,220,190,125, 27,171, 87,175,254, 25,192,170,202,132,214,177,  0,155,233,216,102,
-201,114, 92, 31, 56,112, 32, 26, 52,104, 80,198,154, 37,151,203, 43,173, 60,246,125,118,139,144, 64, 32,192, 11, 47,188, 32, 79,
- 73, 73, 49,138,197, 98,132,133,133,201,179,179,179,141, 98,177,184,218, 51, 93,170,114,140,175,202,  1,222,149,240,105,215,174,
- 93, 25, 11,150,227,175,227,255, 67,135, 14, 85, 57,116,104,231,108,222,188,121,233,253,242,242,242,178,159, 11,  0,232,215,175,
- 31, 88,150,133,191,191,191, 91,156,118, 81,107,115,128,135,201,100, 98,181, 90, 45,121,237,218, 53, 72, 36, 18,120,121,121,149,
-250,234,200,100,178, 82,107, 38, 15, 87, 13,  2, 11, 11, 69,193,104, 52, 66,167,211,  1,  0,146,255,220, 87, 86,136,153, 53, 53,
-230,183, 55,176,  5,  5,  5, 56,113,226,  4,126,248,225,  7,188,252,242,203, 46, 69,117, 53,  4,151,186,160,160,160,243,140, 25,
- 51,174, 46, 88,176,160,142,175,175, 47,172, 86, 43, 30, 62,124,136, 45, 91,182,100, 26, 12,134,206,213,105, 96,192,  1, 20, 69,
-195,100, 48,163, 88,163,197,103, 95,108,173,176,234,  1, 64, 65,238, 29, 12, 28, 52, 92,242, 36,203, 41, 51, 51,115,122,231,206,
-157,191,208,106,181, 69,  6,131, 97, 56,128,101,142,253,169,252,252,252, 46,131,  6, 13, 90,225,235,235,251, 82,110,110,238, 44,
- 55, 40,103,166,166,166,206,170, 87,175, 94,153,141,102,179, 25,245,234,213,123, 33, 55, 55,119,116,215,174, 93,255, 15,128,175,
-195,110, 47,  0, 39,  1,172,171,168, 46,217,135, 14,117, 58, 35,148,170, 16,100, 60, 56, 87,101, 66,196,  2, 19, 56,150,173,180,
- 13,177,119,128, 43, 90,170,152, 25, 87, 46,169,246, 99,237, 47,236, 87,134,141,197, 43,147, 23, 65, 33,  2, 22,190,209,  9, 13,
- 85,  0,228,190, 16,119,253, 24,132,202,118,143, 38, 31,118,139, 60,118,195,  6, 92,183,181,199, 97,  1,  1,152, 49,114, 36, 56,
- 10,184,156,144,128, 93, 63,253,132,145, 61,122, 64, 33,147,185,221, 97, 97, 89, 22, 98,177, 24,201,201,201,184,124,249, 50,154,
- 53,107,134,123,247,238,149,  9, 67,193,113,156,187,249, 47,205,187, 84, 42,133, 72, 36, 66,118,118, 54,162,163,163, 33, 22,139,
-177,117,235, 86,156, 59,119, 14, 51,102,204,192,248,241,227,209,189,123,119, 36, 38, 38,186,197,201,113, 92,185,217,138,206,195,
-185,213, 45, 35,103, 78,231,247,126, 77,202,221,206,185, 96,193,  2,151, 19, 42,220,225,116,165, 69, 92,148,221, 53, 71, 49,100,
-183, 60, 57, 10, 35,231,117,  0, 62,246,109, 51,103,206,156,229,238,121,142,235,118,139, 88,117,134, 48, 75,133, 86,116,116,116,
-153,156, 23, 20, 20, 92,189,122,245,106, 11, 15, 15, 15,220,185,115, 71,162, 84, 42, 91,216, 27,116,146, 36,177,103,207, 30,175,
-254,253,251,159, 90,182,108, 89, 24,203,178,200,201,201,193, 71, 31,125,164,163,105,122, 20,  0,186,162, 23,120, 85,150,169,195,
-135,203, 63,108,  7, 15, 30,116,107,  8,196, 46,164,132, 66, 33,124,124,124,140, 70,163, 17, 10,133,  2, 62, 62, 62, 70,131,193,
-  0, 15, 15, 15,251, 88, 49,137,191,102, 42, 84,101,125,170,202, 49,222,217,  1,190, 74, 36, 36, 36,184,117,156,109,168,213,173,
- 90,158,154,154, 90, 97, 67,114,238,220, 57,176,182,134,214, 93, 78, 91, 47,143,179, 11, 63,133, 66,  1, 95, 95, 95, 72,165, 82,
-200,229,242, 50, 34, 75, 42,149, 86,249,224, 84, 21,144, 84, 38,147,253,226,225,225,161,178,239, 23,137, 68,208,106,181, 69,  5,
-  5,  5,237,159,233,161, 67,112,160,173, 52,140, 70, 19,116, 90, 99,173,243, 91, 44, 22, 72,165, 82,236,220,185, 19,157, 58,117,
- 66,135, 14, 29,202,137,172, 26,154,231,211, 11, 10, 10,186,175, 90,181,234,231,229,203,151,251,232,116, 58,252,247,191,255, 45,
-214,233,116,221,  1,164, 87, 75,108,178, 28, 40,171, 21,  6,147, 25,122, 93,201, 61,184,127,107,223,255, 90, 81,237,204,206,206,
-222, 89,201,254,251, 52, 77, 71,219,227,190,185,129,127,213,171, 87, 15,217,217,217,101, 54,166,165,165,129, 97, 24, 51, 74,226,
-100,189,233,104, 72,198, 95,209,179, 43,234,197,151, 88, 71,141,102,232,116, 37, 86, 16,147, 62,175,118,234,169, 77,108, 84,228,
-147, 85,147, 58, 68, 16, 68,169,211,247,212,169, 83,113,243,198, 13,244,170,163, 65,195, 96, 47,112,154, 12,136,123,126,138, 63,
-212,114, 44, 91,113,172,218,220,187, 29, 92, 32,150,237,222,237,114,223,253,193,131,171,149,247,164,164, 36,200,229,114, 48, 12,
- 83,238,125, 83,221,252, 59, 10,152, 21, 43, 86, 96,198,140, 25,216,186,117, 43,110,222,188,137,214,173, 91,163,119,239,222,200,
-205,205,197,141, 27, 55, 96, 54,155,221, 78,167,163,223, 92, 82, 74,  2, 78, 95, 62,142,180,244,  7,200,204,126, 84,227,114,119,
-228,116, 22, 90,251, 79,255,142, 97, 81,109,107,196,249,217,103,159, 33, 55, 55,183,140, 37,203,177, 93,170,200,162,229,172, 69,
-156,144,231,228, 11,101, 95,183, 56,137, 30,231,117,231,227,  1, 32, 23,128,160,138,243,156,215,243,226,226,226,206,218, 45, 97,
- 54, 94, 65, 85,254, 89,101, 44, 90, 78, 88, 52,120,240,224, 65,171, 87,175, 14,144,201,100,165, 51,144,102,206,156,137, 25, 51,
-102, 32, 34, 34,  2,254,254,254,161, 42,149, 10,249,249,249, 88,188,120, 49, 82, 83, 83, 39,194, 69,160, 61,103,161,213, 37, 69,
- 11,137,228,175, 14,171,221,178,  5,  0,227,199,143, 47,103,209,178, 23, 80,101,160, 40, 10,126,126,126, 48, 24, 12, 16,  8,  4,
- 24, 50,100,136,224,207, 63,255,100,250,246,237,139,161, 67,135, 10,110,220,184,193, 12, 24, 48,  0,  2,129,  0, 61,123,246,212,
-236,223,191,255, 67,  0, 95,186, 33,182,106,205, 49,222, 94,201,220,141,125,228,142,184,172,140,147, 32,  8, 24, 12,  6,  8,133,
-194, 82, 71,121,119, 56,237, 67,135,142, 15, 32, 73,146, 80,169, 84,165,141,135,221,162,101, 23, 90, 85,241, 86, 21,144, 84,161,
- 80, 40,239,220,185,211,200, 62,241, 34, 47, 47, 15, 61,123,246,188, 91, 80, 80,240,108,155,180, 88,192, 74, 51,208, 25, 77,208,
- 25, 13,181, 70,107,127, 30, 54,110,220,136,196,196, 68,152, 76, 38,124,245,213, 87,165,147, 10, 28, 69,214, 99,  8,174,100,185,
- 92,206,246,235,215, 15, 87,175, 94,133, 84, 42,165, 80,131,248, 87, 44,199,194, 74,211, 48, 25,141,208, 85, 61,228,246,188,160,
- 84, 85, 39, 38, 38,194, 98,177, 96,222,188,121,204,175,191,254,122, 22, 37,  1, 80,237, 22,188,209,221,186,117,155,239,225,225,
-161, 58,122,244,232,123,  0,182, 86,246,242,166,104,155,104,175,197,251,232, 56, 34,224,202, 39,171, 38, 97, 86, 28, 95,172, 44,
-203, 98,226, 91,111,161,119, 29, 13,134,190, 20,  0,125,214, 93, 40,188,  3, 64,168,234, 99,217,138, 99,184,149,226,182, 43, 38,
-  7,  0,253,186, 13, 70,171,102,229,195,131,117,238, 85,210, 39,187,248,227, 47,200,201,203,172,118,222,245,122,125,133,150,171,
-106, 88,180, 74,159, 57,251,253,107,211,166, 13,154, 52,105,130,179,103,207,162,109,219,182,184,119,239, 30,238,221,187,135,212,
-212, 84,220,188,121, 19,133,133,133,213, 46,163,239, 79,238, 66,161,182,  0, 18,177,  4,  5, 69,121, 72,203,120,128, 32,191,224,
-199, 46,119, 59,154, 14,248, 12,  0, 80, 39,192,187, 90, 66,203,145,115,201,146, 37,229,196,251,227,134,236, 33,  8,226,151,202,
-214,171,123,254,147, 68, 69, 66,235,129, 90,173,238, 48,114,228,200,153,  0,218,217,182, 21,  3,216,125,234,212,169,193,129,129,
-129, 61, 58,118,236, 40,148, 72, 36,184,124,249, 50,246,239,223,191, 21,192,174,202, 46, 36,145, 72,140,245,235,215,151,219, 43,
-162,253, 65, 84, 42,149,130,197,139, 23, 19,155, 55,111,174,208,202, 85, 85,  1, 21, 23, 23, 67,175,215,195,219,219, 27, 86,171,
- 21,253,250,245, 99, 18, 19, 19, 33, 22,139, 49,104,208, 32, 38, 33, 33,161,180,160, 55,109,218, 20,102, 52, 26,255,253,195, 15,
- 63,244,  1,208,181, 26,247,202,238, 24,239,  9, 55, 29,224, 43,234,229,185,  3,119,135,227, 42,226,156, 54,109, 90,141, 56,197,
- 98, 49,109,143,252, 78,146, 36,172, 86, 43,218,182,109,139,220,220,220,210,135,198,195,195,163, 84,100,185, 35,180,170, 10, 72,
- 42, 20, 10, 97,177, 88,208,181,107, 87, 16,  4,129, 53,107,214, 60, 31,195,145, 44, 75,120,122,250,161, 78,157, 23, 16, 16,104,
-  2,203,214,238, 87,101, 98, 99, 99,203,136, 41, 87,145,151,237,247,191, 38,176,115,185, 51, 75,182,178,183,163,125,200, 75,175,
- 55, 61,115, 69, 24, 24, 24,216, 33, 55, 55,247,160,211,230,  2,  0,243, 43,233, 88,150, 22,244,163, 71,143,208,183,111, 95, 28,
- 63,126, 92,112,224,192,129, 94,135, 14, 29, 74,184,123,247,238,163,182,109,219,214,125,251,237,183,165, 93,187,118, 69, 94, 94,
- 30, 94,122,233,165,207, 51, 50, 50, 42, 17, 90,182,251,104, 50, 67,175,175,125,235,168, 43,107,214,227,188, 24,237,117,114,238,
-220,255, 67,239,144, 34, 12,105,237,141,248, 35,151, 48,186,141, 28,176, 72,171,205,103, 79,139,111,157,  6,168, 31,217,161,220,
-126,169,178, 36,150,107,253,200, 14, 32, 31,221,171,118,222, 29,211,236, 44,170,106, 98,209,115,188,159, 19, 38, 76,192,199, 31,
-127,140, 62,125,250,224,222,189,123, 56,127,254, 60,238,221,187,135,105,211,166, 33, 50, 50, 18,173, 91,183,174, 22,231,161,211,
-123,161,209, 21,131, 36, 72, 20, 20,231,195,100, 54, 34,118,210,220,199, 46,247,210,151,255,233, 56,  0,192,190, 83,215,107,204,
- 57,123,246,108,100,103,103,151,177,100, 61,142, 95,214,179,142,202,162,165, 61,  0, 48,209,121,163,197, 98,241,154, 55,111, 94,
-148,191,191, 63,  8,130,192,138, 21, 43,224,235,235,219,  9,192, 45,139,197,146,167,215,235,103, 56,136,144,222,176,197,218,200,
-201,201,113, 57,111, 95,175,215, 91,163,162,162, 68, 33, 33, 33,101,102, 27,122,120,120, 84,100,221, 41,229,180,239,163,105, 26,
-177,177,177, 88,184,112, 33,194,195,195, 49, 96,192,  0, 68, 71, 71,131, 32,  8,244,235,215, 15,  3,  6,252, 53,148,171, 82,169,
-196,199,143, 31,239, 70,146,100,130,195, 11,164, 12,167, 43,216, 29,227, 41,138,114,215,  1,190, 12,167,189,178, 77,155, 54, 13,
- 11, 23, 46,196,172, 89,149,187,122,108,216,176,  1, 40,239, 79,245,183,115, 22, 20, 20,148,105,236, 21, 10,197,154,161, 67,135,
- 10, 31, 61,122, 84, 70, 92, 57, 46, 46, 26,162, 50,156, 85,  5, 36, 21,  8,  4,  8, 10, 10,194,130,  5, 11,224,231,231,135,224,
-224, 96, 87,129,252,170, 44,163, 26,224,111,229,100, 56,246,218,210, 69,255,215,249,191,219, 15,137,164, 18,224,202,249,125,208,
- 20,150, 29, 78, 50, 91,255,154, 74, 45,105,219, 11,150,235, 63,186, 85,151,236, 98,250,179,207, 62,195,103,159,125, 86,105,130,
- 54,110,220,248,216,121,119, 83,108,149,231,100, 57, 66,225,225,  3,153, 71, 29,180,136,244,  1,203,209,255, 83,101, 84,  1,126,
-253,229,151, 95,  6,249,249,249, 33, 61, 61, 61, 64, 36, 18, 13, 42, 99,174, 50, 26, 81,191,126,253, 23,212,106,245,191,171,226,
-156, 54,109,154,121,206,156, 57,210, 81,163, 70, 97,232,208,161, 24, 53,106,148, 84, 44, 22, 55,230, 56, 14, 86,171, 21,233,233,
-233,248,241,199, 31,161, 86,171,111, 87,150, 78,150,227,  8,185, 66,  5,153, 71,  8, 90,188,168,  2,203,210,181,146,119, 71,171,
-184,163, 53,171,154, 34,203,101,253,  4,128, 95,127, 60,136,185, 31,188,136,173, 71,127,198,234, 95,128, 86,170, 92,180,  8, 80,
-131, 85,223,198, 71,163, 95,198,178, 29,191,  1,  0,206,159,171,178,140,184,202,234,160,201,104,125,172,188, 59, 90,174, 28,175,
-227,134,143, 86, 57, 78,123, 39, 81,171,213,162,168,168,  8,241,241,241,120,227,141, 55,144,155,155,139,212,212, 84,220,189,123,
- 23,223,125,247, 29, 20, 10, 69,141,202,232,195,183,102, 99,206,178,233,224,192,161,105,163, 22,152, 57,249, 51,180,107,213,241,
-177,203,221, 25,110, 88,179, 42,228, 92,185,114,101, 77,235,210, 63, 78,104,185,132,191,191,255,168,110,221,186,193,100, 50, 33,
- 32, 32,  0,169,169,169, 32, 73, 50,  2, 40, 25,194, 11, 13, 13,221,173, 86,171, 35,220,229, 19,  8,  4,160,105,186,212,247,199,
-190,  0,192,192,129,  3,113,248,240,225, 42,123, 20,193,193,193,168, 91,183, 46,222,127,255,253,114,179, 28, 28,103, 58,200,229,
-114, 28, 61,122, 52,187,160,160,160,128,227,184,106, 77,115,179, 59,198, 95,188,120,209,109,  7,120, 71, 88,173,214, 71,119,239,
-222, 13,217,184,113,163,160,146,151, 95, 41,206,159, 63, 79,163,138,161,154,191,131,211, 85,207,148,227,184, 10, 69,150, 59, 97,
-  4,170, 10, 72, 42, 20, 10,145,148,148,132,185,115,231,130, 32,  8,236,219,183,239,185,120,184,254,188,147,191,153, 36, 73,159,
-129,175,116,110,  9,130,128,213, 82,126,164,218,179, 80, 87, 42,178,134,126,185, 11,  7, 62, 28,233,142,232, 73,190,112,225,130,
-239,198,141, 27,133,238,148,251,133, 11, 23,104,142,227,170, 61,236,103,127,225, 88,173, 86, 24,141, 53,179,162,112, 28,119, 57,
-238,139, 57, 81,219,190, 61, 38, 34,  8, 11,174,156,219,135,226, 34,215,238, 12, 18,145, 16,155,227,247,211, 98,145,224,209, 83,
- 46,186,181, 67,134, 12, 25,245,213, 87, 95,181,112,181,211,141, 73, 48,169, 38,147,  9, 25, 25, 25, 48, 24, 12,123, 63,249,228,
- 19,235,177, 99,199,222,124,245,213, 87,209,186,117,107,132,132,132, 32, 43, 43, 11,201,201,201,136,143,143,231, 46, 93,186,180,
- 23,192,148, 42,238,227,193, 69, 95,204,137,137,223,113, 76, 66, 18, 86, 92, 57,191, 15,197, 78,162,189,188,117, 90,132,111,182,
-238,183,138,197,162, 59, 85, 89,139, 28,173, 89,181,249, 98, 28, 52,102, 50,134,174, 90,141,136,118,125,177,104,113,111,124,243,
-197,112, 44,239, 39,134,117,207,104,180,122,109, 27,118,206,235, 15,  0,168,243,141,155,214, 18,161, 24, 15, 93, 88,172,138,138,
-101, 54,113, 83, 61,171,169, 61,239,149, 89,174,170,107,209, 34, 73, 18, 13, 26, 52, 64, 68, 68,  4, 58,117,234,132,182,109,219,
-162, 71,143, 30,184,113,227,  6,110,220,184,129,105,211,166, 85, 38,178,170, 44,163,238,255,142,194,207, 93,238, 60,118,217, 56,
-151,123,109,192,157,186, 52,121,242,100,  0,248, 71, 89,183,170, 45,180, 52, 26,205, 13,150,101, 91,122,123,123,219, 45, 82,165,
-251,210,210,210,192,178,172,161,186,  5, 99,177, 88,236,193, 49,203,196,101,178, 59,199, 87,246,224,115, 28,199, 20, 20, 20,160,
- 91,183,110,232,210,165, 75,233,240,137,227,226, 32, 76,112,224,192,  1,112, 28, 87,109, 39,107,  7,199,120, 29,170,233,  0, 15,
-  0,185,185,185,125,187,118,237,122, 74, 40, 20,186,245, 21, 77,150,101, 83,115,114,114, 94,121,210,156,174,202,135,101,217, 10,
- 69,150, 59, 13, 81, 85,  1, 73,133, 66, 33, 60, 60, 60,240,253,247,223,195,223,223,255,185,122,192,110, 36,170,151, 84,182,191,
-155,159,228, 28,128,128,161, 95,238,122,120, 46,223, 90,111,232,151,187,210, 14,124, 56, 50,188,178,115,178,179,179,251,140, 28,
- 57,242,184,187,229, 78,211,244,131,236,236,236,106,135, 75,224, 56, 14,119,238,220, 97, 39, 76,152,144,167, 86,171,135,215, 36,
-255, 51,231,174, 94,190,240,243,169,126,253,162, 58,180,  3,  9, 88, 42,118,254,229,  8,128, 19,138,  4,143,102,204, 90,249,214,
-240,225,195,159,102,177,105,178,179,179, 59, 13, 27, 54,108, 10,254,114,157, 40, 35,164, 80,193,236,106, 27, 86,213,173, 91,247,
- 69,129, 64, 32,  5, 48, 23, 64,218,165, 75,151,214, 94,186,116,169, 15,128,127,  9,  4,130, 16,134, 97, 50,108,157,158, 93,  0,
-254,168,186, 30,229,190, 13,142, 13,235,215,251, 95,125, 65, 16,156,197, 98,174,162,131,  4, 14, 28,199,137,197,162, 59,191,222,
-200,106, 85, 89, 71,202,225, 11, 28,181, 62,100, 63,101,202, 20, 76,153, 50,165,180, 62,173, 89,211,  5,123,255,188,136,215, 90,
-165,195,252,117,103, 16,202,112,183, 59,124,  0, 48,251,255, 38,212, 90,218, 28,243,238,104,209,114,245, 28, 84,199, 71, 75, 32,
- 16, 32, 47, 47, 15, 73, 73, 73,200,201,201,129,193, 96, 64, 98, 98, 34,172, 86, 43, 10, 11, 11,241,226,139, 47,214, 56,157,181,
- 85, 70, 79,147,243,159, 56,124, 88,109,161,101,181, 90, 63,109,208,160,129, 72, 38,147,181, 96, 24,  6, 28,199,129, 97, 24,206,
- 38,106,170, 61, 11, 79, 36, 18,153,154, 52,105, 66,184,154,157, 96,255,239,225,225, 97,172,196, 90, 18, 87,191,126,253, 79,  8,
-130, 16, 84,212, 11,177,255,103, 89,150, 17, 10,133,113, 53,188, 87,143,235, 24,175, 87,171,213, 29,107,185,252,254, 14, 78,231,
-242,209, 55,107,214,172,244,139,246,206, 49, 81,108, 31, 91,213, 87, 33,206, 43, 13, 72,170,215,235,179,250,246,237,203, 56,238,
-119, 12,104,250, 92,131,224,210,250,143,122,179,222,185,124,107, 61,  0,176,139, 45,112, 92, 90, 37,103, 25,179,179,179,187,253,
-221, 73, 75, 73, 73,177,252,235, 95,255,250, 86,171,213, 78,  6, 80, 99,111,254, 89,159,174,153,245, 12,150,140,  6,192,194, 26,
-158,155,150,159,159,223,211,105,219, 31,118, 65,101,143,107, 87,109,209,126, 59,175,214, 99,139,209, 52,157, 30, 17, 17, 81, 45,
-203, 13, 69, 81,233, 85,237,119,142, 17,230,136, 91,240,198,172,171, 64,201,228,239,124,183, 56, 77, 38, 83, 65,199,142, 29, 69,
-213,204, 91,174,187,121, 15,  9,  9, 65,157, 58,117, 74,127,237,112,222, 94, 85, 58,105,154, 78, 15, 11, 11,131,191,191,127,133,
- 17,223,157,125,178,220,225,172,237, 50,170,140,179, 78,157,109,181,206, 89,211,116,242,112, 15,189,121, 78,158,147,231,124,102,
- 57,  5,252,253,228, 57,121, 78,158,243,  9,114, 62,151,224,189,212,120,240,224, 81, 17, 24,254, 22,240,224,193,131,199,227,129,
-168, 68,149, 86,103,166, 79, 77,148,237,105,158,147,231,228, 57,121, 78,158,147,231,228, 57,255,113,156, 85,113,215,246, 76,227,
-231, 26,188, 89,149,231,228, 57,121, 78,158,147,231,228, 57,121,206,127, 44,248,161, 67, 30, 60,120,240,224,193,131,  7, 15, 94,
-104,241,224,193,131,  7, 15, 30, 60,120,240, 66,139,  7, 15, 30, 60,120,240,224,193,131,  7, 47,180,120,240,224,193,131,  7, 15,
- 30, 60,120,161,197,131,  7, 15, 30, 60,120,240,224,193,131,  7, 15, 30, 60,120,240,224,193,131, 71,  9,  8,  0, 56,114,228, 72,
-233,  7,  1,163,163,163,  9,254,182,240,224,193,131,  7, 15, 30, 60,158, 36,158,107, 45,226,152, 57, 30, 60,120,240,224,193,131,
-  7, 15, 94,139,212, 14, 72, 94,108,241,224,193,131,  7, 15, 30, 60,120,177,197,103,140,  7, 15, 30, 60,120,240,224,193,139,172,
-103, 10,101, 44, 90,188,224,226,193,131,  7, 15, 30, 60,120, 60, 77,177,245,140,106, 17,206,182, 56,174,243,224,193,131,  7, 15,
- 30, 60,120,240,120, 76,129, 85,217, 47, 15, 30, 60,120,240,224,193,131,  7,143, 90, 18, 92,246,255, 79, 76,104,241, 95, 54,231,
- 57,121, 78,158,147,231,228, 57,121, 78,158,243, 31, 11, 33,127, 11,120,240,224,193,131,  7, 15, 30, 60, 30, 27,142, 86, 44,130,
- 23, 90, 60,120,240,224,193,131,  7, 15, 30,181, 39,178,  8, 87,235,252,183, 14,121,240,224,193,131,  7, 15, 30, 60,254, 38,240,
- 22, 45, 30, 60,120,240,224,193,131,  7,143,199,  3,  1,126,232,144,  7, 15, 30, 60,120,240,224,193,227,111, 21, 91, 46, 55, 86,
- 52,115,224,116, 53,200,107, 50,251,224, 52,207,201,115,242,156, 60, 39,207,201,115,242,156,255, 56,206,170,184, 79,227,217, 67,
- 55,  0,103,  1,116,183,253, 86, 40,188,106, 27,252,212, 87,158,147,231,228, 57,121, 78,158,147,231,228, 57,159,119, 84, 24,168,
-148,119,134,231, 81, 21,132,168,124,136,185,170,253, 60,120,240,224,193,131,199, 63, 77,108, 17,225, 72,218,  0,  0, 32,  0, 73,
- 68, 65, 84,113,142, 47, 73, 87,104, 12, 96, 22,  0,111,135,109,191,  0,136,115, 58,110,  7,  0,133,195,186, 30,192, 60,  0,247,
-170, 76, 13,199,137,109,252, 82,219,194,  2, 48,  1, 48,  3,208, 18,  4, 65,241,101,246,212,209, 17, 64,180,237,255, 17,  0, 87,
-170,185,255,185, 66, 72, 72,136,220,199,199,167,207,245,235,215, 37,137,137,137,184,112,225,  2,183,121,243,102,107, 97, 97,225,
-201,172,172, 44, 35, 95, 93,158, 11,244,  5, 48,211,246,127, 17,128, 19,143,201, 71, 40, 20,138,105, 30, 30, 30,253,165, 82,105,
- 29,154,166,  9,131,193,144,169,215,235, 79,209, 52,253,165,173,221,171, 46,  6,251,250,250,190,217,180,105,211,198,169,169,169,
- 25,153,153,153, 59,  0,236,  1, 48,188, 78,157, 58,163,235,215,175, 31,122,231,206,157,123,  5,  5,  5,223,  0, 56,248, 20,211,
-201,131,199, 63,  9, 68,101,214,  8, 87,152,203,113,220,232, 50, 12, 68,121,142,158, 61,123, 14, 58,121,242,164,130,101, 89,216,
- 23,185, 92, 78,  3, 24, 87,133,200,242,187,124,249,114,189,201,147, 39, 15,205,204,204,124, 89,171,213,182,  7,  0,133, 66,241,
-115, 96, 96,224,175,171, 86,173,250,142,227,184,116,130, 32,180,213,204,168, 80, 36, 18,189,225,227,227,211,159,166,233,182, 28,
-199, 65, 36, 18, 93, 47, 44, 44, 60, 65, 81,212, 55,  0,106, 34,222, 36, 66,161,112,138, 84, 42,237, 75,211,116, 75,  0, 16, 10,
-133, 55,205,102,243,  9,154,166,215,  2,176,212,128, 83, 38,145, 72,166, 40,149,202, 40,139,197,210, 18,  0, 36, 18,201, 77,141,
- 70,115,202, 98,177,172,181,  9,206,167, 13, 33,128,104,142,227, 68,  0, 32, 16,  8,  6,183,111,223,190, 30, 65, 16, 44, 65, 16,
- 28,199,113,196,207, 63,255,220,134, 97, 24,210, 86, 63,162,  1,252, 10,128,126, 22,159, 16,127,127,255,133, 44,203,214,169,180,
-208,100,178,151,175, 95,191,222,116,247,238,221,204,215, 95,127, 93, 52,126,252,120,207,201,147, 39, 11,215,172, 89,179, 54, 43,
- 43,235, 61,231,227,253,252,252,150,147, 36,233,239,206,245, 89,150,205,203,207,207,159,254,180,242, 31, 19, 99, 42, 99,238,142,
-143,151, 53,  2,144, 94,195,250,253,247,113,154, 98, 56,  0,136,151,197, 55,138, 49,197, 36,219,255, 63, 46,175,  3,102,174, 59,
-173,237,202,113,192,148, 40, 47,242,113,133, 86,104,104,104,124, 76, 76,204,168,150, 45, 91, 10, 57,142,  3, 69, 81, 48,155,205,
- 77,175, 92,185,210,125,223,190,125, 47,107,181,218,225,213,164,124,235,227,143, 63, 94, 48,127,254,124,127,145, 72, 68, 80, 20,
-213,104,247,238,221,109,223,126,251,237,247, 55,110,220, 88,119,196,136, 17, 94,246,237,115,231,206,109,183,104,209,162,134,  0,
-190,124, 10,233,228,193,227,159,134,110, 40,235,163,245, 57,128,207, 42, 19, 90, 30,182,151,103,142,205,146,  5,135,223, 82,156,
- 57,115,230,144, 80, 40,180, 91,180,218,235,245,250, 32, 39, 43,152, 43,145, 85,127,204,152, 49, 29,247,238,221,187,112,196,136,
- 17,217, 10,133,162,201,171,175,190,170, 37,  8, 66,176,123,247,238, 54, 17, 17, 17,242,129,  3,  7,142,233,217,179,231,135, 28,
-199, 93, 32,  8, 66,237,102, 38, 91,248,250,250,238, 95,178,100, 73,189,190,125,251,138,253,253,253,193,113, 28, 50, 51, 51, 67,
-143, 30, 61,218,239,243,207, 63,255,176,160,160, 96,  8,128,132,106,220,184,118,114,185,124,239,231,159,127, 30,210,175, 95, 63,
- 97,112,112, 48, 76, 38, 19, 18, 19, 19,123,159, 56,113,162,235,198,141, 27,223, 51, 26,141,175,217,  4,134,187,104,239,237,237,
-189,239,191, 31,127, 28,212,225,141, 55,132,190,190,190,224, 56, 14,106,181,186,247,197,109,219,186, 79, 90,178,228,189,226,226,
-226, 97,174,238,247,211,132, 68, 34, 33,183,111,223,222, 90, 34,145,  0,  0, 44, 22, 11, 34, 35, 35,137,231,229,  9, 33,  8, 34,
- 44, 51, 51,211, 91, 44, 22,187,220,207, 48, 12,186,118,237,218, 64, 44, 22,227,203, 47,191,164,242,242,242,218,124,245,213, 87,
-215,119,238,220,233,191,118,237,218,215,  0,148, 19, 90, 36, 73,250,167,167,167,187,228,100, 24,  6, 86,171, 21, 52, 77,195, 98,
-177,160,121,243,230, 79, 53,255,241,241,178, 48,  0,211, 99, 98, 76, 31,216, 54,125,  9,224, 67,  0, 41,168,225, 55,187,254,  6,
- 78,199,250,182,220,225,255, 99,167,213,  1,245,  0,224,216, 13, 19,  0,248, 62,238,125,245,240,240,104,246,250,235,175, 11,213,
-106, 53, 68, 34, 17,172, 86, 43,178,179,179, 17, 25, 25, 41,248,246,219,111, 95,168, 46, 95,163, 70,141,198, 47, 90,180, 40,224,
-216,177, 99,214,237,219,183, 91,162,162,162, 68,227,199,143, 87,118,237,218,181,121, 88, 88, 24,185,101,203, 22,243,169, 83,167,
-168, 49, 99,198, 72,226,226,226,  2,142, 30, 61, 58, 48, 33, 33,225,203, 39,157, 78, 30, 60,254,129, 56,139,191, 66, 60,216,127,
- 43, 21, 90,112, 16, 87,131,  1, 64, 36, 18,181,  9, 10, 10,138,167,105, 58,216,102,213,201,206,201,201,249,146,162,168,223,109,
-199, 30,100, 89,118, 80, 85,150,172, 49, 99,198,116, 60,126,252,248,178, 43, 87,174, 20,231,231,231,  7, 31, 58,116,200,244,225,
-135, 31,166,  2, 64, 74, 74, 74,195,129,  3,  7,134, 78,157, 58, 53,189, 79,159, 62,171,122,244,232,241, 46,199,113,167,  8,130,
-208, 87, 37,178, 34, 35, 35, 47,159, 63,127,222, 75,165, 82,149,217, 81,191,126,125,188,251,238,187,226, 65,131,  6, 69,244,234,
-213,235, 82,114,114,114, 23,  0,127,186, 35,136, 26, 55,110,124,250,204,153, 51,158, 62, 62, 62, 40, 42, 42, 66,118,118, 54, 12,
-  6,  3,148, 74, 37, 70,140, 24, 33,238,214,185, 83,221,169,211,222, 59,157,158,145,209,219, 77,177,213,190, 83,139, 22,167,119,
-198,197,121, 82, 15, 31, 66, 46,151, 67,167,211,  1,  0,188,188,188,240,114,131,  6,194,223,182,109, 11, 29, 29, 27,123,250,215,
-164,164,222, 79, 73,108, 73,109,191,102,  0, 71,  4,  2,193, 96,137, 68, 66, 14, 30, 60, 24,167, 79,159, 38, 76, 38,147,208,102,
-221,161,  7, 15, 30, 12,185, 92, 14,139,197,194,162,100,232,144,126,150,159, 18,137, 68,130,228,228,228, 50,219,180, 90, 45,212,
-106, 53,242,243,243, 97, 54,155, 81, 84, 84,  4,150,101,  9,185, 92,174,102, 89, 22, 36, 73, 58, 11,128, 50, 16,139,197, 72, 74,
- 74, 42,179,141,166,105,232,245,122,152,205,102, 88,173, 86,104,181, 90,185,151,151, 87, 99,127,127,255,116,  0,  7, 11, 10, 10,
-190,204,201,201, 73,123,194,217,207,179, 11,162,248,120,217,125,  0,146,255, 69, 78,  7, 75, 86,168,109,253,143, 90, 74,171, 29,
- 15,143,252,110, 10,183, 89,199, 30,212,  2, 31, 11,  0, 23, 46, 92, 64, 78, 78, 14,242,242,242,160, 86,171, 17, 22, 22,  6,142,
-227,170, 61, 28,151,156,156,188,238,197, 23, 95, 36,110,221,186,117,  2,192,154,221,187,119,143, 43, 40, 40,152, 57, 99,198, 12,
-223,165, 75,151, 22,196,198,198, 46,  2,176,117,247,238,221,239, 52,107,214,172,255,237,219,183, 55, 62,141,116,242,224, 81,219,
-224, 56,174, 29,128,  0,123,219, 98,107,119,253, 28,214,111, 16,  4, 97,113, 56,206, 98,107, 27,156,127,237,176,175,171,  9,130,
-248,213,225, 60, 53, 65, 16,191,214, 52,153, 78,191, 37,157,110,  0, 56,114,228,  8,103, 95, 92,157, 25, 24, 24, 56,173,103,207,
-158,203,174, 93,187,214, 60, 43, 43,203, 39, 43, 43,203,231,218,181,107,205,123,246,236,185, 44, 48, 48,112,154,195,141,112, 62,
-245,180,195, 62,241,229,203,151,235,237,223,191,127,209,233,211,167,139,219,180,105, 99, 57,115,230, 12,221,167, 79,159, 92,219,
- 11,154,238,211,167, 79,238, 79, 63,253,196,116,232,208, 65,126,252,248,241, 71,151, 46, 93, 90,190,119,239,222, 32,142,227,  4,
-174, 56,109, 16,169, 84,170,239,207,157, 59, 87, 78,100, 57,162,110,221,186, 56,114,228,136, 82,165, 82, 29,  4, 32,174, 40,157,
- 54,200,100, 50,217,190,159,126,250,201,211,203,203, 11,185,185,185, 16,137, 68,  8, 12, 12, 68,113,113, 49,178,179,178,144,118,
-247, 46, 72,139,  5, 43,190,152,239, 37,151,203,247,186,104,236,203,113,122,123,123,239,219,185,112,161,103,254,233,211,248, 99,
-193,  2, 88,173,214,210, 33, 87,171,213,138, 75,147, 39, 67,253,227,143,216, 50,119,174,167,183,183,247, 62,  0,178, 42, 56,107,
-  3,142,156,147,  1, 20,216,150,201,  0,174, 68, 70, 70, 94, 75, 76, 76, 68,151, 46, 93,176,103,207,158, 86, 51,102,204,152, 60,
- 99,198,140,201,123,246,236,105,213,165, 75, 23, 36, 38, 38, 34, 50, 50,242, 26,202,250,103,253,221,233,252,219, 56, 25,134, 41,
-179,176,236, 95,239,152, 58,117,234,228,238,223,191, 31, 35, 70,140, 32, 37, 18, 73,214,200,145, 35,165, 23, 47, 94,228,108, 34,
-211,237,116,154, 76, 38, 24,141, 70,232,245,122,164,164,164,200,151, 44, 89,210,249,179,207, 62,107,116,250,244,233,208, 89,179,
-102, 77, 10,  8,  8,184, 30, 20, 20, 84,239,  9,231,221,234,244,127,  5,128,140,106, 90,136,254,110, 78,206,118, 62, 98, 76, 49,
-173, 29, 26,216,234,242, 86,118, 63,179,109,105,213,  3, 72,123,156,186,212,179,103,207, 23, 27, 53,106, 20,180,251,150, 15, 10,
-197, 77,193,138, 85, 96,197, 42, 48,126,237,144, 44,121,  5,225,225,225, 65,158,158,158, 29,171,153,206,237,183,110,221,250,151,
-173,167,156, 15, 96, 89,108,108,236,231,  4, 65, 92,136,141,141,157, 15, 96,153,109,251,130,219,183,111,119,  0,176,243, 41,165,
-243,153,120,222,121,206,255, 45,206, 42,180, 72,  0, 65, 16, 71,  8,130, 56,242,201, 39,159,244,  0,224,231,180,254,111,199,227,
-  0, 72, 92,253,218, 23,135,237,  1, 28,199, 13,112, 56, 47,160,134,201, 39, 92, 44,127,  9, 45,  0,136,142,142, 38,162,163,163,
-237, 59,126, 33,  8,226, 16,128, 95, 68, 34, 81,155,214,173, 91, 15,254,225,135, 31,188,  2,  2,254,186,126, 64, 64,  0,246,238,
-221,235,213,162, 69,139,193, 34,145,168, 13,128, 95,148, 74,229,161, 74,172, 48,170,201,147, 39, 15, 29, 59,118,172,166, 77,155,
- 54,  0, 80,148,144,144,160,232,208,161,131,158,166,105,130,166,105,162, 67,135, 14,250,132,132,  4,  5, 69, 81,218,118,237,218,
-121,244,234,213, 43,117,250,244,233, 99, 92,  8, 14, 71,188,190,120,241,226, 48, 31, 31,159,202,148, 48,180, 90, 45,130,130,130,
- 48,121,242,228, 96,145, 72,244,102,101,119, 75, 40, 20, 78, 89,188,120,113,160, 74,165, 66, 97, 97, 33,194,194,194, 96,177, 88,
-144,148,148,  4,147, 94,  7, 74,171,  1,165, 41,130,250,254, 61,168, 68, 66,140, 25, 20, 29, 36, 20, 10,167, 84, 97, 45,153,242,
- 77,108,108,144, 37, 53, 21, 41,123,246,128,161,203, 27,127,104,171, 21, 55, 55,109,130, 41, 61, 29,139, 38, 76,  8,146, 72, 36,
- 83,158,176, 37,107, 41,199,113,114,142,227,228,  4, 65,172,234,216,177,227,183,114,185,124,114, 92, 92, 92,223,147, 39, 79,246,
- 59,127,254,124,119,154,166, 69, 52, 77,139, 46, 92,184,208,197,100, 50,  9,165, 82, 41,132, 66, 33,135,231, 20, 34,145,  8, 98,
-177, 24,114,185, 28,157, 59,119,190,191,121,243,102, 42, 44, 44, 76,180,111,223, 62,159, 58,117,234,120,172, 89,179,166, 72,171,
-213, 46,118,151,207,106,181,194,108, 54,195,104, 52,194,100, 50,225,204,153, 51, 13,166, 78,157, 42, 52,153, 76,204,192,129,  3,
- 11, 40,138, 50,199,198,198, 42,125,125,125, 63,124,146,249,140,137, 49,177, 54,203,211,109,155,104,121,128,199,244,121,250, 59,
- 56,  1, 88,108, 62, 89,118,248,219,184, 45,181,116, 43,104,  0, 58,155,208, 50, 59, 61, 31, 45, 29, 44,190, 85,162,168,168,104,
-227, 55,223,124, 19, 70, 74, 85,184,104,233,143,239,216,207,113,210,123, 13,114,235,125,132,192,176, 70, 24, 53,106, 84, 32,199,
-113,107,106, 33,205, 95,  1,232, 10, 96, 85, 77, 78,126,  2,233,172,231,225,225,177,199,203,203,235,162,135,135,199, 30,216,134,
-103, 31,  7, 81,141,208,123, 80, 51, 50, 61, 42,  2,220,160,102,100,122, 84, 35, 62,212,192,243,  2, 39, 45,226,  8, 53,199,113,
-209, 28,199, 69, 47, 90,180,104,161,195,251,221,190, 46,119,211, 50, 22,205,113, 92,116, 25,133, 84, 34,176, 30,219,232,230, 98,
- 41,209, 20,142, 74,210, 33,115,165,179, 11,131,130,130,226,227,227,227,189,156, 25,179,178,178,160,209,104, 48,103,206, 28,175,
-177, 99,199,190,151,158,158, 30, 83, 69, 34, 36,217,217,217,109, 71,143, 30, 45,179, 90,173,133, 44,203,146, 26,141, 70,232,237,
-237,205,216, 15,240,246,246,102,138,139,139, 69,122,189, 94,192, 48,140,121,236,216,177,146,  9, 19, 38,188, 12, 64, 80, 17,105,
- 64, 64, 64, 84,255,254,253, 43, 28, 58,160, 40, 10,122,189, 30,122,189, 30, 86,171, 21,157, 59,119,150,110,222,188,185, 79,110,
-110,238,250, 10, 21,135, 84, 26, 21, 21, 21, 37, 42, 40, 40,128,183,183, 55,210,210,210,240,224,193,  3,152,117, 58, 88,117, 26,
- 88,117, 90,208, 90, 13, 56, 77, 49,242,239,221, 65,135,102, 77,197, 59,164,210,190,122,189,126,121, 69,156, 74,165, 50,170,195,
-184,113, 66, 15, 15, 15,116, 31, 93, 50,207,224,120,179,102,224, 24,  6, 44,195,128,161,105,244, 77, 74,  2, 69, 81, 32, 73, 18,
-237, 10, 10,132,202,109,219,162,212,106,245,178,167, 81,217,165, 82,169,112,251,246,237,175, 75, 36, 18,112, 28, 71, 88, 44, 22,
-156, 60,121,242, 31,247,208, 75, 36, 18,200,100, 50, 88,173, 86,212,175, 95,223, 56,122,244,232,203, 95,124,241, 69, 56, 73,146,
- 30, 98,177,248,135,252,252,252,133, 89, 89, 89, 41,238,242, 81, 20,  5,139,197,  2,139,197,  2,163,209,136,251,247,239,  7, 55,
-104,208,128,152, 60,121, 50, 99, 48, 24, 26,174, 94,189, 58,249,228,201,147,138,197,139, 23,191, 10,224,221, 39,157,223,152, 24,
- 83, 51,  0,205,226,227,101, 98,155,229,215,242, 63,198,201,161,196,241, 29,241,178,248, 68,  0,234, 90, 20, 89, 18,  0,222,225,
-126, 66,189, 72,  0, 29,  0, 47,155, 40,120,149, 32,136, 14,205,155, 55,247, 73, 76, 76, 44,228, 56,238, 42,128,239,  0,100, 85,
- 70,198,178, 44,193,178, 44,222,110, 95,132,201, 29,  5,160,168, 98, 20, 23, 23, 35, 45, 45, 13,  9,  9,  9,248,249,231,132,154,
- 62,155,111,122,122,122,246,145,201,100,245,105,154, 38,117, 58, 93,154,193, 96, 56,205,178,236, 70,212,192, 71,237,239, 74,167,
- 29, 30, 30, 30, 75,102,205,154,213,201,219,219, 27,191,255,254,123,195, 93,187,118, 45,209,235,245,143,229, 92, 47, 19,145, 91,
-150,175, 92, 19, 26, 26,168,194,141,243,135, 67, 23,110,216,189,  5, 96,195,120,153,242,236,195, 73,139, 56,138,161, 95, 57,142,
- 27, 64, 16,196, 17,103,161, 84, 45,179,211, 99,158, 95,133, 69,203,249,195,210,101,133, 86,  5, 10, 18, 52, 77,  7, 59, 90,178,
- 56,142, 67, 86, 86, 22, 50, 50, 50,160, 86,171,225,227,227,  3,171,213, 26,236, 78,251,160,213,106,219,251,249,249, 25, 68, 34,
-145,217,104, 52, 66,161, 80,176, 34,145,136,179, 93,135,176,205, 90,100,204,102, 51, 33, 20, 10, 41, 47, 47, 47, 79,179,217,220,
- 20,149,248,146,113, 28,215,222,207,207,207,229, 62,179,217, 12,157, 78,  7,189, 94, 15,157, 78,  7,179,217,140,160,160, 32,208,
- 52,221,182,210, 46, 45, 77,183, 12,  8,  8, 64,102,102, 38,228,114, 57,210,211,211, 97,209,105, 97,213,106, 65,235, 53, 96,138,
-139,193,106, 52, 96,245, 26, 80, 22,  3, 66,155, 52,131,125, 70, 98,133,221,112,139,165,165,159,159, 31,244,250,191,220,205, 56,
-155,192,162,105, 26,180,205, 57,218, 62,156,232,239,239, 15,251,140,196, 39,  4, 51,128, 25, 36, 73,174,146, 74,165,194, 73,147,
- 38, 33, 43, 43,171, 76,157,152, 52,105, 82,169, 79, 86,215,174, 93, 47,200,100, 50, 90,173, 86,195,108, 54,139,158,215,135,158,
- 32,  8, 16,  4, 81, 82, 70, 52, 13,127,127,127,125, 94, 94,222,207, 69, 69, 69,175,215,132,143,162, 40,251,140, 46, 24,141, 70,
-112, 28,135,223,127,255, 29, 50,153, 76,196, 48,204, 45,154,166, 21, 34,145,  8,164,205,249,235, 73,193, 54, 35,240, 75,  0, 97,
- 54, 11,209,155, 40,113, 56,207,112,209,144,184,117,235,220,228,172,190,112, 51,197,216, 45, 77, 25,168,217,112,164, 43,116,111,
-170,146, 44,143,235, 16,168,106, 61,208, 67,175,144,  8,244,108, 90,235,250,255, 93,154,176,107,236,152, 55,189,230,205,155, 87,
-207,223,223, 95,150,156,156,108,154, 63,127,126,131,237,219,183, 19, 40, 25,166,171, 16, 15, 31, 62, 60, 48,107,214, 44,223,254,
-253,251, 55,148, 74,165, 68,113,113, 49,212,106, 53,114,114,114,240,224,193,  3,238,198,141, 27,247,205,102,243,158,234, 36, 50,
- 36, 36,100,243,235,175,191, 62,246,165,151, 94, 18,217, 45,164,122,189,190,205,185,115,231,  6, 29, 63,126,188,139, 94,175,175,
-118,189,124,244,232,209,158,217,179,103,123,188,242,202, 43, 77,165, 82, 41, 89, 27,233,116,  4, 73,146, 65,158,158,158, 56,125,
-250, 52, 84, 42, 21, 72,146, 12,122,220,250,106,178,178,161,117,130,253, 96,186,180, 28, 77,  3,234,193,100,101, 67,121,137,242,
-252, 88,180, 42,120,215,183,179, 91,164,170, 16, 75,198,153, 51,103,206, 34,  8,226,200,204,153, 51,103,185,178,104,217,254, 50,
-142,199, 57, 28,111,174,109,177, 85,173, 64,147, 44,203, 34, 35, 35,  3,153,153,153,200,200,200, 64,126,126, 62, 72,146,  4,199,
-113,238,204, 62,227,  8,130, 96, 79,157, 58,229,115,249,242,101,125,187,118,237,138,236,254, 47, 52, 77, 19, 20, 69, 17, 54,191,
- 24, 34, 45, 45, 77,124,241,226, 69,213,237,219,183,131,108,189, 85,182, 10, 83, 96,185,109,118,129,229,184,152, 76, 38,200,100,
- 50,247, 84,135,237, 69,248,251,181,107, 37, 34, 75,167,181, 13, 25, 22,131,209, 20,131,211,107, 33, 97, 40, 72,192,129, 48, 25,
-220,190,127,142,176,139, 44,171, 77,104, 89, 44, 22, 80, 20,  5,150,101, 65,211, 79,197,175,124, 93,171, 86,173,218, 30, 56,112,
- 96,124, 70, 70,249,119,225,144, 33, 67,240,238,187,239, 98,234,212,169,183,  7, 12, 24,112,227,240,225,195,152, 50,101, 10, 88,
-150,109, 13,160, 24,192,241,231,237,161, 55,155,205,165, 22, 40,147,201,  4,171,213, 10, 84,227,179, 10,206,117,211, 94,182, 52,
- 77,219,185,137,  3,  7,246,227,194,133, 11,100, 66,194,173,176, 73,147, 38,219, 29,238,159,116, 86,211, 81, 50,115, 79, 98,107,
- 40, 44, 40,241,127,170, 40,164, 66,  4, 42, 31,178,227, 42,227,124, 28,180,218,208,106,196,  7, 31,124, 16,133,146, 25,206, 41,
-143,105,209,122, 69, 66, 18, 95, 79,107,233, 43,251,176,149,159, 94, 34, 36,116, 73, 95,207,210, 61,  8, 87,234,131,234, 42, 44,
- 97, 13, 84,117, 22, 46,252, 34,228,246,237, 59,230, 57,115,230, 36,142, 28, 57, 50,240,195, 15, 63,108,190,111,223,190, 46, 38,
-147,233, 27,  0, 69, 21, 25, 93,  6, 13, 26,116, 53, 48, 48,176,193,134, 13, 27,114, 31, 61,122,228,